110 votes

Effacer et réinitialiser les champs de saisie des formulaires

J'ai un formulaire contenant plusieurs champs de saisie et deux boutons : un pour l'envoi et un pour l'annulation.

<form id="create-course-form">
  <input type="text" name="course_Name" ref="fieldName">
  <input type="text" name="course_org" ref="fieldOrg">
  <input type="text" name="course_Number" ref="fieldNum">

  <input type="submit" name="saveCourse" value="Create">
  <input type="button" name="cancelCourse" value="cancel" onClick={this.cancelCourse}>
</form>

Ce que je veux, c'est vider toutes les entrées lorsque le bouton d'annulation est cliqué. Jusqu'à présent, j'ai réussi à le faire en utilisant l'attribut réf. prop.

cancelCourse(){
  this.refs.fieldName.value="";
  this.refs.fieldorg.value="";
  this.refs.fieldNum.value="";
}

Cependant, je veux vider les champs de saisie sans avoir à vider chacun d'eux séparément. Je veux quelque chose de similaire à ceci (jQuery) : $('#create-course-form input[type=text]').val('');

1 votes

Utilisez l'entrée gérée.

151voto

Chris Points 3970

La réponse dépend ici du fait que vos entrées sont ou non contrôlé ou incontrôlé . Si vous n'êtes pas sûr de vous ou si vous avez besoin de plus d'informations à ce sujet, consultez les documents officiels sur le site Web de la Commission européenne. composants contrôlés et composants non contrôlés . Merci @Dan-Esparza pour avoir fourni les liens.

Veuillez également noter que l'utilisation de chaînes de caractères dans ref est déprécié . Utilisez plutôt la méthode de rappel standard.


Effacer un formulaire avec des champs non contrôlés

Vous pouvez effacer l'ensemble du formulaire plutôt que chaque champ du formulaire individuellement.

cancelCourse = () => { 
  document.getElementById("create-course-form").reset();
}

render() {
  return (
    <form id="create-course-form">
      <input />
      <input />
      ...
      <input />
    </form>
  );
}

Si votre formulaire n'avait pas de id vous pourriez utiliser un attribut ref également :

cancelCourse = () => { 
  this.myFormRef.reset();
}

render() {
  return (
    <form ref={(el) => this.myFormRef = el;}>
      <input />
      <input />
      ...
      <input />
    </form>
  );
}

Effacer un formulaire avec des champs contrôlés

Si vous utilisez des champs de formulaire contrôlés, vous devrez peut-être réinitialiser explicitement chaque composant de votre formulaire, en fonction de la manière dont vos valeurs sont stockées dans l'état.

S'ils sont déclarés individuellement, vous devez réinitialiser chacun d'eux explicitement :

cancelCourse = () => { 
  this.setState({
    inputVal_1: "",
    inputVal_2: "",
    ...
    inputVal_n: "",
  });
}

render() {
  return (
    <input value={this.state.inputVal_1} onChange={this.handleInput1Change}>
    <input value={this.state.inputVal_2} onChange={this.handleInput2Change}>
    ...
    <input value={this.state.inputVal_n} onChange={this.handleInputnChange}>
  );
}

Démonstration ci-dessous :

class MyApp extends React.Component {
  constructor() {
    super();
    this.state = {
      inputVal_1: "",
      inputVal_2: "",
      inputVal_3: "",
      inputVal_4: "",
      inputVal_5: "",
      inputVal_6: "",
      inputVal_7: "",
      inputVal_8: "",
      inputVal_9: "",
      inputVal_10: ""
    };
  }

  handleInput1Change = (e) => {
    this.setState({inputVal_1: e.target.value});
  }

  handleInput2Change = (e) => {
    this.setState({inputVal_2: e.target.value});
  }

  handleInput3Change = (e) => {
    this.setState({inputVal_3: e.target.value});
  }

  handleInput4Change = (e) => {
    this.setState({inputVal_4: e.target.value});
  }

  handleInput5Change = (e) => {
    this.setState({inputVal_5: e.target.value});
  }

  handleInput6Change = (e) => {
    this.setState({inputVal_6: e.target.value});
  }

  handleInput7Change = (e) => {
    this.setState({inputVal_7: e.target.value});
  }

  handleInput8Change = (e) => {
    this.setState({inputVal_8: e.target.value});
  }

  handleInput9Change = (e) => {
    this.setState({inputVal_9: e.target.value});
  }

  handleInput10Change = (e) => {
    this.setState({inputVal_10: e.target.value});
  }

  cancelCourse = () => { 
    this.setState({
      inputVal_1: "",
      inputVal_2: "",
      inputVal_3: "",
      inputVal_4: "",
      inputVal_5: "",
      inputVal_6: "",
      inputVal_7: "",
      inputVal_8: "",
      inputVal_9: "",
      inputVal_10: ""
    });
  }

  render() {
    return (
      <form>
        <input value={this.state.inputVal_1} onChange={this.handleInput1Change} />
        <input value={this.state.inputVal_2} onChange={this.handleInput2Change} />
        <input value={this.state.inputVal_3} onChange={this.handleInput3Change} />
        <input value={this.state.inputVal_4} onChange={this.handleInput4Change} />
        <input value={this.state.inputVal_5} onChange={this.handleInput5Change} />
        <input value={this.state.inputVal_6} onChange={this.handleInput6Change} />
        <input value={this.state.inputVal_7} onChange={this.handleInput7Change} />
        <input value={this.state.inputVal_8} onChange={this.handleInput8Change} />
        <input value={this.state.inputVal_9} onChange={this.handleInput9Change} />
        <input value={this.state.inputVal_10} onChange={this.handleInput10Change} />
        <input type="submit" name="saveCourse" value="Create" />
        <input type="button" name="cancelCourse" value="cancel" onClick={this.cancelCourse} />
      </form>
    );
  }
}

ReactDOM.render(<MyApp />, document.getElementById("app"));

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

Il existe cependant un moyen plus propre de le faire. Plutôt que d'avoir n les propriétés de l'état et n des gestionnaires d'événements, un pour chaque entrée, avec un codage astucieux nous pouvons réduire le code de façon spectaculaire.

Dans le constructeur, nous déclarons simplement un objet vide, qui sera utilisé pour contenir les valeurs d'entrée. Nous n'utilisons qu'un seul gestionnaire d'entrée et lui passons l'index de l'élément d'entrée dont nous voulons modifier la valeur. Cela signifie que la valeur d'une entrée individuelle est générée au moment où nous commençons à taper dedans.

Pour réinitialiser le formulaire, il suffit de faire en sorte que notre objet input redevienne vide.

La valeur d'entrée est this.state.inputVal[i] . Si i n'existe pas (nous n'avons encore rien tapé dans cette entrée), nous voulons que la valeur soit une chaîne vide (au lieu de null).

cancelCourse = () => { 
  this.setState({inputVal: {}});
}

render() {
  return (
    <form>
      {[...Array(n)].map(
        (item, i) => <input value={this.state.inputVal[i] || ""} onChange={this.handleInputChange.bind(this, i)} />
      )}
    </form>
  );
}

Démonstration ci-dessous :

class MyApp extends React.Component {
  constructor() {
    super();
    this.state = {
      inputVal: {}
    };
  }

  handleInputChange = (idx, {target}) => {
    this.setState(({inputVal}) => {
      inputVal[idx] = target.value;
      return inputVal;
    });
  }

  cancelCourse = () => { 
    this.setState({inputVal: {}});
  }

  render() {
    return(
      <form>
        {[...Array(10)].map(  //create an array with a length of 10
          (item, i) => <input value={this.state.inputVal[i] || ""} onChange={this.handleInputChange.bind(this, i)} />  //bind the index to the input handler
        )}
        <input type="submit" name="saveCourse" value="Create" />
        <input type="button" name="cancelCourse" value="cancel" onClick={this.cancelCourse} />
      </form>
    );
  }
}

ReactDOM.render(<MyApp />, document.getElementById("app"));

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

1 votes

Merci pour votre réponse, j'utilise des fichiers non contrôlés donc j'ai utilisé la fonction reset(), cela fonctionne comme un charme maintenant.

3 votes

Pour les futurs lecteurs qui se demandent ce que sont les champs "contrôlés" et les champs "non contrôlés", consultez le site Web de la Commission européenne. documents sur la page d'accueil de React pour travailler avec des formulaires .

0 votes

@Chris : quelle est la meilleure pratique pour vider un formulaire en utilisant des composants contrôlés ? On m'a dit que "Définir l'état d'une entrée à '' est considéré comme un anti-modèle", ils ont suggéré d'utiliser ceci sur componentWillUnmount mais avec prudence. Et comme alternative d'utiliser document.getElementByID("someID").value = '' donc je suis perdu ? des idées ?

117voto

Trần Bảo Huy Points 425

Très facile :

handleSubmit(e){
    e.preventDefault();
    e.target.reset();
}

<form onSubmit={this.handleSubmit.bind(this)}>
  ...
</form>

Bonne chance :)

1 votes

J'obtiens cette erreur TypeError: Cannot read property 'preventDefault' of undefined Au lieu du formulaire, j'ai un autre composant où j'appelle handleSubmit(). J'utilise react js

0 votes

@tramada il nettoie toutes les entrées dans le formulaire pour moi. Revérifiez svp

0 votes

Littéralement la meilleure réponse à la question de savoir comment réinitialiser les entrées du formulaire.

20voto

Andrea Points 101

Utilisation de event.target.reset() ne fonctionne que pour les composants non contrôlés, ce qui n'est pas recommandé. Pour les composants contrôlés, vous devriez faire quelque chose comme ceci :

import React, { Component } from 'react'

class MyForm extends Component {
  initialState = { name: '' }

  state = this.initialState

  handleFormReset = () => {
    this.setState(() => this.initialState)
  }

  render() {

    return (
      <form onReset={this.handleFormReset}>
        <div>
          <label htmlFor="name">Name</label>
          <input
            type="text"
            placeholder="Enter name"
            name="name"
            value={name}
            onChange={this.handleInputOnChange}
          />
        </div>
        <div>
          <input
            type="submit"
            value="Submit"
          />
          <input
            type="reset"
            value="Reset"
          />
        </div>
      </form>
    )
  }
}

ContactAdd.propTypes = {}

export default MyForm

0 votes

+1 pour votre utilisation de initialState Cette fonction est idéale si vous devez réinitialiser un formulaire à plusieurs endroits (bouton de réinitialisation, mais aussi après soumission, par exemple).

0 votes

C'est la solution correcte dans React

2voto

Sharad Pawar Points 66

Le code suivant devrait réinitialiser le formulaire en un clic.

import React, { Component } from 'react';

class App extends Component {
    constructor(props){
        super(props);
        this.handleSubmit=this.handleSubmit.bind(this);
    }
    handleSubmit(e){
    this.refs.form.reset();
    }
    render(){
        return(
        <div>
            <form onSubmit={this.handleSubmit} ref="form">
                <input type="text" placeholder="First Name!" ref='firstName'/><br/<br/>
                <input type="text" placeholder="Last Name!" ref='lastName'/><br/><br/>
                <button type="submit" >submit</button>
            </form>
       </div>
    }
}

1 votes

C'est exact, mais j'ai déjà abordé ce point dans ma réponse. De plus, l'utilisation de chaînes littérales pour refs est déprécié. reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs

0 votes

@Chris, ouais c'est vrai comme refs difficile à tester, surtout lorsqu'on utilise shallow

1voto

Webman Points 404

Pour effacer votre formulaire, en admettant que les valeurs des éléments de votre formulaire sont sauvegardées dans votre état, vous pouvez passer par votre état comme ceci :

  // clear all your form
  Object.keys(this.state).map((key, index) => {
      this.setState({[key] : ""});
   });

Si votre formulaire se trouve parmi d'autres champs, vous pouvez simplement les insérer dans un champ particulier de l'état comme cela :

 state={ 
        form: {
        name:"",
        email:""}
      }

      // handle set in nested objects
      handleChange = (e) =>{ 
        e.preventDefault(); 

        const newState = Object.assign({}, this.state);
        newState.form[e.target.name] = e.target.value;
        this.setState(newState);
      }

      // submit and clear state in nested object 
      onSubmit = (e) =>{ 
        e.preventDefault(); 

       var form =   Object.assign({}, this.state.form);
       Object.keys(form).map((key, index) => {
          form[key] = "" ;
        });

       this.setState({form})
      }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X