区分 material-ui SelectFields 并获取它们的值
Telling the difference between material-ui SelectFields and getting their values
我有一个动态生成输入的表单,其中一个输入是具有多个选项的 material-ui TextField 和 SelectField。不过,我在区分 select 字段时遇到了问题。在一个理想的世界中,我希望能够从这两个输入中收集数据并将它们存储为一个对象(即 {name: Employee, type_id: 1}
),该对象将成为一个对象数组,具体取决于生成的输入数量。
我当前的代码如下所示:
import React from 'react';
import TextField from 'material-ui/TextField';
import RaisedButton from 'material-ui/RaisedButton';
import SelectField from 'material-ui/SelectField';
import MenuItem from 'material-ui/MenuItem';
import DatatypeStore from '../../stores/DatatypeStore';
const styles = {
customWidth: {
width: 100,
},
};
class MultipleEntry extends React.Component {
state={inputs: [], columnHeaders: [], value: 1};
addInputField(e) {
e.preventDefault();
let inputs = this.state.inputs;
inputs.push({name: null});
this.setState({inputs});
}
handleChange(e, index, value) {
const isSelectField = value !== undefined;
if (isSelectField) {
console.log(index, value);
} else {
console.log(e.target.value);
}
}
render() {
let {inputs, columnHeaders, value} = this.state;
return (
<div className="col-md-12">
{inputs.map((input, index) => {
let name = "header " + index;
return (
<div key={index}>
<br />
<TextField
hintText="Enter the name for the column"
floatingLabelText="Column Name"
type="text"
name={name}
onChange={e => this.handleChange(e)}
/>
<SelectField
value={this.state.value}
onChange={e => this.handleChange(e, index, value)}
style={styles.customWidth}
>
{DatatypeStore.getDatatypes().map(el => {
return <MenuItem key={el.id} value={el.id} primaryText={el.name} />;
})}
</SelectField>
<br />
</div>
);
})}
<br/>
<RaisedButton
style={{marginTop: 50}}
label="Add column input"
secondary={true}
onClick={e => this.addInputField(e)}
/>
<br />
</div>
);
}
}
export default MultipleEntry;
所以,是的,我将不胜感激做我想做的事的例子。如果你能用 material-ui 组件做到这一点就更好了!
感谢您的宝贵时间
更新
这里是父组件
import React from 'react';
import MultipleEntry from './MultipleEntry.jsx';
import Paper from 'material-ui/Paper';
import TextField from 'material-ui/TextField';
import RaisedButton from 'material-ui/RaisedButton';
import TokenStore from '../../stores/TokenStore';
const styles = {
paper: {
marginTop: 50,
paddingBottom: 50,
width: '100%',
textAlign: 'center',
display: 'inline-block',
},
};
class ColumnHeaderForm extends React.Component {
state = {title: '', input: null};
changeValue(e) {
const title = e.target.value;
this.setState({
title
});
}
handleInputChange(columnHeaderArray) {
let input = this.state.input;
input = columnHeaderArray;
this.setState({input});
}
handleFormSubmit(e) {
e.preventDefault();
let access_token = TokenStore.getToken();
let title = this.state.title;
let inputs = this.state.input;
this.props.handleFormSubmit(access_token, title, inputs);
}
render() {
let {title, input} = this.state;
return (
<div>
<Paper style={styles.paper}>
<form role="form" autoComplete="off">
<div className="text-center">
<h2 style={{padding: 10}}>Fill out the column names (you can add as many as you need)</h2>
<div className="col-md-12">
<TextField
hintText="Enter a title for the table"
floatingLabelText="Title"
type="text"
onChange={e => this.changeValue(e)}
/>
</div>
<div className="col-md-12">
<MultipleEntry handleInputChange={this.handleInputChange.bind(this)} />
</div>
<RaisedButton
style={{marginTop: 50}}
label="Submit"
primary={true}
onClick={e => this.handleFormSubmit(e)}
/>
</div>
</form>
</Paper>
</div>
);
}
}
export default ColumnHeaderForm;
根据我的理解,您希望以相同的方法处理 TextField 和 SelectField onChange
。他们确实有不同的签名
文本字段(event, value)
选择字段(event, index, value)
但是您可以通过测试第三个参数轻松实现它,例如:
handleChange(event, index, value) {
const isSelectField = value !== undefined;
if(isSelectField) {
// do whatever you need to do with the SelectField value
} else {
// do whatever you need to do with the TextField value
}
}
注意:
你不应该改变你的状态,那是错误的。
let columnHeaders = this.state.columnHeaders;
columnHeaders[e.target.name] = e.target.value;
要避免它,您可以 "clone" 状态对象并在那里应用更改..
Object.assign({}, this.state.columnHeaders, {
[e.target.name]: event.target.value
})
在此处阅读有关 Object.assign
的更多信息:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
---------------------------------------- ------------
更新示例 26/04/2016
现在您可以看到我只是更改 SelectField
的输入对象(我通过其 ID 找到的)中的 typeId。 TextField
几乎相同 - 只需更改字段名称..
handleChange(inputId, event, index, value) {
const isSelectField = value !== undefined;
if(isSelectField) {
this.setState({
inputs: this.state.inputs.map((input) => {
return input.id === inputId ? Object.assign({}, input, {
typeId: value
}) : input
})
})
} else {
this.setState({
inputs: this.state.inputs.map((input) => {
return input.id === inputId ? Object.assign({}, input, {
name: event.target.value
}) : input
})
})
}
}
//Make sure the id is unique for each input
addInputField(e) {
e.preventDefault();
this.setState({
inputs: this.state.inputs.concat({ id: 1, name: null })
});
}
//Binding the ID in the call so we can use it in that method..
<SelectField
value={input.typeId}
onChange={this.handleChange.bind(this, input.id)}
style={styles.customWidth}
>
我有一个动态生成输入的表单,其中一个输入是具有多个选项的 material-ui TextField 和 SelectField。不过,我在区分 select 字段时遇到了问题。在一个理想的世界中,我希望能够从这两个输入中收集数据并将它们存储为一个对象(即 {name: Employee, type_id: 1}
),该对象将成为一个对象数组,具体取决于生成的输入数量。
我当前的代码如下所示:
import React from 'react';
import TextField from 'material-ui/TextField';
import RaisedButton from 'material-ui/RaisedButton';
import SelectField from 'material-ui/SelectField';
import MenuItem from 'material-ui/MenuItem';
import DatatypeStore from '../../stores/DatatypeStore';
const styles = {
customWidth: {
width: 100,
},
};
class MultipleEntry extends React.Component {
state={inputs: [], columnHeaders: [], value: 1};
addInputField(e) {
e.preventDefault();
let inputs = this.state.inputs;
inputs.push({name: null});
this.setState({inputs});
}
handleChange(e, index, value) {
const isSelectField = value !== undefined;
if (isSelectField) {
console.log(index, value);
} else {
console.log(e.target.value);
}
}
render() {
let {inputs, columnHeaders, value} = this.state;
return (
<div className="col-md-12">
{inputs.map((input, index) => {
let name = "header " + index;
return (
<div key={index}>
<br />
<TextField
hintText="Enter the name for the column"
floatingLabelText="Column Name"
type="text"
name={name}
onChange={e => this.handleChange(e)}
/>
<SelectField
value={this.state.value}
onChange={e => this.handleChange(e, index, value)}
style={styles.customWidth}
>
{DatatypeStore.getDatatypes().map(el => {
return <MenuItem key={el.id} value={el.id} primaryText={el.name} />;
})}
</SelectField>
<br />
</div>
);
})}
<br/>
<RaisedButton
style={{marginTop: 50}}
label="Add column input"
secondary={true}
onClick={e => this.addInputField(e)}
/>
<br />
</div>
);
}
}
export default MultipleEntry;
所以,是的,我将不胜感激做我想做的事的例子。如果你能用 material-ui 组件做到这一点就更好了!
感谢您的宝贵时间
更新
这里是父组件
import React from 'react';
import MultipleEntry from './MultipleEntry.jsx';
import Paper from 'material-ui/Paper';
import TextField from 'material-ui/TextField';
import RaisedButton from 'material-ui/RaisedButton';
import TokenStore from '../../stores/TokenStore';
const styles = {
paper: {
marginTop: 50,
paddingBottom: 50,
width: '100%',
textAlign: 'center',
display: 'inline-block',
},
};
class ColumnHeaderForm extends React.Component {
state = {title: '', input: null};
changeValue(e) {
const title = e.target.value;
this.setState({
title
});
}
handleInputChange(columnHeaderArray) {
let input = this.state.input;
input = columnHeaderArray;
this.setState({input});
}
handleFormSubmit(e) {
e.preventDefault();
let access_token = TokenStore.getToken();
let title = this.state.title;
let inputs = this.state.input;
this.props.handleFormSubmit(access_token, title, inputs);
}
render() {
let {title, input} = this.state;
return (
<div>
<Paper style={styles.paper}>
<form role="form" autoComplete="off">
<div className="text-center">
<h2 style={{padding: 10}}>Fill out the column names (you can add as many as you need)</h2>
<div className="col-md-12">
<TextField
hintText="Enter a title for the table"
floatingLabelText="Title"
type="text"
onChange={e => this.changeValue(e)}
/>
</div>
<div className="col-md-12">
<MultipleEntry handleInputChange={this.handleInputChange.bind(this)} />
</div>
<RaisedButton
style={{marginTop: 50}}
label="Submit"
primary={true}
onClick={e => this.handleFormSubmit(e)}
/>
</div>
</form>
</Paper>
</div>
);
}
}
export default ColumnHeaderForm;
根据我的理解,您希望以相同的方法处理 TextField 和 SelectField onChange
。他们确实有不同的签名
文本字段(event, value)
选择字段(event, index, value)
但是您可以通过测试第三个参数轻松实现它,例如:
handleChange(event, index, value) {
const isSelectField = value !== undefined;
if(isSelectField) {
// do whatever you need to do with the SelectField value
} else {
// do whatever you need to do with the TextField value
}
}
注意: 你不应该改变你的状态,那是错误的。
let columnHeaders = this.state.columnHeaders;
columnHeaders[e.target.name] = e.target.value;
要避免它,您可以 "clone" 状态对象并在那里应用更改..
Object.assign({}, this.state.columnHeaders, {
[e.target.name]: event.target.value
})
在此处阅读有关 Object.assign
的更多信息:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
---------------------------------------- ------------
更新示例 26/04/2016
现在您可以看到我只是更改 SelectField
的输入对象(我通过其 ID 找到的)中的 typeId。 TextField
几乎相同 - 只需更改字段名称..
handleChange(inputId, event, index, value) {
const isSelectField = value !== undefined;
if(isSelectField) {
this.setState({
inputs: this.state.inputs.map((input) => {
return input.id === inputId ? Object.assign({}, input, {
typeId: value
}) : input
})
})
} else {
this.setState({
inputs: this.state.inputs.map((input) => {
return input.id === inputId ? Object.assign({}, input, {
name: event.target.value
}) : input
})
})
}
}
//Make sure the id is unique for each input
addInputField(e) {
e.preventDefault();
this.setState({
inputs: this.state.inputs.concat({ id: 1, name: null })
});
}
//Binding the ID in the call so we can use it in that method..
<SelectField
value={input.typeId}
onChange={this.handleChange.bind(this, input.id)}
style={styles.customWidth}
>