动态添加/删除表单输入块 [英] Add/remove form inputs block dynamically

查看:41
本文介绍了动态添加/删除表单输入块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我单击加号按钮时,我想重复同一行字段.我尝试根据状态属性 plus 来实现此功能,该状态属性在单击按钮时变为true,然后检查此状态属性是否为true?添加字段:null.但这不起作用,我想我缺少一些概念,请帮忙!

I want to repeat the same line of fields when i click on the plus button. I tried to implement this functionality based on an state attribute plus that changed to true when i click on the button then i check if this state attribute is true? add the Fields : null. but it doesn't work and i think i am missing some concept so please some help!

  this.state = {
            plus : false 
        }

plusHandler:

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 }

这是我想要的输出:

推荐答案

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

I'd think of it not as add/remove input fields, but rather as managing your form state to maintain necessary elements visibility.

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

As long as you're going to access values, selected in those input fields (e.g. upon form submit), instead of using boolean flag, you may need to store dynamic form rows within your state as array of following structure:

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

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

For simplicity sake, I'd also re-design your dynamic form rows as a separate component.

这样,我将行组件中添加/删除按钮的 onClick()事件处理程序附加到父窗体组件的回调中,该父窗体组件将在其状态内追加/删除数组项,从而使行组件出现/消失.

With that, I'd attach onClick() event handlers of add/remove buttons within row component to callbacks of parent form component that will append/remove array items within its state, thus making corresponding row components appear/disappear.

您可以在下面的实时摘要中查询该概念的完整说明:

You may inquiry following live-snippet for complete demonstration of that concept:

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>

这篇关于动态添加/删除表单输入块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