web-dev-qa-db-fra.com

Comment obtenir des données à partir de composants TextField, DropDownMenu de material-ui?

Je crée un formulaire, j'ai plusieurs composants TextField, DropDownMenu material-ui inclus, la question est de savoir comment je peux collecter toutes les données de tous les TextFields, DropDownMenus dans un obj et les envoyer sur le serveur. Pour TextField, il a TextField.getValue () Retourne la valeur de l'entrée. Mais je ne peux pas comprendre comment l'utiliser. 

var React = require('react'),
    mui = require('material-ui'),
    Paper = mui.Paper,
    Toolbar = mui.Toolbar,
    ToolbarGroup = mui.ToolbarGroup,
    DropDownMenu = mui.DropDownMenu,
    TextField = mui.TextField,
    FlatButton = mui.FlatButton,
    Snackbar = mui.Snackbar;

var menuItemsIwant = [
  { payload: '1', text: '[Select a finacial purpose]' },
  { payload: '2', text: 'Every Night' },
  { payload: '3', text: 'Weeknights' },
  { payload: '4', text: 'Weekends' },
  { payload: '5', text: 'Weekly' }
];
var menuItemsIcan = [
  { payload: '1', text: '[Select an objective]' },
  { payload: '2', text: 'Every Night' },
  { payload: '3', text: 'Weeknights' },
  { payload: '4', text: 'Weekends' },
  { payload: '5', text: 'Weekly' }
];
var menuItemsHousing = [
  { payload: '1', text: '[Select housing]' },
  { payload: '2', text: 'Every Night' },
  { payload: '3', text: 'Weeknights' },
  { payload: '4', text: 'Weekends' },
  { payload: '5', text: 'Weekly' }
];
var menuItemsIlive = [
  { payload: '1', text: '[Select family mambers]' },
  { payload: '2', text: 'Every Night' },
  { payload: '3', text: 'Weeknights' },
  { payload: '4', text: 'Weekends' },
  { payload: '5', text: 'Weekly' }
];
var menuItemsLifestyle = [
  { payload: '1', text: '[Select lifestyle]' },
  { payload: '2', text: 'Every Night' },
  { payload: '3', text: 'Weeknights' },
  { payload: '4', text: 'Weekends' },
  { payload: '5', text: 'Weekly' }
];
var menuItemsLifestyle2 = [
  { payload: '1', text: '[Select savings]' },
  { payload: '2', text: 'Every Night' },
  { payload: '3', text: 'Weeknights' },
  { payload: '4', text: 'Weekends' },
  { payload: '5', text: 'Weekly' }
];
var menuItemsIncome = [
  { payload: '1', text: '[Select your yearly income]' },
  { payload: '2', text: 'Every Night' },
  { payload: '3', text: 'Weeknights' },
  { payload: '4', text: 'Weekends' },
  { payload: '5', text: 'Weekly' }
];
var Content = React.createClass({

  getInitialState: function() {
    return {
      //formData: {
      //  name: '',
      //  age: '',
      //  city: '',
      //  state: ''
      //},
      errorTextName: '',
      errorTextAge: '',
      errorTextCity: '',
      errorTextState: ''
    };
  },

  render: function() {

    return (
      <div className="container-fluid">
        <div className="row color-bg"></div>
        <div className="row main-bg">
          <div className="container">
            <div className="mui-app-content-canvas page-with-nav">
              <div className="page-with-nav-content">

                <Paper zDepth={1}>

                  <h2 className="title-h2">Now, what would you like to do?</h2>

                  <Toolbar>
                    <ToolbarGroup key={1} float="right">
                      <span>I want to</span>
                      <DropDownMenu
                        className="dropdown-long"
                        menuItems={menuItemsIwant}
                        //autoWidth={false}
                      />
                    </ToolbarGroup>
                  </Toolbar>

                  <div className="clearfix"></div>

                  <Toolbar>
                    <ToolbarGroup key={2} float="right">
                      <span>So I can</span>
                      <DropDownMenu
                        className="dropdown-long"
                        menuItems={menuItemsIcan}
                        //autoWidth={false}
                      />
                    </ToolbarGroup>
                  </Toolbar>

                  <h2 className="title-h2">Please, share a little about you.</h2>

                  <div className="clearfix"></div>

                  <Toolbar>
                    <ToolbarGroup key={3} float="right">
                      <span>I am</span>
                      <TextField
                        id="name"
                        className="text-field-long"
                        ref="textfield"
                        hintText="Full name"
                        errorText={this.state.errorTextName}
                        onChange={this._handleErrorInputChange}
                      />
                      <span>and I am</span>
                      <TextField
                        id="age"
                        className="text-field-short"
                        ref="textfield"
                        hintText="00"
                        errorText={this.state.errorTextAge}
                        onChange={this._handleErrorInputChange}
                      />
                      <span className="span-right-measure">years of age.</span>
                    </ToolbarGroup>
                  </Toolbar>

                  <div className="clearfix"></div>

                  <Toolbar>
                    <ToolbarGroup key={4} float="right">
                      <span>I</span>
                      <DropDownMenu
                        hintText="I"
                        menuItems={menuItemsHousing}
                        //autoWidth={false}
                      />
                      <span>in</span>
                      <TextField
                        id="city"
                        ref="textfield"
                        className="text-field-long"
                        hintText="City"
                        errorText={this.state.errorTextCity}
                        onChange={this._handleErrorInputChange}
                      />
                      <span>,</span>
                      <TextField
                        id="state"
                        ref="textfield"
                        className="text-field-short text-field-right-measure"
                        hintText="ST"
                        errorText={this.state.errorTextState}
                        onChange={this._handleErrorInputChange}
                      />
                    </ToolbarGroup>
                  </Toolbar>

                  <div className="clearfix"></div>

                  <Toolbar>
                    <ToolbarGroup key={5} float="right">
                      <span>Where I live</span>
                      <DropDownMenu
                        className="dropdown-long"
                        menuItems={menuItemsIlive}
                        //autoWidth={false}
                      />
                    </ToolbarGroup>
                  </Toolbar>

                  <div className="clearfix"></div>

                  <Toolbar>
                    <ToolbarGroup key={6} float="right">
                      <span>My lifestyle is</span>
                      <DropDownMenu
                        className="dropdown-short"
                        menuItems={menuItemsLifestyle}
                        //autoWidth={false}
                      />
                      <span>and I've saved</span>
                      <DropDownMenu
                        className="dropdown-short"
                        menuItems={menuItemsLifestyle2}
                        //autoWidth={false}
                      />
                    </ToolbarGroup>
                  </Toolbar>

                  <div className="clearfix"></div>

                  <Toolbar>
                    <ToolbarGroup key={7} float="right">
                      <span>My yearly household is about</span>
                      <DropDownMenu
                        className="dropdown-mobile"
                        menuItems={menuItemsIncome}
                        //autoWidth={false}
                      />
                    </ToolbarGroup>
                  </Toolbar>

                  <div className="clearfix"></div>

                  <div className="button-place">
                    <FlatButton
                      onTouchTap={this._handleClick}
                      label="I'm done lets go!"
                    />

                    <Snackbar
                      ref="snackbar"
                      message="Invalid input, please check and try again"
                    />
                  </div>

                </Paper>

              </div>
            </div>
          </div>
        </div>
      </div>
    );
  },

  _handleErrorInputChange: function(e) {
    if (e.target.id === 'name') {
      var name = e.target.value;
      this.setState({
        //name: name,
        errorTextName: e.target.value ? '' : 'Please, type your Name'
      });
    } else if (e.target.id === 'age') {
      var age = e.target.value;
      this.setState({
        //age: age,
        errorTextAge: e.target.value ? '' : 'Check Age'
      });
    } else if (e.target.id === 'city') {
      var city = e.target.value;
      this.setState({
        //city: city,
        errorTextCity: e.target.value ? '' : 'Type City'
      });
    } else if (e.target.id === 'state') {
      var state = e.target.value;
      this.setState({
        //state: state,
        errorTextState: e.target.value ? '' : 'Type State'
      });
    }
  },

  _handleClick: function(e) {
    this.refs.snackbar.show();
    //TODO: find a way to change errorText for all empty TextField
    if (this.refs.textfield && this.refs.textfield.getValue().length === 0) {
      this.setState({
        errorTextState: 'Type State',
        errorTextCity: 'Type City',
        errorTextAge: 'Check Age',
        errorTextName: 'Please, type your Name'
      });
    }
  }

});

module.exports = Content;

Je veux l'envoyer sur le serveur dans la méthode _handleClick.

43
Vitalii Trachenko

Ajoutez un gestionnaire onChange à chacun de vos éléments TextField et DropDownMenu. Lors de son appel, enregistrez la nouvelle valeur de ces entrées dans la variable state de votre composant Content. Dans le rendu, récupérez ces valeurs de state et transmettez-les en tant que value prop. Voir Composants contrôlés .

var Content = React.createClass({

    getInitialState: function() {
        return {
            textFieldValue: ''
        };
    },

    _handleTextFieldChange: function(e) {
        this.setState({
            textFieldValue: e.target.value
        });
    },

    render: function() {
        return (
            <div>
                <TextField value={this.state.textFieldValue} onChange={this._handleTextFieldChange} />
            </div>
        )
    }

});

Maintenant, tout ce que vous avez à faire dans votre méthode _handleClick est de récupérer les valeurs de toutes vos entrées à partir de this.state et de les envoyer au serveur.

Vous pouvez également utiliser le React.addons.LinkedStateMixin pour faciliter ce processus. Voir Assistants de reliure bidirectionnelle . Le code précédent devient:

var Content = React.createClass({

    mixins: [React.addons.LinkedStateMixin],

    getInitialState: function() {
        return {
            textFieldValue: ''
        };
    },

    render: function() {
        return (
            <div>
                <TextField valueLink={this.linkState('textFieldValue')} />
            </div>
        )
    }

});
47

