javascriptadvanced45 minutes

Build a Customizable Data Table with Sorting, Filtering, and Pagination in JavaScript

Create a dynamic and reusable data table component in JavaScript that supports sorting by columns, filtering rows based on multiple criteria, and client-side pagination with a configurable page size.

Challenge prompt

Build a function that accepts an array of objects (representing rows of data) and configuration options, then returns an object representing a data table with the following features: 1. Sorting: Allow sorting data based on any column key, in ascending or descending order. 2. Filtering: Support filtering the rows by multiple column values simultaneously. 3. Pagination: Return the data split into pages with a configurable page size and the ability to switch pages. Your function should expose methods to: - sort(columnKey, order) - filter(filtersObject) - goToPage(pageNumber) - getCurrentPageData() Ensure the table state is preserved between operations, and methods can be chained or called in any order. Use pure JavaScript without UI libraries, focusing on data transformations and an API to interact with the table.

Guidance

  • Design your data structures carefully to track the current state of sorting, filtering, and pagination independently.
  • Apply filters before sorting and pagination to ensure data is consistent with the user's query.
  • Optimize for performance by limiting data operations only to changed aspects and avoid re-processing the entire dataset unnecessarily.
  • Test your function with diverse datasets, including edge cases like empty arrays or columns with non-uniform types.

Hints

  • Consider storing the original data separately from the processed data to reset filters or sorts easily.
  • Think about how to merge multiple filter criteria logically (AND behavior across filters).
  • Remember to validate inputs like page numbers and sort orders to prevent runtime errors.

Starter code

function createDataTable(data, options) {
  // options = { pageSize: number }
  let originalData = [...data];
  let filteredData = [...data];
  let sortedData = [...data];
  let currentPage = 1;
  let pageSize = options.pageSize || 10;
  let sortConfig = { key: null, order: 'asc' };
  let filters = {};

  function applyFilters() {
    // TODO: apply filtering logic to filteredData
  }

  function applySorting() {
    // TODO: sort filteredData into sortedData
  }

  return {
    sort(columnKey, order = 'asc') {
      // TODO
      return this;
    },
    filter(filtersObject) {
      // TODO
      return this;
    },
    goToPage(pageNumber) {
      // TODO
      return this;
    },
    getCurrentPageData() {
      // TODO: return current page slice of sortedData
      return [];
    }
  };
}

Expected output

Example usage: const data = [ { id: 1, name: 'Alice', age: 30 }, { id: 2, name: 'Bob', age: 25 }, { id: 3, name: 'Charlie', age: 35 }, // More rows... ]; const table = createDataTable(data, { pageSize: 2 }) .filter({ age: val => val > 25 }) .sort('name', 'desc') .goToPage(1); console.log(table.getCurrentPageData()); Expected output (page 1 with filtered and sorted data): [ { id: 3, name: 'Charlie', age: 35 }, { id: 1, name: 'Alice', age: 30 } ]

Core concepts

Data TransformationSorting AlgorithmsFiltering LogicPaginationState Management

Challenge a Friend

Send this duel to someone else and see if they can solve it.