2016-04-25 9 views
1

私は動的に入力を生成するフォームを持っています.1つの入力は複数のオプションを持つMaterial-UI TextFieldとSelectFieldです。私は選択フィールドを互いに離れて話すことに問題があります。理想的な世界では、これらの両方の入力からデータを収集し、それらをオブジェクト(つまり、{name: Employee, type_id: 1})として保存することができます。これは生成される入力の数に応じてオブジェクトの配列になります。Material-ui SelectFieldsとその値の違いを教えてください

私の現在のコードは次のようになります。

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; 

そうそう、私がやりたいものをやっ例がはるかに高く評価されるだろう。あなたがマテリアルUIコンポーネントを使用してそれを行うことができれば、より良いことができます!

お時間をありがとう

更新

ここでは、同じ方法でのTextFieldとSelectField onChangeを処理する私の理解から親コンポーネント

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 (event, value)
SelectField (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

を----- -----------------------------------------------
更新例26/04/2016
ここでは、SelectFieldの入力オブジェクト内のtypeId(idで見つかった)を変更しています。 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} 
> 
+0

ありがとうございます!チェックは役に立ちましたが、私が抱えている問題は、選択リストがビュー内の値を更新していないということです(別のものをクリックしてもデフォルト値のままです)。私は理解できません。どんな手掛かり? – BeeNag

+0

まあ、これらの突然変異は問題の原因となる可能性があります。また、親コンポーネントが 'handleInputChange'で何をしていますか?(親から渡されたものは何も使用していないようです)あなたが変更を加えたら、あなたのコードを更新できますか? @BeeNag –

+0

handleChangeのコードを削除し、コンソールログで提案したチェックで置き換えて、正しい値を取得していることを確認しました。値は正しいが、選択フィールドは変更されていない。このコンポーネントはより大きなフォームの一部であるため、親コンポーネントはこの部分から値を知る必要があるため、handleInputChangeはそこにあります。 – BeeNag

関連する問題