Несколько полей, появляющихся под родителем в ReactJs - PullRequest
1 голос
/ 19 сентября 2019

class CriteriaSetValue extends Component {
  state = {
  
    count: 0,

    tableName: "",
    fieldName:"",

    tables: [],
    fields: [],
    addLine: [],
    addField: []
  };

  onSubmit = e => {
    e.preventDefault();
    const addField = this.state.addField;
    const size = addField.length + 1;
    addField.push(size);
    this.setState({
      addField
    });

addNewLine = event => {
    event.preventDefault();
    const addLine = this.state.addLine;
    const size = addLine.length + 1;
    const nextLine = this.state.count + 1;
    addLine.push(size);
    this.setState({
      count: nextLine,
      addLine
    });
  };

 render() {
    const {showForm, tableName, fieldName } = this.state;

    const { props, state } = this;

    return (
      <React.Fragment>
      

        <div className="form-wrapper">
          <div className="row">
            <div className="col-10 container">
              <form onSubmit={this.submit} className="card">
                <div className="card-header">
                  <h3 className="card-title">
                    Criteria Set
                    {/* <Locale value="std.formupload" /> */}
                  </h3>
                </div>
                <div className="card-body">
                  <div className="row">
                    <div className="col-md-7 col-lg-8">
                     
                      <div className="add-line">
                        <Button
                          icon
                          labelPosition="left"
                          onClick={this.addNewLine}
                        >
                          Add Line
                          <Icon name="plus" />
                        </Button>
                        {this.state.addLine.map(index => {
                          return (
                            <div
                              className="field-line"
                              style={{ marginTop: "30px" }}
                              key={index}
                              id={index}
                            >
                              <h4 className="field-button">Line {index}</h4>
                              <Button
                                className="field-button"
                                icon
                                onClick={this.toggleForm}
                              >
                                <Icon name="box" />
                              </Button>
                            </div>
                          );
                          
                        })
                        }

                        {
                          this.state.addField.map(index => {
                          return (
                            <React.Fragment>
                              <div
                                className="field-button"
                                style={{
                                  marginTop: "20px",
                                  paddingLeft: "20px"
                                }}
                                key={index}
                                id={index}
                              >
                        
                                <h4
                                  className="field-button"
                                  onclick={this.addCriteriaValue}
                                >
                                  <span>
                                    table.field
                                   
                                  </span>
                                </h4>

                                <Button
                                  className="field-button"
                                  icon
                                  onClick={this.toggleDelete}
                                >
                                  <Icon name="delete calendar" />
                                </Button>
                              </div>
                              <br></br>
                            </React.Fragment>
                          );
                        })
                        }
                      </div>

                    </div>
                  </div>
                </div>
              </form>
            </div>
          </div>
        </div>
      </React.Fragment>
    );
  }
};

Это как-то связано с тем, чего я пытаюсь достичь: https://codesandbox.io/s/3vqyo8xlx5

Но я хочу, чтобы ребенок появлялся под предпочтением того, гдеНажата кнопка «Добавить дочерний элемент», а не последняя.

Я работаю над созданием нескольких полей, которые будут отображаться под каждой строкой, когда нажата кнопка рядом со строкой1, строкой2 и т. Д., Но в настоящее время это полепереход к последним строкам при нажатии кнопки, она не отображается на соответствующей строке.enter image description here

Мне удалось показать линии, когда нажата кнопка «Добавить линию», и я также смог показать поле, когда кнопка рядом с «Линия № 1»нажата.

enter image description here

Я хочу, чтобы поля "Строка № 1" отображались под строкой 1 при нажатии кнопки поля, поле для "Строка № 2 », которая отображается под строкой 2 при нажатии кнопки рядом с полем и т. Д.

enter image description here

1 Ответ

1 голос
/ 19 сентября 2019

Вы можете попробовать что-то вроде этого:

const AddButton = ({ label, onClick }) => (
  <button onClick={onClick}>
    {label} [+]
  </button>
)

const FieldData = ({ label, criterias, onAdd, onDelete }) => (
  <React.Fragment>
    <div
      className='field-button'
      style={{
        marginTop: '20px',
        paddingLeft: '20px'
      }}
    >
      <h4 className='field-button'>
        <AddButton
          label='Add criteria'
          onClick={onAdd}
        />
        <span>
          {label}
        </span>
      </h4>
      {criterias.map((item, idx) => (
        <p key={idx}>{item.id}</p>
      ))}
      <button
        className='field-button'
        onClick={onDelete}
      >
        Del [-]
      </button>
    </div>
    <br />
  </React.Fragment>
)

class App extends React.PureComponent {
  state = {
    lines: []
  }

