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?

1 Answer 1

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>

Sign up to request clarification or add additional context in comments.

7 Comments

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.
Can you help with the previous example in ES5 syntax like the syntax I followed in stackoverflow.com/questions/42387559/…
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! :)
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 :(
After I rebuild, the app is loading but the above logic is not working :-(
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.