Dynamic JS Transformer to Filter and Paginate all Table Data

Just wanted4. to share a JS transformer that I've used in a few apps now (will be converting to a module). If you would like to use it for yourself just follow these steps:

  1. Create a JS transformer and call it filteredData.

  2. Copy and paste the code below into your filteredData transformer, using the following key as a reference for changing column and component names for your own use case:

    Example Transformer Key
    Example Description
    yourQuery Name of data query / data source
    nameSearch Name of Text Input Component
    creatorSwitch Name of Segmented Switch / Toggle Switch Component
    listPagination Name of Pagination Component
    itemsPerPage Change to # of results you want per page
    USER_NAME The column header which contains a user's name
    CREATOR_ID The column header which contains the ID of whoever created a row of data
  const unfilteredData = {{ yourQuery.data }};
  const nameSearch = {{ nameSearch.value || '' }}.trim().toLowerCase();
  const userSubmissions = {{ creatorSwitch.value }};
  const currentPage = {{ listPagination.value }};
  const itemsPerPage = 10;

  const filteredData = unfilteredData.filter(row => {
    const nameMatches = nameSearch ? row.USER_NAME?.toLowerCase().includes(nameSearch) : true;
    const currentUserMatches = userSubmissions ? row.CREATOR_ID === {{ current_user.id }} : true;

    return nameMatches && currentUserMatches;
  });

  const totalPages = Math.ceil(filteredData.length / itemsPerPage);
  const offset = (currentPage - 1) * itemsPerPage;
  const paginatedData = filteredData.slice(offset, offset + itemsPerPage);

  return {
    data: paginatedData,
    totalPages: totalPages,
    currentPage: currentPage
  };

For using on tables:

  1. Place a new table component.
  2. Set your data source to {{ filteredData.value.data }}.
  3. In your table component's inspector, select the Pagination option under Add Ons +, and set the value of Page Size to {{ filteredData.value.data.length }}.
  4. Add a text input component above your table and call it nameSearch.
  5. Add a segmented switch component (or any other switch) and call it creatorSwitch. Set one value of the switch to current_user.id, and the other value to 0.
  6. Add 2 Default Filters to your table in the inspector options:
    • One for your nameSearch text input where your data table's USER_NAME column INCLUDES {{ nameSearch.value }};
    • And the other for your creatorSwitch switch input where your table's CREATOR_ID column IS {{ creatorSwitch.value }};
  7. Enjoy!

For using in a list view component:

  1. Place a new container component
  2. Open the new container component's inspector, and select the Footer option under Add Ons + to add a footer to the container.
  3. Within the footer of that container component -- place a new pagination component and call it listPagination
    • In that pagination component -- set the value of Page count to {{ filteredData.value.totalPages }}
  4. Within the body of that container component -- place a new list view component
    • In that list view component -- set the data source of your list view to {{ filteredData.value.data }}
  5. Within the header of the container component that contains your list view and pagination components -- place a new text input component and segmented switch component (or whatever switch). Again -- set the value of the switch to current_user.id, and the other value to 0
  6. And voila! :magic_wand: The rest will be handled by our transformer :slight_smile:

I hope this helps someone and happy retool-ing everybody!!!

1 Like

Amazing!! Thank you, @AJVancattenburch :magic_wand:

1 Like

Of course and thank you for the compliment! Always appreciate your insight and input @Tess! :pray: