3

I am using react-bootstrap-table2 to make HTML tables, I am using a checkbox inside my table to delete the items.

SO as per This link, it is mentioned how to get the selected row and then do the next part, here what I am doing is when I click on any checkbox row gets selected, and if I again select any row that I am adding to the array into my state like below

onSelect: (row, isSelect, rowIndex, e) => {
        if (isSelect === true) {
            setrowData((rowData) => [...rowData, row]);
        } else {
        //  here i need to do something
        }
    },

My issue is when I unselect the row that value is not getting deleted from my array, and at the time of delete, I have all the data which I have selected once.

  • One more thing which is related to this is when I check any row I want to show delete button and when none of the rows is checked I want to hide the delete button, here select is giving me the boolean value for that, but it is working for each select once I am selecting multiple rows it shows up, but when I unselect any one of them the delete button hides

What I have done for that is something like below

setrowSelect((rowSelect) => [...rowSelect, isSelect]); // this one is inside onSelect callback given by the react-bootstrap-table2 library

           {rowSelect && (
                    <button className="btn Secondary_Button_with_Icon">
                        <i className="ri-upload-cloud-line ri-lg"></i>Register
                    </button>
                )}

My full working code

1
  • Did my solution help? Commented Sep 8, 2020 at 14:52

5 Answers 5

2

Use a filter method inside your else block to remove that unselected element from the array

 onSelect: (row, isSelect, rowIndex, e) => {
      if (isSelect === true) {
        setrowData((rowData) => [...rowData, row]);
      } else {
        setrowData((rowData) => rowData.filter((x,i)=>i!==rowIndex))
      }
      setrowSelect((rowSelect) => [...rowSelect, isSelect]);
    },
Sign up to request clarification or add additional context in comments.

1 Comment

hey that isSelect still the same, when I select rows button is showing up, but when I uncheck all the rows still button is there
1
+50

Note that, you don't need to maintain another state for controlling visibility of Delete button.

You can perfectly hide/show Delete based on rowData state.

Also the code you wrote for handling selected rows works perfectly well. Just get rid of rowSelect state and its handlers.

And update the rendering of your Delete button based on contents of your rowData as:

{
    rowData.length ? (
        <button className="btn btn-primary" onClick={Delete_device}>
          <i className="ri-upload-cloud-line ri-lg"></i>Delete
        </button>
      )
    : null
}

This is the forked sandbox from yours.

Comments

1

try to change onSelect function like this

  onSelect: (row, isSelect, rowIndex, e) => {
  if (isSelect === true) {
    setrowData((rowData) => [...rowData, row]);
    rowSelect.push(true);
    setrowSelect(rowSelect);
  } else {
    setrowData((rowData) => rowData.filter((x, i) => i !== rowIndex));     
      rowSelect.pop();
      setrowSelect(rowSelect);
  }
}

8 Comments

no it is not working, when i select two rows buttons shows up, but when i un select one button again set to hidden please check code sandbox
I have updated sandbox.now Its working onSelect: (row, isSelect, rowIndex, e) => { if (isSelect === true) { setrowData((rowData) => [...rowData, row]); rowSelect.push(true); setrowSelect(rowSelect); } else { setrowData((rowData) => rowData.filter((x, i) => i !== rowIndex)); rowSelect.pop(); setrowSelect(rowSelect); } }
where is your code sandbox ? I have tried your edited answer it is not working, as expected.
but there it is not updating, please create your own and share me the link
|
0

Here is one way to implement what you want :

1.Keep your data in one object, and add an id and isSelect fields

const data = [
  {
    id: "id-1",
    fname: "john",
    lname: "smith",
    isSelect: false
  },
  {
    id: "id-2",
    fname: "steve",
    lname: "warn",
    isSelect: false
  },
  {
    id: "id-3",
    fname: "michel",
    lname: "clark",
    isSelect: false
  }
];

2.pass this data to useState :

const [rowData, setrowData] = useState(data);

3.onSelect : just find the row by id and set isSelect field

onSelect: (row, isSelect, rowIndex, e) => {
  setrowData((rows) => {
    return rows.map((r) => {
      if (r.id !== row.id) {
        return r;
      }

      return { ...r, isSelect };
    });
  });
},

4.onSelectAll set isSelect on all rows

onSelectAll: (isSelect, rows, e) => {
  setrowData((rows) => {
    return rows.map((row) => {
      return { ...row, isSelect };
    });
  });
}

5.for Delete_device just filter the data that is not selected :

  const Delete_device = () => {
    setrowData((rows) => {
      return rows.filter((row) => !row.isSelect);
    });
  };

6.for the delete button, get the selected rows and count them, if the count is > 0 then show the button :

const selectedRows = rowData.filter((row) => row.isSelect);

  return (
    <div className="App">
      {selectedRows.length > 0 && (
        <button className="btn btn-primary" onClick={Delete_device}>
          <i className="ri-upload-cloud-line ri-lg"></i>Delete
        </button>
      )}

7.Pass the state data to BootstrapTable

  <BootstrapTable
    bootstrap4
    keyField="fname"
    data={rowData}
    columns={tableData[0].columnsData}
    selectRow={selectRow}
  />

Complete example

1 Comment

No no for this I need to make a lot of changes, but still I will try to implement this.
0

I updated your state to use your data and removed the select array from your select logic. I also optimized it a bit. Its minor change from your codesandbox sample. Also, I recommend you use ids.

import React, { useState, useMemo } from "react";
import "./styles.css";
import "bootstrap/dist/css/bootstrap.min.css";
import BootstrapTable from "react-bootstrap-table-next";
import "react-bootstrap-table-next/dist/react-bootstrap-table2.min.css";

let tableData = [
  {
    rowsData: [
      {
        fname: "john",
        lname: "smith"
      },
      {
        fname: "steve",
        lname: "warn"
      },
      {
        fname: "michel",
        lname: "clark"
      }
    ],
    columnsData: [
      {
        dataField: "fname",
        text: "First name",
        sort: true
      },
      {
        dataField: "lname",
        text: "last Name",
        sort: true
      }
    ]
  }
];

export default function App() {
  const [rowData, setrowData] = useState(tableData[0].rowsData);
  const [rowSelect, setrowSelect] = useState([]);

  const selectRow = useMemo(
    () => ({
      mode: "checkbox",
      clickToSelect: false,
      classes: "selection-row",
      onSelect: (row, isSelect, rowIndex, e) => {
        setrowSelect((rowData) =>
          isSelect
            ? [...rowData, row]
            : rowData.filter(
                ({ fname, lname }) => row.fname !== fname && row.lname !== lname
              )
        );
        // if (isSelect === true) {
        //   setrowSelect((rowData) => [...rowData, row]);
        // } else {
        //   console.log("onSelect", rowIndex, row, isSelect);
        //   setrowSelect((rowData) =>
        //     rowData.filter(
        //       ({ fname, lname }) => row.fname !== fname && row.lname !== lname
        //     )
        //   );
        // }
      },

      onSelectAll: (isSelect, rows, e) => {
        if (isSelect === true) {
          setrowSelect(rows);
        } else setrowSelect([]);
      }
    }),
    []
  );
  const Delete_device = () => {
    console.log("Delete device", rowData, rowSelect);
    if (rowSelect.length < 1) return;
    setrowData((data) =>
      data.filter(
        ({ fname, lname }) =>
          rowSelect.find((s) => s.fname === fname && s.lname === lname) == null
      )
    );
    setrowSelect([]);
  };
  console.log("App", rowData, rowSelect);
  return (
    <div className="App">
      {rowData.length > 0 && (
        <button className="btn btn-primary" onClick={Delete_device}>
          <i className="ri-upload-cloud-line ri-lg"></i>Delete
        </button>
      )}
      <BootstrapTable
        bootstrap4
        keyField="fname"
        data={rowData}
        columns={tableData[0].columnsData}
        selectRow={selectRow}
      />
    </div>
  );
}

https://codesandbox.io/s/react-bootstrap-table-x-wus5r?file=/src/App.js

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.