my attempt fiddle here ..........
-
Hello @vicky, what's your issue here? You need to tell us how we can help you.Arnold Gandarillas– Arnold Gandarillas2018-03-08 11:03:29 +00:00Commented Mar 8, 2018 at 11:03
-
my issue screenshot here @Arnold Gandarillas i.sstatic.net/KXFot.pngvicky patel– vicky patel2018-03-08 11:30:58 +00:00Commented Mar 8, 2018 at 11:30
-
I see, I can understand what's your issue. I'll post an answer.Arnold Gandarillas– Arnold Gandarillas2018-03-08 13:37:44 +00:00Commented Mar 8, 2018 at 13:37
-
By the way for sure it's a good idea to share code in places like jsfiddle but you need to post code here and explain what is not working and how we can help you.Arnold Gandarillas– Arnold Gandarillas2018-03-08 14:06:03 +00:00Commented Mar 8, 2018 at 14:06
4 Answers
You can achieve that by playing with react state. In your case you are using nested objects so you need to be carefully when you update them.
It's not a good idea to mutate your state because it can cause easily bugs or an unexpected behavior.
Look closely how the handling functions are working.
Here you have a live demo.
class App extends React.Component {
state = {
rows: []
};
handleChange = idx => e => {
const { name, value } = e.target;
const rows = [...this.state.rows];
rows[idx] = {
[name]: value
};
this.setState({
rows
});
};
handleAddRow = () => {
const item = {
name: "",
mobile: ""
};
this.setState({
rows: [...this.state.rows, item]
});
};
handleRemoveRow = () => {
this.setState({
rows: this.state.rows.slice(0, -1)
});
};
render() {
return (
<div>
<div className="container">
<div className="row clearfix">
<div className="col-md-12 column">
<table
className="table table-bordered table-hover"
id="tab_logic"
>
<thead>
<tr>
<th className="text-center"> # </th>
<th className="text-center"> Name </th>
<th className="text-center"> Mobile </th>
</tr>
</thead>
<tbody>
{this.state.rows.map((item, idx) => (
<tr id="addr0" key={idx}>
<td>{idx}</td>
<td>
<input
type="text"
name="name"
value={this.state.rows[idx].name}
onChange={this.handleChange(idx)}
className="form-control"
/>
</td>
<td>
<input
type="text"
name="mobile"
value={this.state.rows[idx].mobile}
onChange={this.handleChange(idx)}
className="form-control"
/>
</td>
</tr>
))}
</tbody>
</table>
<button
onClick={this.handleAddRow}
className="btn btn-default pull-left"
>
Add Row
</button>
<button
onClick={this.handleRemoveRow}
className="pull-right btn btn-default"
>
Delete Row
</button>
</div>
</div>
</div>
</div>
);
}
}
render(<App />, document.getElementById("root"));
PD: If I can give you a recommendation I'd say that you need to study a little bit more about react - javascript to move forward, it would help to achieve things like this faster, right now you probably need to focus on understand the basics.
5 Comments
splice method it allows you to remove a single item from an array. I've updated my example supporting that idea. Regards.Incase someone might be looking for a React hooks version, this is a sample implementation of Arnold's answer:
import React, { useState } from "react";
const App = () => {
const [rows, setRows] = useState([{}]);
const collumnsArray = ["name", "id", "mobile", "date", "amount"]; // pass collumns here dynamically
const handleAddRow = () => {
const item = {};
setRows([...rows, item]);
};
const postResults = () => {
console.log(rows); // there you go, do as you please
};
const handleRemoveSpecificRow = (idx) => {
const tempRows = [...rows]; // to avoid direct state mutation
tempRows.splice(idx, 1);
setRows(tempRows);
};
const updateState = (e) => {
let prope = e.target.attributes.collumn.value; // the custom collumn attribute
let index = e.target.attributes.index.value; // index of state array -rows
let fieldValue = e.target.value; // value
const tempRows = [...rows]; // avoid direct state mutation
const tempObj = rows[index]; // copy state object at index to a temporary object
tempObj[prope] = fieldValue; // modify temporary object
// return object to rows` clone
tempRows[index] = tempObj;
setRows(tempRows); // update state
};
return (
<div>
<div className="container">
<div className="row clearfix">
<div className="col-md-12 column">
<table className="table table-bordered table-hover" id="tab_logic">
<thead>
<tr>
<th className="text-center"> # </th>
{collumnsArray.map((collumn, index) => (
<th className="text-center" key={index}>
{collumn}
</th>
))}
<th />
</tr>
</thead>
<tbody>
{rows.map((item, idx) => (
<tr key={idx}>
<td>{idx + 1}</td>
{collumnsArray.map((collumn, index) => (
<td key={index}>
<input
type="text"
collumn={collumn}
value={rows[idx][collumn]}
index={idx}
className="form-control"
onChange={(e) => updateState(e)}
/>
</td>
))}
<td>
<button
className="btn btn-outline-danger btn-sm"
onClick={() => handleRemoveSpecificRow(idx)}
>
Remove
</button>
</td>
</tr>
))}
</tbody>
</table>
<button onClick={handleAddRow} className="btn btn-primary">
Add Row
</button>
<button
onClick={postResults}
className="btn btn-success float-right"
>
Save Results
</button>
</div>
</div>
</div>
</div>
);
};
export default App;
2 Comments
If you want to add/remove rows dynamically you can play with the state, or if you where using Redux you can play with the store.
Here's a simple example using a components local state to add and remove rows:
https://codesandbox.io/s/k302jwn44r
EDIT: fixed mutating state
import React from "react";
import { render } from "react-dom";
const styles = {
fontFamily: "sans-serif",
textAlign: "left"
};
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
rows: []
};
}
handleAddRow = () => {
this.setState((prevState, props) => {
const row = {content: "hello this is a new row!" };
return { rows: [...prevState.rows, row] };
});
};
handleRemoveRow = () => {
this.setState((prevState, props) => {
return { rows: prevState.rows.slice(1) };
});
};
render() {
console.log(this.state);
return (
<div style={styles}>
<table>
<tbody>
{this.state.rows.map(row => (
<tr>
<td>{row.content}</td>
</tr>
))}
<tr>
<td className="" onClick={this.handleAddRow}>
(+)
</td>
{Boolean(this.state.rows.length) && (
<td onClick={this.handleRemoveRow}>(-)</td>
)}
</tr>
</tbody>
</table>
</div>
);
}
}
render(<App />, document.getElementById("root"));