Reputation: 1865
I have an HTML table which I would like to create a function that takes a row with a specific id, and moves it to the top of the table. I'm not even sure where to begin, but here is the code I am using:
function App() {
function changeRow(id){
//Move row with "id" to top of table
}
return (
<div className="App">
<table>
<tbody>
<tr id='row1'>
<td><b>Value 1</b></td>
<td>Description 1</td>
<td><button onClick={()=>changeRow('row1')}>Change Row</button></td>
</tr>
<tr id='row2'>
<td><b>Value 2</b></td>
<td>Description 2</td>
<td><button onClick={()=>changeRow('row2')}>Change Row</button></td>
</tr>
<tr id='row3'>
<td><b>Value 3</b></td>
<td>Description 3</td>
<td><button onClick={()=>changeRow('row3')}>Change Row</button></td>
</tr>
<tr id='row4'>
<td><b>Value 4</b></td>
<td>Description 4</td>
<td><button onClick={()=>changeRow('row4')}>Change Row</button></td>
</tr>
</tbody>
</table>
</div>
);
}
And here is the code sandbox:
https://codesandbox.io/s/thirsty-leftpad-vvrmz
Thanks!!
Upvotes: 0
Views: 1200
Reputation: 41893
Avoid hardcoding data - store it in e.g. array of objects, it will be much easier to tweak on it.
Then - apply state with activeId
field. Then sort your array and render it.
https://codesandbox.io/s/polished-resonance-oo063
class App extends React.Component {
state = {
activeRowId: null
};
changeRow = id => {
this.setState({ activeRowId: id });
};
render() {
const arr = [
{ id: "row1", value: "value1" },
{ id: "row2", value: "value2" },
{ id: "row3", value: "value3" },
{ id: "row4", value: "value4" }
];
const elements = arr
.sort(
(a, b) =>
+(this.state.activeRowId === b.id) -
+(this.state.activeRowId === a.id)
)
.map(elem => (
<tr id="row1">
<td>
<b>{elem.value}</b>
</td>
<td>{elem.value}</td>
<td>
<button onClick={() => this.changeRow(elem.id)}>Change Row</button>
</td>
</tr>
));
return (
<div className="App">
<table>
<tbody>{elements}</tbody>
</table>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root' />
Upvotes: 3
Reputation: 4632
Use different kind of react functions and abilities like so:
Comments in the code:
import React, { useState } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
// create a row component so we dont repeat the same thing over and over again
// that's the reason why we are using react btw
function Row(row) {
const {changeRow, val, desc, id} = row;
return <tr id={id}>
<td>
<b>{val}</b>
</td>
<td>{desc}</td>
/** if changeRow is not define, don't show the button (this is for the top row) **/
{ changeRow && <td>
<button onClick={() => changeRow(row)}>Change Row</button>
</td>}
</tr>
}
function App() {
// store a top row as state
const [topRow, setTopRow] = useState(null)
// store rows as state so you can modify (add/remove) them
const [rows, setRows] = useState([{
id: 'row1',
val: 'Value 1',
desc: 'Description: 1',
}, {
id: 'row2',
val: 'Value 2',
desc: 'Description: 2',
}])
// function to change row
function changeRow(row) {
// set the data for top row
setTopRow(row)
// filter it so we remove the selected row on the rows list
const rows = rows.filter(rowItem => rowItem.id === row.id)
setRows(rows)
}
function getTopRow() {
// if toprow is null (initial value) return nothing
if (!topRow) {
return null;
}
// return it as a row
return <Row val={topRow.val} desc={topRow.desc} id={topRow.id} />
}
return (
<div className="App">
{getTopRow() // we call the top row here}
<table>
<tbody>
{rows.map((row) => <Row {...row} changeRow={changeRow}/>) // map them to avoid that repetitive html code }
</tbody>
</table>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Upvotes: 2