-
-
Save markerikson/bd9f03e0808558c5951e02f1aa98c563 to your computer and use it in GitHub Desktop.
class ParentComponent extends Component { | |
constructor() { | |
super(); | |
this.state = { | |
data : [ | |
{id : 1, date : "2014-04-18", total : 121.0, status : "Shipped", name : "A", points: 5, percent : 50}, | |
{id : 2, date : "2014-04-21", total : 121.0, status : "Not Shipped", name : "B", points: 10, percent: 60}, | |
{id : 3, date : "2014-08-09", total : 121.0, status : "Not Shipped", name : "C", points: 15, percent: 70}, | |
{id : 4, date : "2014-04-24", total : 121.0, status : "Shipped", name : "D", points: 20, percent : 80}, | |
{id : 5, date : "2014-04-26", total : 121.0, status : "Shipped", name : "E", points: 25, percent : 90}, | |
], | |
expandedRows : [] | |
}; | |
} | |
handleRowClick(rowId) { | |
const currentExpandedRows = this.state.expandedRows; | |
const isRowCurrentlyExpanded = currentExpandedRows.includes(rowId); | |
const newExpandedRows = isRowCurrentlyExpanded ? | |
currentExpandedRows.filter(id => id !== rowId) : | |
currentExpandedRows.concat(rowId); | |
this.setState({expandedRows : newExpandedRows}); | |
} | |
renderItem(item) { | |
const clickCallback = () => this.handleRowClick(item.id); | |
const itemRows = [ | |
<tr onClick={clickCallback} key={"row-data-" + item.id}> | |
<td>{item.date}</td> | |
<td>{item.total}</td> | |
<td>{item.status}</td> | |
</tr> | |
]; | |
if(this.state.expandedRows.includes(item.id)) { | |
itemRows.push( | |
<tr key={"row-expanded-" + item.id}> | |
<td>{item.name}</td> | |
<td>{item.points}</td> | |
<td>{item.percent}</td> | |
</tr> | |
); | |
} | |
return itemRows; | |
} | |
render() { | |
let allItemRows = []; | |
this.state.data.forEach(item => { | |
const perItemRows = this.renderItem(item); | |
allItemRows = allItemRows.concat(perItemRows); | |
}); | |
return ( | |
<table>{allItemRows}</table> | |
); | |
} | |
} |
Seriously... this is awesome! This was trivial to implement in my already running app. Love it!
Thanks for the script, what if I would like to expand clicked row but close other? Mind to teach me how? Thanks in advance
tanks
realy goood
awesome !! really helpful !!
Thanks!!!
Really helpful!
@greysaga, you can show only one expanded row doing this way:
constructor() {
super();
this.state = {
data :
{id : 1, date : "2014-04-18", total : 121.0, status : "Shipped", name : "A", points: 5, percent : 50},
{id : 2, date : "2014-04-21", total : 121.0, status : "Not Shipped", name : "B", points: 10, percent: 60},
],
expandedRow: null,
};
}
handleRowClick(rowId) {
const currentExpandedRow = this.state.expandedRow;
this.setState({ expandedRow: (rowId === currentExpandedRow) ? null : rowId })
}
renderItem(item) {
const clickCallback = () => this.handleRowClick(item.id);
const itemRows = [
<tr key={"row-data-" + item.id}>
<td onClick={clickCallback} key={"row-data-" + item.id}>{item.id}</td>
<td>{item.date}</td>
<td>{item.total}</td>
<td>{item.status}</td>
<td>{item.name}</td>
<td>{item.points}</td>
<td>{item.percent}</td>
</tr>
];
if (this.state.expandedRow === item.id) {
itemRows.push(
<tr>
<td colspan={Object.keys(this.state.data[0]).length}>
<div> {item.status} </div>
</td>
</tr>
);
}
return itemRows;
}
Sandbox link to play around (Bonus: semantic styling)
awesome,thank you
This is great! But I'm interested in how can you add a new row below the extended row on, let's say button click?
@ivanmarkovic2464: "just" a question of how you want to define what that should look like in your state, and having render logic that matches that. It could be as simple as inserting an item into the array after the index of the expanded row.
@ivanmarkovic2464: "just" a question of how you want to define what that should look like in your state, and having render logic that matches that. It could be as simple as inserting an item into the array after the index of the expanded row.
Well if possible I would like to have state defined just like you showed in here. But I'm struggling because I want to add multiple sub rows instead of just one and manipulate with them (by this I mean delete just the one sub row I want to). Something like this:
1 parent
subrow
subrow
subrow
...
2 parent
subrow
subrow
...
Really good! Thanks
I used it in TypeScript today, so here is the typescript code:
import React, { useState } from 'react';
interface TableDataInterface {
id: number,
date: string,
total: number,
status: string,
name: string,
points: number,
percent: number
}
const ParentComponent = (): JSX.Element => {
const data: TableDataInterface[] = [
{ id: 1, date: "2014-04-18", total: 121.0, status: "Shipped", name: "A", points: 5, percent: 50 },
{ id: 2, date: "2014-04-21", total: 121.0, status: "Not Shipped", name: "B", points: 10, percent: 60 },
{ id: 3, date: "2014-08-09", total: 121.0, status: "Not Shipped", name: "C", points: 15, percent: 70 },
{ id: 4, date: "2014-04-24", total: 121.0, status: "Shipped", name: "D", points: 20, percent: 80 },
{ id: 5, date: "2014-04-26", total: 121.0, status: "Shipped", name: "E", points: 25, percent: 90 },
]
const [expandedRows, setExpandedRows] = useState<number[]>([]);
const handleRowClick = (rowId: number) => {
const currentExpandedRows = expandedRows;
const isRowCurrentlyExpanded = currentExpandedRows.includes(rowId);
const newExpandedRows = isRowCurrentlyExpanded ?
currentExpandedRows.filter(id => id !== rowId) :
currentExpandedRows.concat(rowId);
setExpandedRows(newExpandedRows);
}
const renderItem = (item: TableDataInterface): JSX.Element[] => {
const clickCallback = () => handleRowClick(item.id);
const itemRows = [
<tr onClick={clickCallback} key={"row-data-" + item.id}>
<td>{item.date}</td>
<td>{item.total}</td>
<td>{item.status}</td>
</tr>
];
if (expandedRows.includes(item.id)) {
itemRows.push(
<tr key={"row-expanded-" + item.id}>
<td>{item.name}</td>
<td>{item.points}</td>
<td>{item.percent}</td>
</tr>
);
}
return itemRows;
}
let allItemRows: JSX.Element[] = [];
data.forEach(item => {
const perItemRows = renderItem(item);
allItemRows = allItemRows.concat(perItemRows);
});
return (
<table>{allItemRows}</table>
);
}
Thanks bro, you saved me
Does anyone know how to modify this so there are some rows that are not expandable? In this example, all rows are expandable. I'd like to only have certain rows expand. Thanks for any insight!
This solution works for single expand only, How it's possible to expand it to multiple level?
Thanks @auryn31
Thank you so much!