javascriptreactjshtml-tablereact-tablereact-table-v7

How can I set the default state of a checkbox based on value in firestore in react table


How can I set the default state of checkboxes based on values from firestore in React Table. Sorry if the question is a bit basic. I have read through the official docs and couldn't really make sense of how to do it, I've also looked at a good few other examples.

I'm looking to check the value in a firestore document when the page loads, then set the default value of the checkbox. I also want the user to be able to check/uncheck it which will then update that field in the doc.

I've looked at this initialState.selectedRowIds: Object<rowId: Boolean> in the docs but cant figure out how to get it to work or what else needs to be connected with it.

Any help would be greatly appreciated.

Here is my implementation below.

    import React from "react";
import {
  useTable,
  useFlexLayout,
  useFilters,
  useGlobalFilter,
  useRowSelect
} from "react-table";
import _ from "lodash";
// noinspection ES6CheckImport
import { useHistory } from "react-router-dom";
import Table from "react-bootstrap/Table";

// Define a default UI for filtering
function GlobalFilter({
  preGlobalFilteredRows,
  globalFilter,
  setGlobalFilter
}) {
  return (
    <span>
      <input
        value={globalFilter || ""}
        onChange={e => {
          setGlobalFilter(e.target.value || undefined); // Set undefined to remove the filter entirely
        }}
        placeholder={" Search by any criteria"}
        style={{
          fontSize: "2.0rem",
          width: "100%"
        }}
      />
    </span>
  );
}

   
export const RecordTable = ({ forms }) => {
  const data = forms;
  let history = useHistory();

  const columns = React.useMemo(
    () => [
      {
        Header: "Disclaimer Form Records",
        columns: [
          {
            Header: "Active",
            accessor: "active",
            width: 75,
            maxWidth: 75,
            maxHeight: 50,
            Cell: ({ row, column }) => (
              <div
                style={{
                  fontSize: "50px",
                  textAlign: "center",
                  display: "flex",
                  justifyContent: "center",
                  alignItems: "center",
                  width: "100%",
                  height: "100%"
                }}
                onClick={event => {
                  event.stopPropagation();
                  console.log("div OnClick");
                }}>
                <input
                  type="checkbox"
                  onClick={event => {
                    event.stopPropagation();
                    console.log("checkedIn Clicked: ", column);
                  }}
                  {...row.getToggleRowSelectedProps}
                />
              </div>
            )
          },
          {
            Header: "Time In",
            accessor: "timeIn"
          },
          {
            Header: "Time Out",
            accessor: "timeOut"
          },
          {
            Header: "€ Price",
            accessor: "totalGroupPrice",
            disableFilters: true,
            disableSortBy: true
          },
          {
            Header: "Shoebox",
            accessor: "shoeboxNumber"
          }
        ]
      }
    ],
    []
  );

  const defaultColumn = React.useMemo(
    () => ({
      //minWidth: 20,
      maxWidth: 150,
      width: 120
    }),
    []
  );

  const rowOnClick = (rowObject, column) => {
    history.push("/viewform", { ...rowObject.original });
  };

  // Use the state and functions returned from useTable to build your UI
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    state,
    preGlobalFilteredRows,
    setGlobalFilter,
    setHiddenColumns
  } = useTable(
    {
      columns,
      data,
      defaultColumn,
    },
    useFilters,
    useGlobalFilter,
    useFlexLayout,
    useRowSelect
  );

  React.useEffect(() => {
    // for each column who's data is null, hide that column.

    let emptyColumns = [];

    _.forEach(data[0], function(value, key) {
      if (value === "") emptyColumns.push(key);
    });

    emptyColumns.push("parentEmailAddress");

    setHiddenColumns(emptyColumns);
  }, [setHiddenColumns, columns]);

  // Render the UI for your table
  return (
    <div>
      <div>Records: {rows.length}</div>
      <GlobalFilter
        preGlobalFilteredRows={preGlobalFilteredRows}
        globalFilter={state.globalFilter}
        setGlobalFilter={setGlobalFilter}
      />

      <div
        style={{
          height: 500,
          border: "2px solid grey",
          borderRadius: "5px",
          overflow: "scroll"
        }}>
        <Table striped bordered hover responsive={"md"} {...getTableProps()}>
          <thead>
            {headerGroups.map(headerGroup => (
              <tr {...headerGroup.getHeaderGroupProps()}>
                {headerGroup.headers.map(column => (
                  <th {...column.getHeaderProps()}>
                    {column.render("Header")}
                  </th>
                ))}
              </tr>
            ))}
          </thead>

          <tbody {...getTableBodyProps()}>
            {rows.map((row, i) => {
              prepareRow(row);
              return (
                <tr
                  {...row.getRowProps({
                    onClick: () => rowOnClick(row)
                  })}>
                  {row.cells.map(cell => {
                    return (
                      <td {...cell.getCellProps()}>{cell.render("Cell")}</td>
                    );
                  })}
                </tr>
              );
            })}
          </tbody>
        </Table>
      </div>
    </div>
  );
};

Solution

  • Although maybe not the most recommended way.

    This is whats worked for me:

    I read in a boolean from firestore, then pass it to the checkbox. Whenever I check/uncheck the checkbox I have a function that toggles the value in firestore, and I have a snapshot function that's subscribed to any changes so automatically updates the actual checkbox.

    <input type="checkbox" checked={isChecked}