0

Disclaimer: I'm new to ReactJS, Javascript and more generally to front-end development.

Hi everyone,

I decided to build a generic component to handle all the forms I'll be using in my project based on a given template.

Generation is quite simple: I loop on my template in Json and create the components I need.

But now I'm struggling to find a solution to retrieve the input values of those components without passing by some code generation writing the JS code.

p.s.: I'm using Material UI components.

Here is an example of template :

{ label: "General information",
                        elements: [ { label: "Firstname",
                                      element: "textfield",
                                      element_info: []
                                    },
                                    { label: "Lastname",
                                      element: "textfield",
                                      element_info: []
                                    },
                                    { label: "Email",
                                      element: "textfield",
                                      element_info: []
                                    },
                                    { label: "Password",
                                      element: "textfield",
                                      element_info: []
                                    },
                                    { label: "Phone number",
                                      element: "textfield",
                                      element_info: []
                                    }
                                  ]
                      },

And here is my code so far :

render: function() {
    var formPattern = this.props.form;
    var form = [];

    for (var paper in formPattern) {
      var elements = formPattern[paper].elements;
      var paper = [];

      for (var element in elements) {
        var label = elements[element].label;

        if (elements[element].element == "selectfield") {
          var element_info = elements[element].element_info;
          var items = [];

          for (var i = 0; i < element_info.length; i++) {
            items.push(<MenuItem value={i+1} primaryText={element_info[i]} />);
          }

          paper.push( <SelectField>
                        {items}
                      </SelectField>);

        } else if (elements[element].element == "toggle") {
          paper.push(<Toggle label={label} />);

        } else if (elements[element].element == "checkbox") {
          paper.push( <Checkbox
                        label={label}
                        style={checkboxStyle}
                    />);

        } else {
          paper.push(<TextField hintText={label} />);
        }
      }

      form.push(<Paper style={paperStyle}>
                  {paper}
                </Paper>);
    }

    return (
      <div>
        {form}
        <FlatButton
          label="Create"
          onTouchTap={this.props.onNewClick}
        />
      </div>
    );

So if we just concentrate on the TextField component I would need to add a "onChange" property-like to get the input knowing that I don't know who's this field because I'm on a generic component.

Obvioulsy I need to be able to access to the result data from the parent component where I'll be playing with it.

I was thinking of concatenating all the values in a single string with a format like "fieldName:value," or even directly in a JSON format.

But: How do I retrieve those values?????? That's the question!

Here I am. I've been searching a solution for hours and you guys are my last chance /o/

Thank you in advance for your help!

Samir D.
  • 1
  • 2
  • Highly recommend you look at some existing solutions. [`tcomb-form`](https://github.com/gcanti/tcomb-form) is pretty cool. – ctrlplusb May 30 '16 at 21:35

2 Answers2

1

You probably want to use a handleChange(name, event) function and then bind each instance with a name property. You'll also need to use an immutability helper (either React's or any other one) to modify the state given a dynamic element;

handleChange: function(name, event){
    var newState = {};
    newState[name] = event.target.value;
    this.setState(React.addons.update(this.state, {$merge: newState}));
}

...

    } else {
      paper.push(<TextField hintText={label} onChange={this.handleChange.bind(this, elements[element].label)}/>);
    }

And then you can access those values from the state as this.state.{{label name}}

Jake Haller-Roby
  • 6,335
  • 1
  • 18
  • 31
0

I have built Material UI based dynamic form component for React using JSON-Schema

The forms can be rendered from server side and also comprises of inbuilt validation rules & layout construction using bootstrap grid

Github Repo: https://github.com/ajainvivek/react-aztec

Build dynamic forms using interactive editor: http://ajainvivek.github.io/react-aztec/#/playground

Hope this library helps someone

Cheers

Ajain Vivek
  • 1,111
  • 1
  • 12
  • 20