bietkul / react-reactive-form

Angular like reactive forms in React.
MIT License
309 stars 32 forks source link

Dynamically adding radio inputs #5

Closed michaelspeed closed 6 years ago

michaelspeed commented 6 years ago

how can we dynamically add radio input with label?

bietkul commented 6 years ago

Can you please specify your use case?

michaelspeed commented 6 years ago

i am specifically creating a form builder like this -

` class regForm extends Component { constructor(props) { super(props) this.registrationForm = FormBuilder.group({ formName: ['', Validators.required], items: FormBuilder.array([]) }) }

  createItem = () => { 
    return FormBuilder.group({
      label: '',
      type: 1,
      array: FormBuilder.array([])
    })
  }

  addItem = () => { 
    const itemControls = this.registrationForm.get('items')
    itemControls.push(this.createItem())
 }

  handleSubmit = () => { 
    console.log(this.registrationForm.value)
  }

  createInputItem = () => {
    return FormBuilder.group({
     answer: '',
      type: 1
    })
  }

  createCheckBox = () => { 
     return FormBuilder.group({
      checkBox: false,
      label: ''
    })
  }

  createRadio = () => { 
    return FormBuilder.group({
      radio: false,
      label: ''
    })
  }

  createSwitch = () => { 
    return FormBuilder.group({
      switch: false,
      label: ''
     })
  }

  addInput = productControl => { 
    const controlItem1 = productControl.get('array')
    controlItem1.push(this.createInputItem())
  }

  addCheckBoxItem = productControl => { 
    const controlItem2 = productControl.get('array')
    controlItem2.push(this.createCheckBox())
  }
  addRadioItem = productControl => { 
    const controlItem2 = productControl.get('array')
    controlItem2.push(this.createRadio())
  }

  addSwitch = productControl => { 
     const controlItem2 = productControl.get('array')
    controlItem2.push(this.createSwitch())
  }

  renderExtraControls = (productControl, value, get) => { 
    switch (value) { 
      case 1: 

  return (
    <Field control={get('array')} render={({ controls }) => (
      <div>
        <Button onClick={() => this.addInput(productControl)} appearance='primary'>Add Input</Button>  
        {controls.map((customConrtol, index) => (
          <div key={index}>
            <Field control={customConrtol} render={({ get }) => (
              <div>
                <Field control={get('answer')} render={({ handler }) => (
                  <Input {...handler()} />
                )}/>  
              </div>
            )}/>
          </div>
        ))}  
      </div>
    )}/>
  )
  case 2:    

    return (
      <Field control={get('array')} render={({ controls }) => (
        <div>
        <Button onClick={() => this.addCheckBoxItem(productControl)} appearance='primary'>Add Input</Button>  
          {controls.map((customConrtol, index) => (
            <div key={index}>
              <Field control={customConrtol} render={({ get }) => (
                <div>
                  <Field control={get('checkBox')} render={({ handler }) => (
                    <Checkbox {...handler('checkbox')}/>
                  )}/>  
                  <Field control={get('label')} render={({ handler }) => (
                    <Input {...handler()}/>
                  )}/>  
                </div>
              )}/>
            </div>
          ))}  
        </div>
      )}/>
    )
  case 3:
    return (
      <Field control={get('array')} render={({ controls }) => (
        <div>
        <Button onClick={() => this.addRadioItem(productControl)} appearance='primary'>Add Input</Button>  
          {controls.map((customConrtol, index) => (
            <div key={index}>
              <Field control={customConrtol} render={({ get }) => (
                <div>
                  <Field control={get('radio')} render={({ handler }) => (
                    <Radio {...handler('radio')}/>
                  )}/>  
                  <Field control={get('label')} render={({ handler }) => (
                    <Input {...handler()}/>
                  )}/>  
                </div>
              )}/>
            </div>
          ))}  
        </div>
      )}/>
    )
  case 4:
    return (
      <Field control={get('array')} render={({ controls }) => (
        <div>
          <Button onClick={() => this.addInput(productControl)} appearance='primary'>Add Input</Button>  
          {controls.map((customConrtol, index) => (
            <div key={index}>
              <Field control={customConrtol} render={({ get }) => (
                <div>
                  <Field control={get('answer')} render={({ handler }) => (
                    <TextArea {...handler()} />
                  )}/>  
                </div>
              )}/>
            </div>
          ))}  
        </div>
      )}/>
    )
  case 5:
    return (
      <Field control={get('array')} render={({ controls }) => (
        <div>
        <Button onClick={() => this.addSwitch(productControl)} appearance='primary'>Add Input</Button>  
          {controls.map((customConrtol, index) => (
            <div key={index}>
              <Field control={customConrtol} render={({ get }) => (
                <div>
                  <Field control={get('switch')} render={({ handler }) => (
                    <Switch {...handler('checkbox')}/>
                  )}/>  
                  <Field control={get('label')} render={({ handler }) => (
                    <Input {...handler()}/>
                  )}/>  
                </div>
              )}/>
            </div>
          ))}  
        </div>
      )}/>
    )
  case 6:
    return (
      <Field />
    )
  case 7:
    return (
      <Field />
      )  
    }
  }
  render() { 
return (
  <Field control={this.registrationForm}
  render={({ get, value, pristine, invalid }) => (
    <form onSubmit={this.handleSubmit}>
      <Field control={get('formName')}
        render={({ handler, pending, touched, hasError }) => (
          <Input {...handler()} placeholder='Form name'/>
        )} />
      <Field control={get('items')} render={({ controls }) => (
        <div>
          {controls.map((productControl, index) => (
            <div key={index}>
              <Field control={productControl} render={({ get }) => (
                <div>
                  <Field control={get('label')} render={({ handler }) => (
                    <Input {...handler()}/>
                  )}/>  
                  <Field control={get('type')}
                  render={({ handler, value }) => {
                    console.log(handler, value)
                    return (
                      <div>
                        <RadioGroup {...handler('radio')} value={value}>
                          <RadioButton value={1}>Short Answer</RadioButton>
                          <RadioButton value={2}>CheckBox</RadioButton>
                          <RadioButton value={3}>Multiple Options</RadioButton>
                          <RadioButton value={4}>Long Answer</RadioButton>
                          <RadioButton value={5}>Switch</RadioButton>
                          <RadioButton value={6}>Date</RadioButton>
                          <RadioButton value={7}>Numbers</RadioButton>
                        </RadioGroup>
                        {this.renderExtraControls(productControl, value, get)}
                      </div>
                    )
                  }}/>  
                </div>
              )}/>
            </div>
          ))}  
        </div>
      )}/>
      <ButtonGroup>
        <Button appearance='primary' onClick={this.handleSubmit}>Submit</Button>
        <Button appearance='primary' onClick={this.addItem}>Add Item</Button>  
      </ButtonGroup>
    </form>
  )}  
>
</Field>
    )
  }
}`

cannot figure out how to put the radio boxes

bietkul commented 6 years ago

You're using Field here which is deprecated in the latest version of RRF. If you want to add controls dynamically then you can check the new React Components ( FieldGroup, FieldControl & FieldArray ) in latest version (1.0.13) of RRF. Let me know if it solves your issue or not.

michaelspeed commented 6 years ago

i was going with this example - https://codesandbox.io/s/nw9wxw2nvl

michaelspeed commented 6 years ago

can you reproduce the above example with the new API?

bietkul commented 6 years ago

Yes, I'll update all the examples with the new api & when done I'll let you know.

michaelspeed commented 6 years ago

thanks

jfbloom22 commented 6 years ago

@michaelspeed did you ever get this working? I am trying to do something similar, but with select options. And I am using the FormGenerator.

I put together this: https://codesandbox.io/s/kmoj4j2823 But as you see on line 92 in index.js, I don't know how to pass the updated array of options to the select.

My goal is to either update the select with the new options, or wait to add the select until the options have been received.