  handleSubmit = e => {
    e.preventDefault()
    console.log('DATA TO SAVE ' + JSON.stringify(this.state.lines))
  }
  
  handleAddLine = event => {
    event.preventDefault()
    this.setState(prevState => ({
      ...prevState,
      lines: [
        ...prevState.lines,
        {
         id: (prevState.lines.length + 1),
         fields: []
        }
      ]
    }))
  }
  
  handleAddField = lineId => e => {
    e.preventDefault()
    this.setState(prevState => {
      const newLines = [ ...prevState.lines ]
      const curLine = newLines[newLines.findIndex(({ id }) => id === lineId)]

      curLine.fields.push({
        id: curLine.fields.length + 1,
        criterias: []
      })
      
       return {
        ...prevState,
        lines: newLines
      }
    })
  }

  handleAddCriteria = (lineId, fieldId) => event => {
    event.preventDefault()
    
    this.setState(prevState => {
      const newLines = [ ...prevState.lines ]
      const curLine = newLines[newLines.findIndex(({ id }) => id === lineId)]
      const curField =  curLine.fields[curLine.fields.findIndex(({ id }) => id === fieldId)]

      curField.criterias.push({
        id: curField.criterias.length + 1
      })
      
      return {
        ...prevState,
        lines: newLines
      }
    })
  }
  
  handleDeleteField = (lineId, fieldId) => event => {
    event.preventDefault()
    this.setState(prevState => {
      const newLines = [ ...prevState.lines ]
      const curLine = newLines[newLines.findIndex(({ id }) => id === lineId)]
      curLine.fields =  curLine.fields.filter(item => item.id !== fieldId)
      
      return {
        ...prevState,
        lines: newLines
      }
    })
  }
  
  render() {
    const { lines } = this.state

    return (
      <React.Fragment>
        <div className='form-wrapper'>
          <div className='row'>
            <div className='col-10 container'>
              <form
                onSubmit={this.handleSubmit}
                className='card' 
              >
                <div className='card-header'>
                  <h3 className='card-title'>
                    Criteria Set
                  </h3>
                </div>
                <div className='card-body'>
                  <div className='row'>
                    <div className='col-md-7 col-lg-8'>
                      <div className='add-line'>
                        <AddButton
                          label='Add Line'
                          onClick={this.handleAddLine}
                        />
                        {lines.map((line, idx) => {
                          return (
                            <React.Fragment key={idx}>
                              <div
                                className='field-line'
                                style={{ marginTop: '30px' }}
                              >
                                <h4 className='field-button'>
                                  Line {idx+1}
                                </h4>
                                <AddButton
                                  label='Add field'
                                  onClick={this.handleAddField(line.id)}
                                />
                              </div>
                              {line.fields.map((lField, idx) => (
                                <FieldData
                                  label={idx+1}
                                  criterias={lField.criterias}
                                  onAdd={this.handleAddCriteria(line.id, lField.id)}
                                  onDelete={this.handleDeleteField(line.id, lField.id)}
                                />
                              ))}                    
                            </React.Fragment>
                          )
                        })}
                      </div>
                    </div>
                  </div>
                </div>
              </form>
            </div>
          </div>
        </div>
      </React.Fragment>
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('app')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="app"></div>

Я определил новую структуру данных для состояния, поэтому лучше подумать о вложенных данных, и я немного переработал код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...