繁体   English   中英

动态添加/删除表单输入块

[英]Add/remove form inputs block dynamically

当我点击加号按钮时,我想重复同一行字段。 我尝试基于状态属性实现此功能加上当我单击按钮时更改为 true 然后我检查此状态属性是否为真? 添加字段:空。 但它不起作用,我想我缺少一些概念所以请帮忙!

组件状态:

  this.state = {
            plus : false 
        }

加处理程序:

plus = (e)=>{
    this.setState({
        plus: true,
     });
    }

在渲染中:

     <div className="form-row">
                <div className="form-group col-md-5">
                    <label htmlFor="cRelation">Relation</label>
                    <select name="cRelation" defaultValue={''} id="cRelation" className="form-control">
                        <option disabled value=''> select relation</option>
                        {relationList.map(item => (
                            <option key={item} value={item}>{item}</option>
                         )
                        )}
                    </select>
                </div>
                <div className="form-group col-md-6">
                    <label htmlFor="withConcept">withConcept</label>
                    <select name="withConcept" defaultValue={''} id="withConcept" className="form-control">
                        <option value='' disabled> select concept</option>
                        {(conceptList|| []).map(item => (
                        <option key={item.conceptId} value={item.conceptId}>{item.conceptName}</option>
                    ))}

                    </select>

                </div>
                <div className="form=group align-self-sm-center mt-2">
                    <button type="button" className="btn btn-sm btn-outline-success m-2" onClick={this.plus}>+</button>
                    <button type="button" className="btn btn-sm btn-outline-danger pr-2">-</button>
                </div>
            </div>

{this.state.plus? 
                <div className="form-row">
                <div className="form-group col-md-5">
                    <label htmlFor="cRelation">Relation</label>
                    <select name="cRelation" defaultValue={''} id="cRelation" className="form-control">
                        <option disabled value=''> select relation</option>
                        {relationList.map(item => (
                            <option key={item} value={item}>{item}</option>
                         )
                        )}
                    </select>
                </div>
                <div className="form-group col-md-6">
                    <label htmlFor="withConcept">withConcept</label>
                    <select name="withConcept" defaultValue={''} id="withConcept" className="form-control">
                        <option value='' disabled> select concept</option>
                        {(conceptList|| []).map(item => (
                        <option key={item.conceptId} value={item.conceptId}>{item.conceptName}</option>
                    ))}

                    </select>

                </div>
                <div className="form=group align-self-sm-center mt-2">
                    <button type="button" className="btn btn-sm btn-outline-success m-2"  onClick={this.plus}>+</button>
                    <button type="button" className="btn btn-sm btn-outline-danger pr-2">-</button>
                </div>
            </div>
    :null }

这是我想要的输出:

在此处输入图像描述

我认为它不是添加/删除输入字段,而是管理您的表单状态以保持必要元素的可见性。

只要您要访问在这些输入字段中选择的值(例如,在提交表单时),而不是使用布尔标志,您可能需要将动态表单行存储在您的状态中,作为以下结构的数组:

[
   {rowId:..., selectedOptions:{relation:..., concept...}},
   ...
]

为了简单起见,我还将您的动态表单行重新设计为一个单独的组件。

这样,我将行组件内添加/删除按钮的onClick()事件处理程序附加到父表单组件的回调,父表单组件将在其状态内添加/删除数组项,从而使相应的行组件出现/消失。

