Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter and Pagination do not work correctly when using controlledProps or managing filter state externally #219

Open
EnzoArg opened this issue Nov 29, 2024 · 1 comment

Comments

@EnzoArg
Copy link

EnzoArg commented Nov 29, 2024

I am encountering issues with the Filter component and its integration with DatatableWrapper. When I attempt to use controlledProps to manage the filter state externally, the component stops working, breaking both the filter and pagination functionality.

When I do not use controlledProps, the filter and pagination work correctly. However, if I open a modal or interact with other states in the application, the filter value resets, losing the active search.

Additionally, I want to highlight that my problem arises specifically when I add a button in each row that opens a Modal( react-bootstrap/Modal). When the modal is opened, the search input in the data table is cleared.

Here’s a simplified example of the issue:

function MyProgram() {
  const [modalShow, setModalShow] = useState(false);
  const [dataSelected, setdDataSelected] = useState({});

const columns = [
    {
      prop: 'id',
      title: 'Id',
      isFilterable: true,
      isSortable: true,
    },
    {
      prop: 'name',
      title: 'Name',
      isFilterable: true,
      isSortable: true,
    },
    {
      prop: 'description',
      title: 'Description',
      isFilterable: true,
      isSortable: true,
    },
    {
      prop: 'Actions',
      title: 'Actions',
      cell: (row) => (
        <ButtonGroup
          dataRow= {row}
          handleShow={handleButtonShowModal}
        />
      ),
    },
  ];
  const handleButtonShowModal = async (row) => {
    try {
      //request axios to get extra data
      const data = response.data.data;
      setdDataSelected(data);
      setModalShow(true);
    } catch (error) {
      console.error('Fail on handleButtonShowModal:', error);
    }
  };
  
  return (
    <>
      <hr />
      <MyModal show={modalShow} onHide={() => setModalShow(false)} data={dataSelected} />
      <MyDataTable
        columns={columns}
        data={myData}
      />
    </>
  );
}
export default MyProgram;



import PropTypes from "prop-types";
import { Col, Row, Table } from "react-bootstrap";
import {
  DatatableWrapper,
  Filter,
  Pagination,
  TableBody,
  TableHeader
} from "react-bs-datatable";

const MyDataTable = ({ columns, data }) => {
  return (
    <DatatableWrapper
      body={data}
      headers={columns}
      paginationOptionsProps={{
        initialState: {
          rowsPerPage: 10,
        },
      }}
    >
      <Row className="mb-4 p-2">
        <Col
          xs={12}
          lg={8}
          className="d-flex flex-col justify-content-end align-items-end"
        >
          <Filter placeholder="Search" />
        </Col>
        <Col
          xs={12}
          sm={6}
          lg={4}
          className="d-flex flex-col justify-content-end align-items-end"
        >
          <Pagination />
        </Col>
      </Row>
      <Table>
        <TableHeader />
        <TableBody />
      </Table>
    </DatatableWrapper>
  );
};

MyDataTable.propTypes = {
  columns: PropTypes.arrayOf(PropTypes.object).isRequired,
  data: PropTypes.arrayOf(PropTypes.object).isRequired,
};

export default MyDataTable;

Previous Approach (Without controlledProps):

In the previous implementation, the filter and pagination work correctly.
However, when I open a react-bootstrap/Modal or interact with other parts of the application, the active filter value resets, losing the search.
Current Approach (With controlledProps):

When using controlledProps to manage the filter state externally, both the filter and pagination stop working altogether.

import PropTypes from "prop-types";
import { Col, Row, Table } from "react-bootstrap";
import {
  DatatableWrapper,
  Filter,
  Pagination,
  TableBody,
  TableHeader,
} from "react-bs-datatable";

const MyDataTable = ({ columns, data, filterValue, onFilterChange }) => {
  return (
    <DatatableWrapper
      body={data}
      headers={columns}
      paginationOptionsProps={{
        initialState: {
          rowsPerPage: 10,
        },
      }}
      sortProps={{
        initialState: {
          order: "asc",
          prop: "name",
        },
      }}
      filterProps={{
        filterValue,
        onFilterChange,
      }}
    >
      <Row className="mb-4 p-2">
        <Col xs={12} lg={8}>
          <Filter
            placeholder="Search"
            controlledProps={{
              filter: filterValue,
              onFilterChange,
            }}
          />
        </Col>
        <Col xs={12} sm={6} lg={4}>
          <Pagination />
        </Col>
      </Row>
      <Table>
        <TableHeader />
        <TableBody />
      </Table>
    </DatatableWrapper>
  );
};

MyDataTable.propTypes = {
  columns: PropTypes.arrayOf(PropTypes.object).isRequired,
  data: PropTypes.arrayOf(PropTypes.object).isRequired,
  filterValue: PropTypes.string.isRequired,
  onFilterChange: PropTypes.func.isRequired,
};

export default MyDataTable;

It might be that I’m not correctly understanding how to use the library, and perhaps I should implement my filter externally to the datatable.

SO: Windows 10
CODE: (javascript)
"react": "^18.2.0",
"react-bootstrap": "^2.10.6",
"react-bs-datatable": "^3.15.0",
browser: chrome and edge

thanks!

@imballinst
Copy link
Owner

imballinst commented Nov 29, 2024

hi @EnzoArg, thanks for reporting this issue! Apologies, the documentation is a bit lacking. Apparently the Storybook examples for controlled table were broken, now it should be fixed: https://imballinst.github.io/react-bs-datatable/storybook/?path=/story/controlled--async. The story files can be seen in this folder: https://github.com/imballinst/react-bs-datatable/tree/main/src/__stories__/01-Controlled.

I have also created example StackBlitz project here: https://stackblitz.com/edit/vitejs-vite-pqsyk4?file=src%2FTable.tsx

From what I could see, when we want to use controlled component, we only need to provide headers and body column to <DatatableWrapper>. Then, all control components needs to have controlledProps. For example:

<Filter controlledProps={{ filter, onFilterChange }} />

<PaginationOptions
  controlledProps={{
    filteredDataLength,
    onRowsPerPageChange,
    rowsPerPageOptions: [5, 10, 15, 20],
    rowsPerPage,
  }}
/>

<Pagination controlledProps={{ currentPage, maxPage, onPaginationChange }} />

<TableHeader
  controlledProps={{
    sortState,
    onSortChange,
    filteredDataLength,
  }}
/>

<TableBody
  controlledProps={{
    filteredDataLength,
  }}
/>

I believe that should cover all -- I would appreciate it if you could expand on the StackBlitz example above and expand on your example, if you still have problems. I can fix your example from there 😄 Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants