区分material-ui SelectFields并获取它们的值

Posted

技术标签:

【中文标题】区分material-ui SelectFields并获取它们的值【英文标题】:Telling the difference between material-ui SelectFields and getting their values 【发布时间】:2016-08-18 20:22:49 【问题描述】:

我有一个动态生成输入的表单,其中一个输入是 material-ui TextField 和具有多个选项的 SelectField。我在将选择字段彼此分开时遇到问题。在理想情况下,我希望能够从这两个输入中收集数据并将它们存储为一个对象(即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;

【问题讨论】:

【参考方案1】:

据我了解,您希望以相同的方法处理 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;

为避免这种情况,您可以“克隆”状态对象并在那里应用更改..

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

------------------------------------------ -------- 2016 年 4 月 26 日更新示例 现在您可以看到我只是将输入对象(我通过它的 id 找到)中的 typeId 更改为SelectFields。 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 
>

【讨论】:

感谢您的帮助!检查有帮助,但我遇到的问题是选择列表没有更新它在视图中的值(所以即使你点击不同的东西它也会保持默认值),值的状态也永远不会更新,这我想不通。你自己有什么线索吗? 嗯,这些突变可能是问题的原因..你删除它们了吗?另外,handleInputChange 中的父组件在做什么?(似乎您没有使用从父组件传递的任何内容..)如果您进行了更改,您能否更新您的代码..? @BeeNag 我删除了 handleChange 的代码,并将其替换为您建议的控制台日志检查,以检查我得到的值是否正确。值是正确的,但选择字段没有改变。 handleInputChange 存在是因为该组件是较大表单的一部分,因此父组件需要知道这部分的值! 你能说明你是如何在你的状态对象中设置值的吗? @BeeNag 是的,这就是我最终所做的!感谢您的所有帮助,它现在像魅力一样工作

以上是关于区分material-ui SelectFields并获取它们的值的主要内容,如果未能解决你的问题,请参考以下文章

材质 UI 在点击“选项卡”时未选择 SelectField

Flask WTForms 动态表单依赖项 selectField 未填充在编辑页面中

Sencha touch selectfield 占位符

记住 selectfield sencha touch

浏览器地址自动填充不会填充“状态”SelectField 元素

如何使我的烧瓶 wtforms SelectField 看起来像一个下拉列表?