Reputation: 471
I am new to react-16 and have done with React-16 save and delete operation.when it comes to edit/update operation, I found difficulty in approach.1)when I hit on the update button, get modal open but values not getting shown in each field.2)how do i update form values in setState function after saving to them. Thanks.
import React, { Component } from "react";
import {Form,FormGroup,FormControl,Col,Button,Modal,ButtonToolbar,Table} from "react-bootstrap";
class Dashboard extends Component {
constructor(props) {
super(props);
this.state = {
name: "",
description: "",
amount: "",
date: "",
show: false,
formdata: []
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleInputChange = this.handleInputChange.bind(this);
this.showModal = this.showModal.bind(this);
this.hideModal = this.hideModal.bind(this);
this.showEditModal = this.showEditModal.bind(this);
}
showModal() {
this.setState({ show: true });
}
showEditModal(event) {
this.setState({
show: true,
name: this.state.name.value,
description: this.state.description.value,
amount: this.state.amount.value,
date: this.state.date.value
});
}
hideModal() {
this.setState({
show: false,
name: "",
description: "",
amount: "",
date: ""
});
}
handleInputChange(event) {
this.setState({
[event.target.name]: event.target.value,
[event.target.description]: event.target.value,
[event.target.amount]: event.target.value,
[event.target.date]: event.target.value
});
}
handleSubmit(event) {
const formItem = {
name: this.state.name,
description: this.state.description,
amount: this.state.amount,
date: this.state.date
};
if (
this.state.name === "" ||
this.state.amount === "" ||
this.state.date === ""
) {
alert("Please fill mandatory filed");
} else {
this.setState(prevState => ({
formdata: prevState.formdata.concat(formItem)
}));
alert("form submited: ");
this.setState({
name: "",
description: "",
amount: "",
date: ""
});
}
event.preventDefault();
}
deleteExpense(i) {
alert("are you sure you want to Delete this item ?");
this.setState({
formdata: this.state.formdata.filter((item, index) => {
return index !== i;
})
});
}
render() {
return (
<div>
<p>Welcome</p>
<ButtonToolbar>
<Button bsStyle="primary" onClick={this.showModal}>
Add Expenses
</Button>
<Table striped bordered condensed hover>
<thead>
<tr>
<th>name</th>
<th>description</th>
<th>amount</th>
<th>date</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{this.state.formdata.map((item, i) => (
<tr key={i}>
<td>{item.name}</td>
<td>{item.description}</td>
<td>{item.amount}</td>
<td>{item.date}</td>
<td>
<Button bsStyle="warning" onClick={this.showEditModal}>
Update
</Button>
<Button
bsStyle="danger"
onClick={() => this.deleteExpense(i)}
>
Delete
</Button>
</td>
<td />
</tr>
))}
</tbody>
</Table>
<Modal
{...this.props}
show={this.state.show}
onHide={this.hideModal}
dialogClassName="custom-modal"
>
<Modal.Header closeButton>
<Modal.Title
id="contained-modal-title-lg "
className="text-center"
>
Add Expenses
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form horizontal onSubmit={this.handleSubmit}>
<FormGroup controlId="formHorizontalEmail">
<Col smOffset={4} sm={4}>
<FormControl
type="Text"
placeholder="name"
name="name"
value={this.state.name}
onChange={this.handleInputChange}
/>
</Col>
</FormGroup>
<FormGroup controlId="formHorizontalPassword">
<Col smOffset={4} sm={4}>
<FormControl
type="description"
placeholder="description"
name="description"
value={this.state.description}
onChange={this.handleInputChange}
/>
</Col>
</FormGroup>
<FormGroup controlId="formHorizontalPassword">
<Col smOffset={4} sm={4}>
<FormControl
type="amount"
placeholder="amount"
name="amount"
value={this.state.amount}
onChange={this.handleInputChange}
/>
</Col>
</FormGroup>
<FormGroup controlId="formHorizontalPassword">
<Col smOffset={4} sm={4}>
<FormControl
type="date"
placeholder="date"
name="date"
value={this.state.date}
onChange={this.handleInputChange}
/>
</Col>
</FormGroup>
<FormGroup>
<Col smOffset={5} sm={4}>
<Button type="submit" bsStyle="primary">
Add
</Button>
</Col>
</FormGroup>
</Form>
</Modal.Body>
</Modal>
</ButtonToolbar>
</div>
);
}
}
export default Dashboard;
Upvotes: 1
Views: 2319
Reputation: 1281
In your openEditModal()
method, you will want to set the state values to the values of the record you want to edit (the one you clicked in the table). In this case, you will need to look up the selected item, update the state, and then open the modal. Like so:
import React, { Component } from "react";
import {Form,FormGroup,FormControl,Col,Button,Modal,ButtonToolbar,Table} from "react-bootstrap";
class Dashboard extends Component {
constructor(props) {
super(props);
this.state = {
name: "",
description: "",
amount: "",
date: "",
show: false,
formdata: []
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleInputChange = this.handleInputChange.bind(this);
this.showModal = this.showModal.bind(this);
this.hideModal = this.hideModal.bind(this);
this.showEditModal = this.showEditModal.bind(this);
}
showModal() {
this.setState({ show: true });
}
showEditModal(event, i) {
const recordToEdit = this.state.formdata.filter((item, index) => {
return index === i;
})[0];
this.setState({
show: true,
name: recordToEdit.name,
description: recordToEdit.description,
amount: recordToEdit.amount,
date: recordToEdit.date
});
}
hideModal() {
this.setState({
show: false,
name: "",
description: "",
amount: "",
date: ""
});
}
handleInputChange(event) {
// update the input that changed
this.setState({
[event.target.name]: event.target.value
});
}
handleSubmit(event) {
const formItem = {
name: this.state.name,
description: this.state.description,
amount: this.state.amount,
date: this.state.date
};
if (
this.state.name === "" ||
this.state.amount === "" ||
this.state.date === ""
) {
alert("Please fill mandatory filed");
} else {
if (this.state.formdata.filter(item => item.name === formItem.name).length > 0) {
// update item
this.setState(prevState => ({
formdata: prevState.formdata.map(item => {
if (item.name === formItem.name)
return formItem;
else
return item;
})
}));
} else {
// add new item
this.setState(prevState => ({
formdata: prevState.formdata.concat(formItem)
}));
}
alert("form submited: ");
this.setState({
name: "",
description: "",
amount: "",
date: ""
});
}
event.preventDefault();
}
deleteExpense(i) {
alert("are you sure you want to Delete this item ?");
this.setState({
formdata: this.state.formdata.filter((item, index) => {
return index !== i;
})
});
}
render() {
return (
<div>
<p>Welcome</p>
<ButtonToolbar>
<Button bsStyle="primary" onClick={this.showModal}>
Add Expenses
</Button>
<Table striped bordered condensed hover>
<thead>
<tr>
<th>name</th>
<th>description</th>
<th>amount</th>
<th>date</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{this.state.formdata.map((item, i) => (
<tr key={i}>
<td>{item.name}</td>
<td>{item.description}</td>
<td>{item.amount}</td>
<td>{item.date}</td>
<td>
<Button bsStyle="warning" onClick={(e) => this.showEditModal(e, i)}>
Update
</Button>
<Button
bsStyle="danger"
onClick={() => this.deleteExpense(i)}
>
Delete
</Button>
</td>
<td />
</tr>
))}
</tbody>
</Table>
<Modal
{...this.props}
show={this.state.show}
onHide={this.hideModal}
dialogClassName="custom-modal"
>
<Modal.Header closeButton>
<Modal.Title
id="contained-modal-title-lg "
className="text-center"
>
Add Expenses
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form horizontal onSubmit={this.handleSubmit}>
<FormGroup controlId="formHorizontalEmail">
<Col smOffset={4} sm={4}>
<FormControl
type="Text"
placeholder="name"
name="name"
value={this.state.name}
onChange={this.handleInputChange}
/>
</Col>
</FormGroup>
<FormGroup controlId="formHorizontalPassword">
<Col smOffset={4} sm={4}>
<FormControl
type="description"
placeholder="description"
name="description"
value={this.state.description}
onChange={this.handleInputChange}
/>
</Col>
</FormGroup>
<FormGroup controlId="formHorizontalPassword">
<Col smOffset={4} sm={4}>
<FormControl
type="amount"
placeholder="amount"
name="amount"
value={this.state.amount}
onChange={this.handleInputChange}
/>
</Col>
</FormGroup>
<FormGroup controlId="formHorizontalPassword">
<Col smOffset={4} sm={4}>
<FormControl
type="date"
placeholder="date"
name="date"
value={this.state.date}
onChange={this.handleInputChange}
/>
</Col>
</FormGroup>
<FormGroup>
<Col smOffset={5} sm={4}>
<Button type="submit" bsStyle="primary">
Add
</Button>
</Col>
</FormGroup>
</Form>
</Modal.Body>
</Modal>
</ButtonToolbar>
</div>
);
}
}
export default Dashboard;
Notice that I'm passing the index to the showEditModal()
function so I can update the state with the selected record. Also, I'm updating the field in the handleInputChange()
method using the name="field_name"
property on each form input.
Side note: per the React docs:
We don’t recommend using indexes for keys if the order of items may change. This can negatively impact performance and may cause issues with component state.
Consider using a unique ID for each record rather than the index provided by the map function.
Upvotes: 1