I have to setup one form which have nested values in single form Basically I need to send data in below format to API
Payload: {"name": "The org name", "detail": "The org detail", "attributes": {"address": {"lines":[], "city":"", "state": "", "country": "India", "zip": ""}, "contacts":[{"name": "abc", "phone": "PH"}, {"name": "x", "phone": "PH"}] }}
I used react-bootstrap for handling forms.
below are the currrent code of my form
constructor(props) {
super(props);
this.state = this.getInitialState();
}
getInitialState() {
const initialState = {
organizationForm: {
name: '',
detail: '',
type: 'org',
attributes: {
contacts: [{
name: '',
phone: ''
}],
address: {
lines: [],
city: '',
state: '',
country: '',
zip: ''
}
}
},
errors: {}
};
return initialState;
}
handleChange(e) {
const organizationForm = this.state.organizationForm;
var key = e.target.name;
var value = e.target.value;
organizationForm[key] = value;
this.setState({
organizationForm
});
}
Below are the code of form
<Col className="create-content-wrap" sm={12}>
<form className="">
<FormGroup className="custom-form-group required row">
<ControlLabel className="custom-form-control-label col-sm-3">
Name
</ControlLabel>
<FormControl
className="custom-form-control col-sm-9"
type="text"
name="name"
value={organizationForm.name}
onChange={this.handleChange.bind(this)}
/>
</FormGroup>
<FormGroup className="custom-form-group required row">
<ControlLabel className="custom-form-control-label col-sm-3">
Detail
</ControlLabel>
<FormControl
className="custom-form-control col-sm-9"
type="text"
name="detail"
componentClass="textarea"
value={organizationForm.detail}
onChange={this.handleChange.bind(this)}
/>
</FormGroup>
<FormGroup className="custom-form-group row">
<ControlLabel className="custom-form-control-label col-sm-3">
Address
</ControlLabel>
<FormControl
className="custom-form-control col-sm-9"
type="text"
name="lines"
componentClass="textarea"
value={organizationForm.lines}
onChange={this.handleAddressChange.bind(this)}
/>
</FormGroup>
<FormGroup className="custom-form-group row">
<ControlLabel className="custom-form-control-label col-sm-3">
City
</ControlLabel>
<FormControl
className="custom-form-control col-sm-9"
type="text"
name="city"
value={organizationForm.attributes.address.city}
onChange={this.handleAddressChange.bind(this)}
/>
</FormGroup>
<FormGroup className="custom-form-group row">
<ControlLabel className="custom-form-control-label col-sm-3">
State
</ControlLabel>
<FormControl
className="custom-form-control col-sm-9"
type="text"
name="state"
value={organizationForm.attributes.address.state}
onChange={this.handleAddressChange.bind(this)}
/>
</FormGroup>
<FormGroup className="custom-form-group row">
<ControlLabel className="custom-form-control-label col-sm-3">
Country
</ControlLabel>
<FormControl
className="custom-form-control col-sm-9"
type="text"
name="country"
value={organizationForm.attributes.address.country}
onChange={this.handleAddressChange.bind(this)}
/>
</FormGroup>
<FormGroup className="custom-form-group row">
<ControlLabel className="custom-form-control-label col-sm-3">
Zipcode
</ControlLabel>
<FormControl
className="custom-form-control col-sm-9"
type="number"
name="zip"
value={organizationForm.attributes.address.zip}
onChange={this.handleAddressChange.bind(this)}
/>
</FormGroup>
<FormGroup className="custom-form-group row">
<ControlLabel className="custom-form-control-label col-sm-3">
Contacts
</ControlLabel>
<FormControl
className="custom-form-control col-sm-9"
type="number"
name="contacts"
value={organizationForm.attributes.contacts}
onChange={this.handleChange.bind(this)}
/>
</FormGroup>
</form>
</Col>
I am noobie in react js world. How can i bind nested fields of address and contacts ?
You can add couple of methods to handle for address and attributes like below Way - 1
<FormControl
className="custom-form-control col-sm-9"
type="text"
name="city"
value={organizationForm.attributes.address.city}
onChange={this.handleAddressChange(this)}
/>
handleAddressChange = (e) => {
const organizationForm = this.state.organizationForm;
let address = organizationForm.attributes.address;
var key = e.target.name;
var value = e.target.value;
address[key] = value;
organizationForm.attributes.address = address;
this.setState({
organizationForm
});
}
This way your form is loosely coupled also . So if any change happens in the child object will not affect the other one. Similarly you can add for all the nested objects like address, attribute etc.
Way - 2
You can do the same by below but you need to handle which object your modifing with in the same method .
<FormControl
className="custom-form-control col-sm-9"
type="text"
name="city"
value={organizationForm.attributes.address.city}
onChange={event => { this.handleChange(event, this.state.organizationForm.attributes.address ,'address'); }}
/>
<FormControl
className="custom-form-control col-sm-9"
type="text"
name="city"
value={organizationForm.attributes.address.city}
onChange={event => { this.handleChange(event, this.state.organizationForm.attributes.contacts ,'contacts'); }}
/>
<FormControl
className="custom-form-control col-sm-9"
type="text"
name="city"
value=onChange={event => { this.handleChange(event, this.state.organizationForm ,'organizationForm'); }}
/>
handleChange = (e , object , type) => {
const organizationForm = this.state.organizationForm;
var key = e.target.name;
var value = e.target.value;
object[key] = value;
if(type === 'address'){
organizationForm.attributes.address = object;
} else if (type === 'contacts'){
organizationForm.attributes.contacts = object;
}
this.setState({
organizationForm : organizationForm
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With