<html manifest="">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<TITLE></TITLE>
<meta name="google" content="notranslate">
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<script type="text/javascript" src="https://unpkg.com/react@16.2.0/umd/react.production.min.js"></script>
<script type="text/javascript" src="https://unpkg.com/react-dom@16.2.0/umd/react-dom.production.min.js"></script>
<script type="text/javascript" src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
<script type="text/javascript" src="https://unpkg.com/jquery@2.2.4/dist/jquery.min.js"></script>
<style type="text/css">
body{
font:14px/1 Arial;
}
h2{
text-align: center;
}
.wrap{
margin:auto;
width: 480px;
}
.listUL{
list-style: none;
margin:0;
padding:0;
}
.listUL li{
border:1px solid #ABABAB;
padding:10px;
margin-bottom: 30px;
box-shadow: 2px 2px 30px 4px #ccc;
box-shadow: 2px 2px 30px 4px #ccc;
box-shadow: 2px 2px 30px 4px #ccc;
}
.listUL li input[type=text]{
height: 28px;
border:1px solid #ccc;
color: #333;
font:16px Arial;
padding-left: 5px;
}
.listUL li input[type=submit]{
font:16px Arial;
}
.success{
color:green;
}
.fail{
color:red;
}
.line p{
display: inline-block;
width: 80px;
}
.info{
display: inline-block;
padding-left: 10px;
}
</style>
</head>
<body>
<h2>员工列表</h2>
<div class="wrap">读取中...</div>
<script type="text/babel">
var host=""
class SearchBox extends React.Component{
constructor(){
super(...arguments)
}
onChange = (e)=> {
var val = $(e.target).val();
this.props.onSearch(val);
}
render() {
return(
<div><input type="text" placeholder="输入关键词" onChange={this.onChange} /></div>
)
}
}
class UserForm extends React.Component{
constructor(){
super(...arguments)
}
submit = (e)=> {
e.preventDefault();
var newData = this.props.data;
for(var i in this.refs){
var v = this.refs[i];
if(v.name) newData[i] = v.value;
}
var infoEl = this.refs.info;
$(this).removeAttr('style').html('更新中...').show();
$.ajax({
url: '/update',
type:'POST',
data: JSON.stringify(newData),
contentType:'application/json',
success:function (data) {
infoEl.className = 'info success';
infoEl.innerHTML = '已更新!';
},
error: function (err) {
console.log("AJAX error in request: " + JSON.stringify(err, null, 2));
infoEl.className = 'info fail';
infoEl.innerHTML = '更新错误!';
},
complete:function () {
$(infoEl).removeAttr('style').stop().animate({opacity:0}, 2000, function () {
$(this).hide();
});
}
});
}
handleChange (event) {
var val = event.target.value;
this.setProps({[event.target.name]:val});
}
render () {
console.log(this.props.data)
return(
<li>
<form onSubmit={this.submit}>
{/* // Below use defaultValue="" instead of value="" to make input editable, but after search with keyword, the input value don't update: solved:using value+onChange handler */}
<div className="line"><p>用户ID:</p><input type="text" defaultValue={this.props.data.userid} readOnly ref="userid" name="userid" /></div>
<div className="line"><p>电脑名称:</p><input type="text" value={this.props.data.client} onChange={this.handleChange} placeholder="电脑名称" ref="client" name="client" /></div>
<div className="line"><p>IP地址:</p><input type="text" defaultValue={this.props.data.ip} placeholder="IP地址" onChange={this.handleChange} ref="ip" name="ip" /></div>
<div className="line"><p>用户级别:</p><input type="text" defaultValue={this.props.data.level} placeholder="用户级别" ref="level" name="level" /></div>
<div className="line"><p>短号:</p><input type="text" defaultValue={this.props.data.shortPhone} placeholder="短号" ref="shortPhone" name="shortPhone" /></div>
<div className="line"><p></p><input type="submit" value="提交" /><span className="info" ref="info"></span></div>
</form>
</li>
);
}
}
class User extends React.Component{
constructor(){
super(...arguments)
this.state= {data:[]}
}
onSearch = (val)=> {
if(!window.STUFF_LIST) return;
var newData = window.STUFF_LIST.filter(v=> {
return v.userid.match(new RegExp(val), 'i') || v.name&&v.name.match(new RegExp(val), 'i');
});
this.setState({data:newData, searchText:val}, ()=> {
});
}
getData (initData) {
if(!initData){
$.ajax({
url:host+'/views/dataJSON.json',
success:(data)=>{
data = mockData
window.STUFF_LIST = data;
this.setState({data:data||window.mockData}, function () {
});
},
error:(e)=>{
window.STUFF_LIST = mockData;
this.setState({data:window.mockData}, function () {
});
}
})
} else {
this.setState({data:initData});
}
}
componentDidMount () {
this.getData();
}
render () {
var forms = this.state.data.map(v=>{
return window.STUFF_LIST ? <UserForm className="list" data={v} searchText={this.state.searchText} /> : <UserForm>读取中...</UserForm>
});
return(
<div>
<SearchBox onSearch={this.onSearch} />
<ul className="listUL">
{forms}
</ul>
</div>
);
}
}
ReactDOM.render( <User />, $('.wrap')[0] );
</script>
</body>
</html>
<script>
var mockData = [
{
"userid": "gary",
"client": "pc-gary",
"ip": "",
"level": 80,
"userRole": [
"boss"
],
"shortPhone": "664148",
"color": "#0000CD"
},
{
"userid": "yangjiming",
"client": "pc33",
"ip": "192.168.1.135",
"level": 0,
"userRole": [
"designer"
],
"isAdmin": true,
"shortPhone": "665991",
"color": "#0000CD"
},
{
"userid": "dongyuexia",
"client": "pc-dong",
"ip": "",
"level": 10,
"userRole": [
"designer"
],
"shortPhone": "665991"
},
{
"userid": "ceshi02",
"client": "pc333",
"ip": "",
"level": 0,
"shortPhone": "665991"
},
{
"userid": "ceshi1",
"client": "pc333",
"ip": "",
"level": 100,
"shortPhone": "665991"
},
{
"userid": "jinweichao",
"client": "pcxln",
"ip": "",
"level": 20,
"shortPhone": "665991"
},
{
"userid": "tangxiaohong",
"client": "",
"ip": "",
"level": "",
"userRole": [],
"shortPhone": ""
},
{
"userid": "fangdifei",
"client": "",
"ip": "",
"level": "",
"userRole": [],
"shortPhone": ""
},
{
"userid": "chenjie",
"client": "",
"ip": "",
"level": "",
"userRole": [],
"shortPhone": ""
},
{
"userid": "yangjufen",
"client": "",
"ip": "",
"level": "",
"userRole": [],
"shortPhone": ""
},
{
"userid": "zhaojianming",
"client": "",
"ip": "",
"level": "",
"userRole": [],
"shortPhone": ""
},
{
"userid": "chenpeifang",
"client": "",
"ip": "",
"level": "",
"userRole": [],
"shortPhone": ""
},
{
"userid": "ziyanmei",
"client": "",
"ip": "",
"level": "",
"userRole": [],
"shortPhone": ""
},
{
"userid": "hongyinghai",
"client": "",
"ip": "",
"level": "",
"userRole": [],
"shortPhone": ""
},
{
"userid": "tangdongya",
"client": "",
"ip": "",
"level": "",
"userRole": [],
"shortPhone": ""
},
{
"userid": "zhuzhangfu",
"client": "",
"ip": "",
"level": "",
"userRole": [],
"shortPhone": ""
},
{
"userid": "shenjianqin",
"client": "pcdz",
"ip": "192.168.1.124",
"level": "",
"userRole": [],
"shortPhone": ""
}
]
</script>
Output
You can jump to the latest bin by adding /latest
to your URL
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |