0

I have the below json data and the react code to populate the data dynamically

var DATA = [{"processList":
[{"processId":"1","processName":"Process1","htmlControlType":"radio","cssClassName":"radio"},
{"processId":"2","processName":"Process2","htmlControlType":"radio","cssClassName":"radio"}],
"processIndexList":
[{"processId":"1","indexId":"1","indexDesc":"First Name","htmlControlType":"textbox","cssClassName":"form-control"},{"indexId":"2","indexDesc":"Last Name","htmlControlType":"textbox","cssClassName":"form-control"}]}];

renderProcessList: function () {

    const data = DATA;
    return data[0].processList.map(group => {
        return <div className={group.cssClassName}>
                    <label><input type={group.htmlControlType} name="processOptions"/>{group.processName}</label>
                </div>
    });

},

renderProcessData: function () {

    const data = DATA;
    return data[0].processIndexList.map(group => {
        return <div>
                    <label>{group.indexDesc}</label>
                  <input type={group.htmlControlType} className={group.cssClassName} placeholder=""/>
                  <br/>
        </div>
    });

},

As of now the form is getting displayed based on the json data, but i want to display the form based on the user selection in the process list ex: If the user select the Process1 radio the the First Name text box needs to be displayed below the radio and the user selects the process2 then Last Name text box needs to be displyed.

Can anyone tell me how to do it in reactjs?

knbibin
  • 1,099
  • 7
  • 18
  • 36

1 Answers1

0

To achieve the task, you have to implement the next three steps:

  1. Handle radio input click.
  2. Store the selected process ID in the state.
  3. Display process list items, based on the selected ID (a.k.a. filtering).

Please note that you missed to add processId property in processIndexList[1] object.

Also please consider that in the example below I'm using basic filtering in renderProcessData().


I implemented the example in ES5, ES6 because of question's author request. Keep in mind that in the both examples I'm using JSX, so you need a compiler tool (Babel for example). Once you use a compiler, then you can use latest JS features. Please revise your choise of using ES5.

ES6

var DATA = [{
    "processList": [{
            "processId": "1",
            "processName": "Process1",
            "htmlControlType": "radio",
            "cssClassName": "radio"
        },
        {
            "processId": "2",
            "processName": "Process2",
            "htmlControlType": "radio",
            "cssClassName": "radio"
        }
    ],
    "processIndexList": [{
        "processId": "1",
        "indexId": "1",
        "indexDesc": "First Name",
        "htmlControlType": "textbox",
        "cssClassName": "form-control"
    }, {
        "processId": "2",
        "indexId": "2",
        "indexDesc": "Last Name",
        "htmlControlType": "textbox",
        "cssClassName": "form-control"
    }]
}];



class App extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            selectedProcessID: null
        };
    }

    setProcessID(e) {
        this.setState({
            selectedProcessID: e.target.value
        });
    }

    renderProcessList() {
        const data = DATA;

        return data[0].processList.map( group => {
            return <div className={group.cssClassName}>
                <label><input
                    value={group.processId}
                    onClick={this.setProcessID.bind(this)}
                    type={group.htmlControlType}
                    name="processOptions"/>{group.processName}</label>
            </div>
        });

    }

    renderProcessData() {
        // Display process data, only if there is already
        // selected process ID
        if ( ! this.state.selectedProcessID) return;

        const data = DATA;

        return data[0].processIndexList.map( group => {
            // Display process list items for the selected process ID.
            // The filtering can be implemented performance better with a library (lodash for example).
            // Current implementation is enough for the SO demo. 
            if (group.processId !== this.state.selectedProcessID) return;

            return <div>
                <label>{group.indexDesc}</label>
                <input type={group.htmlControlType} className={group.cssClassName} placeholder=""/>
                <br/>
            </div>
        });

    }

    render() {
        return <div>
            {this.renderProcessList()}
            {this.renderProcessData()}
        </div>
    }
}

ReactDOM.render(<App />, document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>

ES5

var DATA = [{
    "processList": [{
            "processId": "1",
            "processName": "Process1",
            "htmlControlType": "radio",
            "cssClassName": "radio"
        },
        {
            "processId": "2",
            "processName": "Process2",
            "htmlControlType": "radio",
            "cssClassName": "radio"
        }
    ],
    "processIndexList": [{
        "processId": "1",
        "indexId": "1",
        "indexDesc": "First Name",
        "htmlControlType": "textbox",
        "cssClassName": "form-control"
    }, {
        "processId": "2",
        "indexId": "2",
        "indexDesc": "Last Name",
        "htmlControlType": "textbox",
        "cssClassName": "form-control"
    }]
}];



var App = React.createClass({

    getInitialState() {
        return {
            selectedProcessID: null
        }
    },

    setProcessID: function(e) {
        this.setState({
            selectedProcessID: e.target.value
        });
    },

    renderProcessList: function() {
        const data = DATA;

        return data[0].processList.map( group => {
            return <div className={group.cssClassName}>
                <label><input
                    value={group.processId}
                    onClick={this.setProcessID.bind(this)}
                    type={group.htmlControlType}
                    name="processOptions"/>{group.processName}</label>
            </div>
        });

    },

    renderProcessData: function() {
        // Display process data, only if there is already
        // selected process ID
        if ( ! this.state.selectedProcessID) return;

        const data = DATA;

        return data[0].processIndexList.map( group => {
            // Display process list items for the selected process ID.
            // The filtering can be implemented performance better with a library (lodash for example).
            // Current implementation is enough for the SO demo. 
            if (group.processId !== this.state.selectedProcessID) return;

            return <div>
                <label>{group.indexDesc}</label>
                <input type={group.htmlControlType} className={group.cssClassName} placeholder=""/>
                <br/>
            </div>
        });

    },

    render: function() {
        return <div>
            {this.renderProcessList()}
            {this.renderProcessData()}
        </div>
    }
});

ReactDOM.render(<App />, document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>
Jordan Enev
  • 16,904
  • 3
  • 42
  • 67
  • I'm using ES5 React.createClass method rather than React.Component so I've changed the constructor to getInitialState() function. While changing to ES5 syntax the app is not working and getting console error - Uncaught Error: _registerComponent(...): Target container is not a DOM element. – knbibin Mar 08 '17 at 07:13
  • Can you help with the previous example in ES5 syntax like the syntax I followed in http://stackoverflow.com/questions/42387559/how-to-create-a-dynamic-html-form-in-reactjs-using-json-data – knbibin Mar 08 '17 at 07:19
  • Alright, I've added the example. BTW there aren't big differences in the both examples, so with a little more effort you can do it by yourself. In that way you'll learn and understand it better and that's the constructive way of resolving problems. I hope you tried to resolve it, before asking. Good luck and keep coding/learning! :) – Jordan Enev Mar 08 '17 at 09:04
  • The same way only I updated my code to ES5 and getting the above console error, so I thought that was a mistake from my updated code, but here itself Im getting the same console error :( – knbibin Mar 08 '17 at 09:52
  • After I rebuild, the app is loading but the above logic is not working :-( – knbibin Mar 08 '17 at 10:03
  • Hey, you have both working examples in my answer. So make sure you follow their logic/implementation in your app. – Jordan Enev Mar 08 '17 at 10:11
  • Glad to hear it! :) – Jordan Enev Mar 08 '17 at 10:32