Data Analyse Breda

React Table #4: Kolomfilter variaties: Min-Max, en Dropdown filters

In deze serie posts vertellen we u meer over het gebruik van React Table. Deze bibliotheek stelt ons in staat om krachtige data tabellen te maken binnen React JS. We laten u zien hoe u een simpele tabel kan maken, hoe u vervolgens filters, sorteeropties, en pagination kan toevoegen, en hoe u de tabel kan stylen zodat het aantrekkelijk is voor gebruikers in uw applicatie.

In de voorgaande post hebben we met behulp van de useFilter hook een begin gemaakt met kolomfilters. We hebben nog enkel een tekstfilter gemaakt, in deze post gaan we enkele variaties hierop introduceren. We de min-max filter en de dropdown filter. Aan het einde van dit artikel vindt u opnieuw een Sandbox met daarin alle code en een werkend voorbeeld.

Dropdown filter

We beginnen met de dropdown filter. Onderstaand de benodigde code die we toe dienen te voegen aan ons Filters. js bestand. Onder de code vindt u de uitleg.

Filters.js 

export const DropdownFilter= ({
  column: { filterValue, setFilter, preFilteredRows, id }
}) => {
  const options = useMemo(() => {
    const options = new Set();
    preFilteredRows.forEach((row) => {
      options.add(row.values[id]);
    });
    return [...options.values()];
  }, [id, preFilteredRows]);

  return (
    <select
      type="select"
      value={filterValue}
      onChange={(e) => {
        setFilter(e.target.value || undefined);
      }}
    >
      <option value="">Alles</option>
      {options.map((option) => (
        <option key={option} value={option}>
          {option}
        </option>
      ))}
    </select>
  );
};
  • De dropdown heeft als parameter de column. Dit is de link naar de kolom van de tabel, waar ook het datapunt aan vast zit. Hierbinnen worden vier variabelen gebruikt, namelijk filterValue, setFilter, preFilteredRows, en id. De eerste drie hebben we in de voorgaande post ook al gezien.
  • De eerste constante in de functie zorgt ervoor dat alle opties die in de rijen beschikbaar zijn in onze dropdown komen. Je ziet dat hij eerst alle preFilteredRows doorloopt, en vervolgens van elke bestaande rij de id toevoegt aan de opties constante (Je moet voor dit voorbeeld dus een id hebben in je data!). Dit is logisch, want preFilteredRows zijn alle rijen die beschikbaar zijn voor een filtermoment. Als er dus een andere kolom gefilterd wordt, zorgt preFilteredRows ervoor dat alleen de overgebleven waardes uit die rijen nog zichtbaar zijn in je dropdown filter.

Voorbeeld: Ik heb de filter toegepast op landen. Hier heb ik 4 opties + alles. Als ik nu de clubs filter op aa, blijven er nog clubs uit drie landen over. De dropdown filter laat dan ook alleen die landen nog zien.

  • De return statement werkt hetzelfde als in de voorgaande post. De FilterValue is de waarde van de filter. Dit is de input die de gebruiker selecteert. De onchange wordt geactiveerd als de filterValue veranderd. Als dit gebeurd wordt de setFilter functie getriggered. Deze functie pakt de value, en communiceert deze door aan de filter. En zo krijgt de gebruiker uiteindelijk de juiste waardes te zien.
  • In ons select field zie je twee opties gedefinieerd. De eerste is Alles, deze optie heeft geen waarde, en zorgt er dus voor dat de filter weer leeg word en alles zichtbaar is. De rest van de opties komen voort uit onze options constante. Dit is de lijst van alle mogelijke opties die nog beschikbaar zijn in de kolom.

Om de dropdown in de tabel te krijgen dienen we nog twee kleine dingen aan te passen in ons Tabel.js bestand. Allereerst importeren we onze filter bovenaan het bestand.

Tabel.js 

import { DropdownFilter } from "./Filters";

Vervolgens dienen we in onze kolom aan te geven welke kolommen een dropdown filter moeten krijgen. Ook moeten we het filtertype definïeeren. Hier kiezen we equals omdat we alleen resultaten willen zien die gelijk zijn aan onze zoekopdracht. De dikgedrukte code bij Land kan je als je wil bij elke kolom toepassen.