utilise la réponse acceptée/c'était la réponse à une autre question (déjà supprimée)

@ Karopastal

ajoutez un attribut ref à votre composant <TextField /> et appelez-y getValue (), comme ceci:

Composant:

<TextField ref="myField" />

En utilisant getValue:

this.refs.myField.getValue()
70
flson

le code de flson n'a pas fonctionné pour moi. Pour ceux qui se trouvent dans la même situation, voici mon code légèrement différent:

<TextField ref='myTextField'/>

obtenir sa valeur en utilisant 

this.refs.myTextField.input.value

5
Nitin Jadhav

La stratégie de la réponse acceptée est correcte, mais voici un exemple généralisé qui fonctionne avec la version actuelle de React et de Material-UI. 

Le flux de données doit être à sens unique:

  • l'état initial est initialisé dans le constructeur du contrôle MyForm
  • les TextAreas sont remplis à partir de cet état initial
  • les modifications apportées aux TextAreas sont propagées à la state via le rappel handleChange.
  • la state est accessible à partir du rappel onClick - pour le moment, il écrit simplement sur la console. Si vous voulez ajouter une validation, vous pouvez y aller.
import * as React from "react";
import TextField from "material-ui/TextField";
import RaisedButton from "material-ui/RaisedButton";

const initialState = {
    error: null, // you could put error messages here if you wanted
    person: {
        firstname: "",
        lastname: ""
    }
};

export class MyForm extends React.Component {

    constructor(props) {
        super(props);
        this.state = initialState;
        // make sure the "this" variable keeps its scope
        this.handleChange = this.handleChange.bind(this);
        this.onClick = this.onClick.bind(this);
    }

    render() {
        return (
            <div>
                <div>{this.state.error}</div>
                <div>
                    <TextField
                        name="firstname"
                        value={this.state.person.firstname}
                        floatingLabelText="First Name"
                        onChange={this.handleChange}/>
                    <TextField
                        name="lastname"
                        value={this.state.person.lastname}
                        floatingLabelText="Last Name"
                        onChange={this.handleChange}/>
                </div>
                <div>
                    <RaisedButton onClick={this.onClick} label="Submit!" />
                </div>
            </div>
        );
    }

    onClick() {
        console.log("when clicking, the form data is:");
        console.log(this.state.person);
    }

    handleChange(event, newValue): void {
        event.persist(); // allow native event access (see: https://facebook.github.io/react/docs/events.html)
        // give react a function to set the state asynchronously.
        // here it's using the "name" value set on the TextField
        // to set state.person.[firstname|lastname].            
        this.setState((state) => state.person[event.target.name] = newValue);

    }

}


React.render(<MyForm />, document.getElementById('app'));

(Remarque: vous souhaiterez peut-être écrire un rappel handleChange par composant MUI pour éliminer cet appel event.persist() laid.)

3
mikebridge

Voici la solution la plus simple que j'ai proposée, nous obtenons la valeur de l'entrée créée par material-ui textField:

      create(e) {
        e.preventDefault();
        let name = this.refs.name.input.value;
        alert(name);
      }

      constructor(){
        super();
        this.create = this.create.bind(this);
      }

      render() {
        return (
              <form>
                <TextField ref="name" hintText="" floatingLabelText="Your name" /><br/>
                <RaisedButton label="Create" onClick={this.create} primary={true} />
              </form>
        )}

j'espère que cela t'aides.

2
Chtiwi Malek
class Content extends React.Component {
    render() {
        return (
            <TextField ref={(input) => this.input = input} />
        );
    }

    _doSomethingWithData() {
        let inputValue =  this.input.getValue();
    }
}
0