I have made a table using Material UI where I have two buttons in the first column of every row. I wish to edit/delete rows on clicking these but Im stuck on logic. Is it even possible with my implementation ? If not then what's the preferred way of doing so?
render() {
var deleteIcon =
(<IconButton onClick={console.log("delete")}>
<DeleteIcon color="secondary" />
</IconButton>
);
const editIcon = (
<IconButton onClick={console.log("edited")}>
<EditIcon color="primary" />
</IconButton>
);
return(
<TableBody>
{this.state.serviceData.map(n => {
return (
<TableRow key={n.id}>
<TableCell style={styles.editor} ponent="th" scope="row">
{deleteIcon}
{editIcon}
</TableCell>
<TableCell>{n.domain}</TableCell>
<TableCell>{n.service_name}</TableCell>
</TableCell>
</TableRow>
)};
And my result is :
I have made a table using Material UI where I have two buttons in the first column of every row. I wish to edit/delete rows on clicking these but Im stuck on logic. Is it even possible with my implementation ? If not then what's the preferred way of doing so?
render() {
var deleteIcon =
(<IconButton onClick={console.log("delete")}>
<DeleteIcon color="secondary" />
</IconButton>
);
const editIcon = (
<IconButton onClick={console.log("edited")}>
<EditIcon color="primary" />
</IconButton>
);
return(
<TableBody>
{this.state.serviceData.map(n => {
return (
<TableRow key={n.id}>
<TableCell style={styles.editor} ponent="th" scope="row">
{deleteIcon}
{editIcon}
</TableCell>
<TableCell>{n.domain}</TableCell>
<TableCell>{n.service_name}</TableCell>
</TableCell>
</TableRow>
)};
And my result is :
Share Improve this question asked Jul 20, 2018 at 5:37 YashankYashank 8132 gold badges11 silver badges24 bronze badges 4-
You should give
onPress
a function, but it seems like you are giving it simplynull
(console.log runs every time your ponent renders, and the result of that gets to theonPress
, which isnull
). So you should add a method to the class like:editItem
anddeleteItem
and pass that instead as the value foronPress
– rowinbot Commented Jul 20, 2018 at 5:41 - You mean going onPress={this.editItem.bind()} ? – Yashank Commented Jul 20, 2018 at 5:48
-
You shouldn't really do the bind on
render
, becausebind
creates another function with the values attached or bind, so it would create a function every time the ponent renders. Bindthis
to the class method onconstructor
likethis.editItem = this.editItem.bind(this)
(only bind on instance creation, one time only, like any other class method) or use syntax sugareditItem = () => {}
(arrow function) to automatically bind this to class method. – rowinbot Commented Jul 20, 2018 at 5:58 - Looks like onPress is not a valid handler.. However on binding the function on render and calling it with onClick works! Any idea how to pass in my row details now as well? Usually I would do bind(this,data) and use data but how to work here? – Yashank Commented Jul 20, 2018 at 6:18
3 Answers
Reset to default 7Building on @st4rl00rd's ment, I was able to tie the buttons using :
const editIcon = (
<IconButton onClick={this.editItem}>
<EditIcon color="primary" />
</IconButton>
);
and binding them in the constructor. I was able to get the selected row data by doing :
<TableBody>
{this.state.serviceData.map(n => {
return (
<TableRow key={n.id} onClick={this.getData.bind(this,n)}>
I have recreated your problem and solved the problem with my logic.
I passed the index
of each element as a parameter to the handler functions.
Eg:
const editIcon = index => (
<IconButton onClick={() => this.editComponent(index)}>
<EditIcon color="primary" />
</IconButton>
);
DELETION
For deletion, pass the index as params to the handler function and delete the element at specified index using splice
operator.
deleteComponent(index) {
const serviceData = this.state.serviceData.slice();
serviceData.splice(index, 1);
this.setState({ serviceData });
}
EDITING
I have used a state called index
to keep track of the index the user is currently editing. Initially the index
is -1
So whenever the user clicks edit button the editedIndex
is updated.
editComponent(index) {
this.setState({ editedIndex: index });
}
I created two TextField Component which is shown at the specified cell (the cell where editbutton is clicked)
const editDomain = (
<TextField
id="domain"
label="Domain"
className={classes.textField}
value={this.state.editedDomain}
margin="normal"
onChange={this.handleChange('editedDomain')}
/>
);
So Whenever the rendering ponent Index is equal to editedIndex the editing Compomemts are shown at corresponding Tablecell
<TableCell>
{serviceData.indexOf(n) === editedIndex
? editDomain
: n.domain}
</TableCell>
I suppose you want to do this
I have done same using React-Table here is the link for my project repo you can consider this as an example:
https://github./AdnanShah/ReactJS-KretaHub-/blob/Thank_You_Init/src/app/routes/dashboard/routes/Default/rows.js