I am working on developing a UI in react js where i am generating a dynamic table from the data i get from the API, on the left side i have check boxes and each check box have a particular input of type text, which are dynamically generated as stated. What i want to archive is as soon as user check box is checked i need to generate an object which has following 4 fileds isChecked (to check wheather the check box is checked or not), module_id (if checked than i need to get the module id), isUpdated (this is for tracking any changes made on the specific input text, if not it should be zero ), discount_price (if isUpdated is true than i need this value). these things i am trying to achieve by setState in react js.
The necessity for the above defined object is for handling the data in back-end. Based on the conditions i ll be writing the queries, i hope i am clear with my statement problem.
I have initialized the object state in constructor of the class component, i have binded the handleChange method in with both inputs of checkbox and text, but i am getting error like TypeError: Cannot read property 'checked' of undefined, i want to know the best approach of handling such dynamic forms.
constructor(){
super();
this.state = {moduleData: [], modules : [] }
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
this is my handleChange function
handleChange(event) {
const key = event.target.dataset.moduleindex;
const modId = event.target.dataset.moduleid;
const inputKeyType = event.target.type;
var is_updated = 1;
if(inputKeyType == 'checkbox'){
var inputChecked = !this.state.modules[key].checked;
if (!this.state.modules[key].checked == false) {
is_updated = 0;
}
} else {
var inputChecked = true;
is_updated = 1;
}
this.setState({
modules: {
...this.state.modules,
[key]: {
["isChecked"]: inputChecked,
["module_id"]: modId,
["isUpdated"]: is_updated,
["discount_price"]: event.target.value,
}
}
});
}
and this the table which is generated dynamically
const moduleRow = modules.map((module, index) => (
<tr key={module.id.toString()}>
<th scope="row" width="" className='text-center' >
<Input type="checkbox"
className="checkbox"
name="module_id"
data-moduleindex = {index}
data-moduleid = {module.id}
checked={
this.state.modules[index]
? this.state.modules[index].checked
: ""
}
onChange={this.handleChange}
/>
</th>
<td>
{module.module_name}
</td>
<td>
{module.module_short_code}
</td>
<td>
{module.limits}
</td>
<td>
{ module.subscriptionInterval === 'monthly' ? module.monthly_price : module.annual_price }
</td>
<td>
<Input
type="text"
name="discount_price"
data-moduleindex = {index}
id = {module.id}
onChange={this.handleChange}
value={
this.state.modules[index]
? this.state.modules[index].discount_price
: ""
}
/>
</td>
<td>
{this.getStatus(module.status)}
</td>
</tr>
));
finally i want to get the array of objects like this
[
0:{"isChecked":true, "module_id":2, "isUpdated" : 1, "discount_price": 5 },
1:{"isChecked":false, "module_id":3, "isUpdated" : 1, "discount_price": 5 },
2: {"isChecked":true, "module_id":8, "isUpdated" : 0, "discount_price": "" }
]
can this be achieved or am i missing some thing? pls help