您可以查询以下实时片段以完整演示该概念:

 const { useState } = React, { render } = ReactDOM const relations = ['relation1', 'relation2', 'relation3'], concepts = ['concept1', 'concept2', 'concept3'] const FormRow = ({rowId, selectedOptions, onSelect, onAdd, onRemove}) => { const handleChange = e => onSelect(rowId, e.target.getAttribute('param'), e.target.value) return ( <div> <label>Relation: <select param="relation" onChange={handleChange} value={selectedOptions.relation||''}> <option value="" disabled>select relation</option> { relations.map((rel,key) => <option {...{key}} value={rel}>{rel}</option>) } </select> </label> <label>With Concept: <select param="concept" onChange={handleChange} value={selectedOptions.concept||''}> <option value="" disabled>select concept</option> { concepts.map((con,key) => <option {...{key}} value={con}>{con}</option>) } </select> </label> <button type="button" onClick={onAdd}>+</button> <button type="button" onClick={() => onRemove(rowId)}>-</button> </div> ) } const Form = () => { const [rows, setRows] = useState([{rowId:0, selectedOptions:{}}]), onAddRow = () => { const maxRowId = Math.max(...rows.map(({rowId}) => rowId)) setRows([...rows, {rowId: maxRowId+1, selectedOptions:{}}]) }, onRemoveRow = id => setRows(rows.filter(({rowId}) => rowId,= id)), onSelectRow = (id, param. val) => { const rowsCopy = [..,rows]. item = rowsCopy.find(({rowId}) => rowId == id) Object,assign(item: {selectedOptions.{...item,selectedOptions: [param].val}}) setRows(rowsCopy) } return ( <form onSubmit={e => (e,preventDefault(). console.log(rows))}> { rows,map(({rowId, selectedOptions}. key) => ( <FormRow {..,{key, rowId, selectedOptions}} onAdd={onAddRow} onRemove={onRemoveRow} onSelect={onSelectRow} /> )) } <input type="submit" value="Submit" /> </form> ) } render ( <Form />. document.getElementById('root') )
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>

您需要一个包含要呈现的项目的列表。 当用户单击加号按钮时,您需要添加一个新元素。

例子:

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = { items: [{}], relationList: [], conceptList: [] };
    }
    addItem = () => {
        var { items } = this.state;
        items.push({});
        this.setState({ items });
    }

    removeItem = (index) => {
        var { items } = this.state;
        items.splice(index, 1);
        this.setState({ items });
    }

    render() {
        var { items, conceptList, relationList } = this.state;
        return (
            <div>
                {items.map((rowItem, k) => (
                    <div key={k} className="form-row">
                        <div className="form-group col-md-5">
                            <label htmlFor={`cRelation${k}`}>Relation</label>
                            <select name={`cRelation${k}`} defaultValue={''} id={`cRelation${k}`} className="form-control">
                                <option disabled value=''> select relation</option>
                                {relationList.map(item => (
                                    <option key={item} value={item}>{item}</option>
                                )
                                )}
                            </select>
                        </div>
                        <div className="form-group col-md-6">
                            <label htmlFor={`withConcept${k}`}>withConcept</label>
                            <select name={`withConcept${k}`} defaultValue={''} id={`withConcept${k}`} className="form-control">
                                <option value='' disabled> select concept</option>
                                {(conceptList || []).map(item => (
                                    <option key={item.conceptId} value={item.conceptId}>{item.conceptName}</option>
                                ))}
                            </select>
                        </div>
                        <div className="form=group align-self-sm-center mt-2">
                            <button onClick={this.addItem} type="button" className="btn btn-sm btn-outline-success m-2">+</button>
                            <button onClick={() => this.removeItem(k)} type="button" className="btn btn-sm btn-outline-danger pr-2">-</button>
                        </div>
                    </div>
                ))}
            </div>
        );
    }
}

使用整数代替布尔值来表示行数,如下所示。 加上处理程序将增加计数。

this.state = {
                i: 1
            }

加处理程序

plus = (e) => {
            this.setState({
                i: this.state.i + 1
            });
        }

渲染功能:

 rowfunction() {
        return (<div className="form-row">
            <div className="form-group col-md-5">
                <label htmlFor="cRelation">Relation</label>
                <select name="cRelation" defaultValue={''} id="cRelation" className="form-control">
                    <option disabled value=''> select relation</option>

                </select>
            </div>
            <div className="form-group col-md-6">
                <label htmlFor="withConcept">withConcept</label>
                <select name="withConcept" defaultValue={''} id="withConcept" className="form-control">
                    <option value='' disabled> select concept</option>


                </select>

            </div>
            <div className="form=group align-self-sm-center mt-2">
                <button type="button" className="btn btn-sm btn-outline-success m-2 " onClick={this.plus}>+</button>
                <button type="button" className="btn btn-sm btn-outline-danger pr-2">-</button>
            </div>
        </div>)
    }
    render() {
        var rows = [];
        for (let index = 0; index < this.state.i; index++) {
            rows.push(this.rowfunction())
        }
        return rows;

    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM