How to implement a dynamic form with controlled components in ReactJS?

后端 未结 4 1557
野性不改
野性不改 2020-11-29 22:18

As I am looking at the examples in the reference for controlled form components in react.js official website, I am wondering how is one supposed to implement a

相关标签:
4条回答
  • 2020-11-29 22:57

    How adding/removing input elements dynamically possible?

    Yes, it is possible, you can add/remove input elements dynamically, But for that you need to take care of few things:

    1- Proper binding of events.

    2- Array to store the values of each input element separately.

    3- When user fill value in any input element then updating only that specific value in state.

    Logic:

    Maintain an array inside state, that will store the values. Use #array.map to create ui (input element) for each array values. while creating the fields, use a remove button with each field, and pass the index of field in that function, it will help you to identify which field you wants to delete, do the same thing for onChange also.

    Check this example:

    class App extends React.Component {
      constructor(props) {
        super(props);
        this.state = { values: [] };
        this.handleSubmit = this.handleSubmit.bind(this);
      }
    
      createUI(){
         return this.state.values.map((el, i) => 
             <div key={i}>
        	    <input type="text" value={el||''} onChange={this.handleChange.bind(this, i)} />
        	    <input type='button' value='remove' onClick={this.removeClick.bind(this, i)}/>
             </div>          
         )
      }
    
      handleChange(i, event) {
         let values = [...this.state.values];
         values[i] = event.target.value;
         this.setState({ values });
      }
      
      addClick(){
        this.setState(prevState => ({ values: [...prevState.values, '']}))
      }
      
      removeClick(i){
         let values = [...this.state.values];
         values.splice(i,1);
         this.setState({ values });
      }
    
      handleSubmit(event) {
        alert('A name was submitted: ' + this.state.values.join(', '));
        event.preventDefault();
      }
    
      render() {
        return (
          <form onSubmit={this.handleSubmit}>
              {this.createUI()}        
              <input type='button' value='add more' onClick={this.addClick.bind(this)}/>
              <input type="submit" value="Submit" />
          </form>
        );
      }
    }
    
    ReactDOM.render(<App />, document.getElementById('container'));
    <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='container'/>

    Check the working jsfiddle: https://jsfiddle.net/mayankshukla5031/ezdxg224/

    0 讨论(0)
  • 2020-11-29 23:02

    How adding/removing input elements dynamically with functional components?

    The same component from the selected answer reviewed and rewrited as a functional component.

    import React from 'react';
    import { useState } from 'react';
    
    function DynamicInput() {
    
        const [values, setValues] = useState({ val: []});
    
          function createInputs() {
            return values.val.map((el, i) =>
              <div key={i}>
                <input type="text" value={el||''} onChange={handleChange.bind(i)} />
                <input type='button' value='remove' onClick={removeClick.bind(i)} />
              </div>
            );
          }
    
        function handleChange(event) {
          let vals = [...values.val];
          vals[this] = event.target.value;
          setValues({ val: vals });
        }
    
        const addClick = () => {
          setValues({ val: [...values.val, '']})
        }
    
        const removeClick = () => {
          let vals = [...values.val];
          vals.splice(this,1);
          setValues({ val: vals });
        }
    
        const handleSubmit = event => {
          alert('A name was submitted: ' + values.val.join(', '));
          event.preventDefault();
        }
    
        return (
          <form onSubmit={handleSubmit}>
              {createInputs()}
              <input type='button' value='add more' onClick={addClick} />
              <input type="submit" value="Submit" />
          </form>
        );
    
    }
    
    export default DynamicInput;
    
    
    0 讨论(0)
  • 2020-11-29 23:09
    import React, { Component, } from 'react';
    import { BrowserRouter as Router, Route, Link } from "react-router-dom";
    var childJson = []
    export default class AddInvoice extends Component {
    constructor(props) {
        super(props);
        this.state = {
            Json: [],
            rows: [{}]
        }
    }
    
    handleChange = idx => e => {
        const { name, value } = e.target;
        const rows = [...this.state.rows];
        rows[idx] = { [name]: value };
        this.setState({ rows });
    
        console.log(`rows-->>${this.state.rows[idx].amount}`);
        childJson.push(this.dynamicJson(this.state.rows, idx))
        this.setState({ Json: childJson })
    
    };
    handleAddRow = () => {
        const item = {
            name: "",
            mobile: "",
            btn: ""
        };
        this.setState({
            rows: [...this.state.rows, item]
        });
    };
    handleRemoveRow = (idx) => {
        this.state.rows.splice(idx, 1);
        this.setState({ rows: this.state.rows });
    };
    dynamicJson(rows, index) {
        return {
            "service": rows[index].text,
            "tax": rows[index].tax,
            "amount": rows[index].amount
        }
    };
    render() {
        return (
            <div className="ui one column grid">
                <div className=" row">
                    <div className="one wide computer one wide tablet one wide mobile column">
                    </div>
                    <div className="fourteen wide computer fourteen wide tablet fourteen wide mobile column">
                        <h1 id="title_header">INVOICE-ADD NEW</h1>
                    </div>
                    <div className="one wide computer one wide tablet one wide mobile column">
                    </div>
                </div>
                <div className=" row">
                    <div className="one wide computer one wide tablet one wide mobile column">
                    </div>
                    <div className="fourteen wide computer fourteen wide tablet fourteen wide mobile column">
                        <div id="#cus_segment" className="ui segment" style={{ backgroundColor: '#f5f5f5' }}>
                            <div className="ui form">
                                <div className="ui  stackable grid">
                                    <div className="six wide column">
                                        <div className="field">
                                            <label>Invoice No</label>
                                            <input type="text" name="invoiceno" placeholder="Invoice No" value={this.state.invoiceno} onChange={e => this.setState({ invoiceno: e.target.value })} />
                                        </div>
                                    </div>
                                    <div className=" six wide column">
                                        <div className="field">
                                            <label>Customer</label>
                                            <select className="ui fluid selection search dropdown" name="customer" value={this.state.customer} onChange={e => this.setState({ customer: e.target.value })}>
                                                <option defaultValue="">select</option>
                                                <option value="sohanpatil@gmail.com">sohanpatil@gmail.com</option>
                                                <option value="mayurawati@gmail.co">mayurawati@gmail.com</option>
                                                <option value="nasirpatel@gmail.com">nasirpatel@gmail.com</option>
                                                <option value="nandkishorshinde@gmail.com">nandkishorshinde@gmail.com</option>
                                            </select>
                                        </div>
                                    </div>
                                    <div className="one row">
                                        <div className="six wide column">
                                            <div className="field">
                                                <label>Invoice Date</label>
                                                <div className="ui calendar" id="calender1">
                                                    <div className="ui input right icon">
                                                        <i className="calendar icon"></i>
                                                        <input type="text" placeholder="Invoice Date" value={this.state.invoicedate} onBlur={e => this.setState({ invoicedate: e.target.value })} />
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                        <div className="six wide column">
                                            <div className="field">
                                                <label>Due Date</label>
                                                <div className="ui calendar" id="calender2">
                                                    <div className="ui input right icon">
                                                        <i className="calendar icon"></i>
                                                        <input type="text" placeholder="Due Date" value={this.state.duedate} onBlur={e => this.setState({ duedate: e.target.value })} />
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                    <div className="two row">
                                        <div className="six wide column">
                                            <div className="field">
                                                <label>Header</label>
                                                <input type="text" name="header" placeholder="Header" value={this.state.header} onChange={e => this.setState({ header: e.target.value })} />
                                            </div>
                                        </div>
                                        <div className="six wide column">
                                            <div className="field">
                                                <label>Remark</label>
                                                <input type="text" name="remark" placeholder="Remark" value={this.state.remark} onChange={e => this.setState({ remark: e.target.value })} />
                                            </div>
                                        </div>
                                    </div>
                                    <div className="three row">
                                        <div className="ten wide column">
                                            <button className="ui primary button" type="submit">Save</button>
                                            <button className="ui  button" type="submit">Clear</button>
                                            <button className="ui  button" type="submit">Cancel</button>
                                        </div>
                                    </div>
    
                                    <div className="foure row">
                                        <div className="one wide column">
                                            <div className="field">
                                                <h4 style={{ textAlign: "center", borderRadius: 2 }}>Action</h4>
                                            </div>
                                        </div>
                                        <div className="two wide column" style={{ marginLeft: 55 }}>
                                            <div className="field">
                                                <h4 style={{ textAlign: "center", borderRadius: 2 }}>Text</h4>
                                            </div>
                                        </div>
                                        <div className="three column" style={{ marginLeft: 200 }}>
                                            <div className="field">
                                                <h4 style={{ textAlign: "center", borderRadius: 2 }}>Tax</h4>
                                            </div>
                                        </div>
                                        <div className="foure wide column" style={{ marginLeft: 190 }}>
                                            <div className="field">
                                                <h4 style={{ textAlign: "center", borderRadius: 2 }}>Amount</h4>
                                            </div>
                                        </div>
                                    </div>
                                    {this.state.rows.map((item, idx) => (
                                        <div className="five row" id="addr0" key={idx} >
                                            <div className="one wide column">
                                                <div className="field">
                                                    <div className="ui icon" style={{ backgroundColor: "#f76060", color: "white", height: 35, width: 40, textAlign: "center", borderRadius: 2 }} onClick={() => this.handleRemoveRow(idx)}>
                                                        <i className="trash alternate icon" style={{ marginTop: 8 }}></i>
                                                    </div>
                                                </div>
                                            </div>
    
                                            <div className="five wide column">
                                                <div className="field">
                                                    <input type="text" name="text" placeholder="text" value={this.state.rows[idx].text} onChange={this.handleChange(idx)} />
                                                </div>
                                            </div>
    
                                            <div className="three wide column">
                                                <div className="field">
                                                    <select className="ui fluid selection search dropdown " name="tax" id="tax_dropdown" value={this.state.rows[idx].tax} onChange={this.handleChange.bind(this)}>
                                                        <option defaultValue="">Select</option>
                                                        <option value="STAX">STAX</option>
                                                        <option value="VAT">VAT</option>
                                                    </select>
                                                </div>
                                            </div>
    
                                            <div className="three wide column">
                                                <div className="field">
                                                    <input type="text" name="amount" placeholder="amount" value={this.state.rows[idx].amount} onChange={this.handleChange(idx)} />
                                                </div>
                                            </div>
                                        </div>
    
                                    ))}
                                    <div className="six row">
                                        <div className="two wide column">
                                            <div className="field">
                                                <div className="ui icon" style={{ backgroundColor: "#c4d3d3", height: 35, width: 55, textAlign: "center", borderRadius: 2 }} onClick={this.handleAddRow}>
                                                    <i className="plus icon" style={{ marginTop: 8 }}></i>
                                                    <label>Add</label>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div className="one wide computer one wide tablet one wide mobile column">
                    </div>
                </div>
    
            </div>
        );
    }
    

    }

    0 讨论(0)
  • 2020-11-29 23:15

    You can easily use your state or the props that you are passing from other components to decide what your form should be.

    Here a dumb example:

    class NameForm extends React.Component {
      constructor(props) {
        super(props);
        this.state = {value: ''};
    
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
      }
    
      handleChange(event) {
        this.setState({value: event.target.value});
      }
    
      handleSubmit(event) {
        alert('A name was submitted: ' + this.state.value);
        event.preventDefault();
      }
    
      render() {
        let myForm;
        if(this.props.someprop == true){
           myForm = (
               <form onSubmit={this.handleSubmit}>
                  <label>
                     Name:
                     <input type="text" value={this.state.value} onChange=      {this.handleChange} />
                  </label>
                  <input type="submit" value="Submit" />
               </form>
           );
        }
        else if(this.state.statevar == "expectedValue"){
            myForm = (
               // other HTML with embedded JS here
            );
        }
    
    
        return (
             {myForm}
        );
      }
    }
    

    I did it in the render method just to be clear but all the logic can be moved in auxiliary functions.

    0 讨论(0)
提交回复
热议问题