Tabel.js
const columns = useMemo(
    () => [
      {
        Header: "Id",
        accessor: "id",
        disableFilters: true
      },
      {
        Header: "Clubnaam",
        accessor: "naam"
      },
      {
        Header: "Land",
        accessor: "land",
        Filter: DropdownFilter,
        filter: "equals"
      },
      {
        Header: "Stadion",
        accessor: "stadion"
      },
      {
        Header: "Capaciteit",
        accessor: "capaciteit",
        disableFilters: true
      }
    ],
    []
  );

Min-Max filter

Dan nu de min-max filter. Deze filter stelt u in staat om tussen twee verschillende waarden te filteren. Opnieuw onderstaand de code voor in het Filters.js bestand , daarna volgt de uitleg.

Filters.js


export const MinMaxFilter = ({
  column: { filterValue = [], preFilteredRows, setFilter, id }
}) => {
  const [min, max] = React.useMemo(() => {
    let min = preFilteredRows.length ? preFilteredRows[0].values[id] : 0;
    let max = preFilteredRows.length ? preFilteredRows[0].values[id] : 0;
    preFilteredRows.forEach((row) => {
      min = Math.min(row.values[id], min);
      max = Math.max(row.values[id], max);
    });
    return [min, max];
  }, [id, preFilteredRows]);

  return (
    <div
      style={{
        display: "flex"
      }}
    >
      <input
        value={filterValue[0] || ""}
        type="number"
        onChange={(e) => {
          const val = e.target.value;
          setFilter((old = []) => [
            val ? parseInt(val, 10) : undefined,
            old[1]
          ]);
        }}
        placeholder={`Min (${min})`}
        style={{
          width: "70px",
          marginRight: "0.5rem"
        }}
      />
      tot
      <input
        value={filterValue[1] || ""}
        type="number"
        onChange={(e) => {
          const val = e.target.value;
          setFilter((old = []) => [
            old[0],
            val ? parseInt(val, 10) : undefined
          ]);
        }}
        placeholder={`Max (${max})`}
        style={{
          width: "70px",
          marginLeft: "0.5rem"
        }}
      />
    </div>
  );
};

Zoals je ziet is deze code wat langer, hieronder een uitleg over enkele aspecten:

  • De constante [Min, Max] gaat na wat nou de min en de max is. Je ziet eerst twee keer de let, dit betekent dat de voorlopige waarde van min en max op 0 gezet worden. Vervolgens word met preFilteredRow voor elke ongefilterde rij gekeken of het de hoogste of laagste waarde is. Nadat alle rijen geevalueerd zijn hebben we onze min en max waardes uit de tabel.
  • We hebben ook twee inputvelden. De eerste is de min, de tweede de max. De filterValue is hier opnieuw de waarde die de gebruiker ingeeft. Als hier verandering in komt word de onChange functie geactiveerd die vervolgens die setFilter functie triggered. SetFunctie verteld tegen de filter wat de waardes zijn in de input boxen.
  • Beide boxen hebben een placeholder met daarin de min/ max waarde uit de constante [min,max]. Dit verteld de gebruiker wat de minimale en maximale waardes zijn.

Nu kunnen we de filter importeren in ons Tabel.js bestand.

Tabel.js
import { MinMaxFilter } from "./Filters";

Ook dienen we de Filter in de kolommen te vermelden samen met het filtertype (filter). In dit geval kiezen we hier between omdat we tussen twee waardes willen filteren.

Tabel.js

const columns = useMemo(
    () => [
      {
        Header: "Id",
        accessor: "id",
        Filter: MinMaxFilter,
        filter: "between"
      },
      {
        Header: "Clubnaam",
        accessor: "naam"
      },
      {
        Header: "Land",
        accessor: "land",
        Filter: DropdownFilter,
        filter: "equals"
      },
      {
        Header: "Stadion",
        accessor: "stadion"
      },
      {
        Header: "Capaciteit",
        accessor: "capaciteit",
        disableFilters: true
      }
    ],
    []
  );

Sandbox

Dit was de tutorial over het invoegen van een min-max en dropdown filter in React JS. De volgende blogpost we dieper ingaan op pagination. Daarnaast zullen we later aan de slag gaan met styling en andere functionaliteiten.

Leave a Reply