Djaenike
Djaenike

Reputation: 1865

Reactjs insert specific row to top of table

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

Answers (2)

kind user
kind user

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

I am L
I am L

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

Related Questions