Fermer

mai 17, 2023

Comment implémenter le filtrage dans votre grille de données React

Comment implémenter le filtrage dans votre grille de données React


Apprenez à filtrer vos données dans une grille React à l’aide de KendoReact Data Grid.

Le filtrage des données est une fonctionnalité couramment utilisée dans les applications Web gourmandes en données. Il permet aux utilisateurs de trouver rapidement des informations spécifiques en fonction des critères de recherche fournis. Grâce à cela, les utilisateurs peuvent facilement trouver ce dont ils ont besoin sans avoir à parcourir de grandes quantités de données.

Dans cet article, nous allons expliquer comment implémenter la fonctionnalité de filtrage dans React. Nous utiliserons KendoReact Data Grid pour créer une table avec un ensemble de données de recettes, puis commencerons à ajouter des filtres plus complexes pour trouver des données spécifiques.

Qu’est-ce que la grille KendoReact ?

Le Grille du progrès KendoRéagir est un puissant composant de tableau React qui fournit plus d’une centaine de fonctionnalités prêtes à l’emploi, notamment la pagination, le tri, le filtrage, l’édition, le regroupement de lignes et de colonnes, l’exportation de données vers différents formats, etc. Grâce à la prise en charge des lignes et des colonnes virtualisées, il permet aux utilisateurs de travailler facilement avec de grands ensembles de données.

Configuration du projet

Si vous souhaitez suivre cet article, clonez le référentiel suivant et passez au start bifurquer. Le main branche contient le code final pour cette partie de la série.

$ git clone git@github.com:ThomasFindlay/kendo-react-how-to-implement-filtering-in-data-grid.git
$ cd kendo-react-how-to-implement-filtering-in-data-grid
$ git checkout start
$ npm install
$ npm run dev

Le npm install commande installera toutes les dépendances, et npm run dev démarre le serveur de développement.

L’exemple d’application a été échafaudé avec Vite. Si vous n’en avez jamais entendu parler ou utilisé auparavant, j’ai écrit un article à ce sujet—Qu’est-ce que Vite : le guide des outils de projet modernes et ultra-rapides.

Vous pouvez trouver l’exemple de code complet pour cet article dans ce référentiel GitHub. Ci-dessous, vous pouvez également trouver un exemple interactif de StackBlitz.

Configuration par défaut de la grille de données KendoReact

Commençons par créer un nouveau fichier appelé RecettesTable.jsx dans le src/composants annuaire. Nous allons commencer par importer quelques éléments.

src/components/RecipesTable.jsx

import { useState } from "react";
import { Grid, GridColumn as Column } from "@progress/kendo-react-grid";
import { filterBy } from "@progress/kendo-data-query";
import originalRecipes from "../assets/recipes.json";
const recipes = originalRecipes.slice(0, 100);

De plus, le useState hook sera utilisé pour contenir l’état des filtres.

Ensuite, nous importons Grid et GridColumn composants de la @progress/kendo-react-grid bibliothèque. Nous allons utiliser ces composants pour créer un tableau.

De plus, le filterBy méthode fournie par @progress/kendo-data-query se chargera de filtrer les données.

Enfin et surtout, recipes est un tableau d’objets contenant des informations sur les recettes. Cet ensemble de données a été extrait de kaggle et il peut y avoir des fautes de frappe, etc., mais ce n’est pas pertinent pour ce projet. Nous avons juste besoin de beaucoup de données pour le tableau.

Ensuite, configurons l’état initial des filtres et rendons une table avec le recipes données.

src/components/RecipesTable.jsx

import { Grid, GridColumn as Column } from "@progress/kendo-react-grid";
import originalRecipes from "../assets/recipes.json";
const recipes = originalRecipes.slice(0, 100);

export const RecipesTable = () => {
  return (
    <Grid
      style={{
        height: "420px",
      }}
      data={recipes}
      pageSize={20}
    >
      <Column field="recipe" title="Recipe" width="250px" />
      <Column field="numIngredients" title="Ingredients" width="150px" />
      <Column field="cuisine" title="Cuisine" width="120px" />
      <Column field="course" title="Course" width="120px" />
      <Column field="servings" title="Servings" width="120px" />
      <Column field="cookTime" title="Cooking Time" width="150px" />
      <Column field="prepTime" title="Prep Time" width="120px" />
      <Column field="totalTime" title="Total Time" width="120px" />
    </Grid>
  );
};

export default RecipesTable;

Le RecipesTable composant est assez simple. Nous utilisons le Grid et GridColumn composants de la @progress/kendo-react-grid packagez et affichez un tableau avec les colonnes suivantes :

  • Recette
  • Ingrédients
  • Cuisine
  • Cours
  • Portions
  • Temps de cuisson
  • Temps de préparation
  • Temps total

Enfin, nous devons ajouter le RecipesTable composant dans le App.jsx déposer.

src/App.jsx

import "./App.css";
import RecipesTable from "./components/RecipesTable.jsx";

function App() {
  return (
    <div className="App">
      <h1>KendoReact Data Grid Filtering</h1>
      <h2>Default Table</h2>
      <RecipesTable />
    </div>
  );
}

export default App;

L’image ci-dessous montre à quoi ressemble le tableau.

Tableau de grille KendoReact simple

Nous n’avons pas eu besoin d’écrire beaucoup de code et nous avons une belle table avec plusieurs colonnes. Ensuite, ajoutons la fonctionnalité de filtrage.

Filtres de colonne par défaut

L’ajout de filtres pour chaque colonne dans KendoReact Data Grid est très simple. Tout d’abord, nous devons commencer par définir un objet qui servira d’état initial pour les filtres. Appelons-le initialFilter. Le initialFilter l’objet a besoin de deux propriétés—logic et filters:

  • logic: configure l’opérateur logique utilisé lors de la combinaison de plusieurs filtres. Il devrait être « et » ou « ou ».
  • filters: contient les filtres qui seront appliqués en fonction de l’opérateur logique spécifié dans le logic valeur.

Ci-dessous, vous pouvez voir la configuration de base du filtre sans aucune logique de filtrage.

const initialFilter = {
  logic: "and",
  filters: [],
};

Certains scénarios peuvent nécessiter la définition préalable de certains filtres pour les utilisateurs. Par exemple, une page peut avoir un tableau d’utilisateurs qui ne doit initialement afficher que les utilisateurs actifs. Supposons qu’un objet utilisateur ait un status propriété qui peut être soit
Active ou Inactive. Afficher uniquement les utilisateurs actifs peut être obtenu en définissant le filtre suivant :

const initialFilter = {
  logic: "and",
  filters: [
    {
      field: 'status',
      operator: 'eq',
      value: 'Active'
    }
  ]
}

Notez que plusieurs filtres peuvent être ajoutés. Nous utilisons des recettes dans nos exemples, nous pourrions donc configurer le tableau pour afficher uniquement les recettes asiatiques contenant le mot « poulet ».

const initialFilter = {
  logic: "and",
  filters: [
    {
      field: "recipe",
      operator: "contains",
      value: "Chicken",
    },
    {
      field: "cuisine",
      operator: "Contains",
      value: "Asian",
    },
  ],
};

Le initialFilter sera transmis au useState crochet, comme le Grid le composant doit pouvoir le mettre à jour.

const [filter, setFilter] = useState(initialFilter)

Les prochaines étapes consistent à passer quelques accessoires au Grid et Column Composants.

Plus précisément, le Grid le composant doit recevoir filterable, filter et onFilterChange accessoires, et les Column les composants ont besoin filter et un facultatif format soutenir.

Le filterable prop active la fonctionnalité de filtrage, tandis que le filter accessoire passé au Grid le composant est le filter objet retourné par le useState crochet au-dessus. Encore une fois, il spécifie quel type de filtres doit être appliqué.

Cependant, le filter accessoire passé au Column est différent, car il est utilisé pour spécifier le type de filtre à utiliser pour une colonne. Il peut s’agir de l’un des éléments suivants : text, numeric, boolean ou date. L’optionnel format prop peut être utilisé pour formater le texte de la colonne. Créons un nouveau composant pour la grille de recettes qui contiendra des filtres de colonne.

src/components/RecipesGridWithColumnFilters.jsx

import { Grid, GridColumn as Column } from "@progress/kendo-react-grid";
import { filterBy } from "@progress/kendo-data-query";
import { useState } from "react";
import originalRecipes from "../assets/recipes.json";
import { useEffect } from "react";

const recipes = originalRecipes.slice(0, 100);
const initialFilter = {
  logic: "and",
  filters: [],
};

const gridStyle = {
  height: "420px",
};

export const RecipesGridWithColumnFilters = () => {
  const [filter, setFilter] = useState(initialFilter);

  return (
    <Grid
      style={gridStyle}
      data={filterBy(recipes, filter)}
      pageSize={20}
      filterable
      filter={filter}
      onFilterChange={e => setFilter(e.filter)}
    >
      <Column field="recipe" title="Recipe" width="250px" filterable />
      <Column
        field="numIngredients"
        title="Ingredients"
        width="240px"
        filter="numeric"
      />
      <Column field="cuisine" title="Cuisine" width="240px" />
      <Column field="course" title="Course" width="240px" />
      <Column
        field="servings"
        title="Servings"
        width="240px"
        filter="numeric"
      />
      <Column
        field="cookTime"
        title="Cooking Time"
        width="240px"
        filter="numeric"
        format="{0} mins"
      />
      <Column
        field="prepTime"
        title="Prep Time"
        width="240px"
        filter="numeric"
        format="{0} mins"
      />
      <Column
        field="totalTime"
        title="Total Time"
        width="240px"
        filter="numeric"
        format="{0} mins"
      />
    </Grid>
  );
};

export default RecipesGridWithColumnFilters;

Il faut l’ajouter dans le App composant également.

src/App.jsx

import "./App.css";
import RecipesTable from "./components/RecipesTable.jsx";
import RecipesGridWithColumnFilters from "./components/RecipesGridWithColumnFilters.jsx";

function App() {
  return (
    <div className="App">
      <h1>KendoReact Data Grid Filtering</h1>
      {}
      <h2>Grid with column filters</h2>
      <RecipesGridWithColumnFilters />
    </div>
  );
}

export default App;

Le GIF ci-dessous montre comment utiliser la fonctionnalité de filtrage de colonne.

Filtres de colonne de grille de données KendoReact

Nous pouvons saisir la valeur que nous voulons rechercher et modifier l’opérateur du filtre selon les besoins. Par exemple, si nous voulons trouver des recettes qui peuvent être faites en 2 heures, nous pouvons régler le filtre de temps total sur 120 et l’opérateur sur is less than or equal toou si nous avons envie d’un repas de la cuisine indienne, nous changeons simplement le filtre Plat.

Dans la section suivante, nous verrons comment ajouter des filtres de colonne personnalisés.

Filtres de colonne personnalisés

Supposons que nous aimerions pouvoir spécifier le montant minimum et maximum pour la cuisson, la préparation et le temps total. Nous ne pouvons pas le faire avec les filtres de colonne par défaut, mais heureusement, nous pouvons fournir notre propre composant de filtre personnalisé. Créons un composant appelé RangeFilterCell.

src/components/RangeFilterCell.jsx

import { NumericTextBox } from "@progress/kendo-react-inputs";

export const RangeFilterCell = props => {
  let minTextBox;
  let maxTextBox;
  
  const inRange = (current, { min, max }) =>
    (min === null || current >= min) && (max === null || current <= max);
  
  const onChange = event => {
    props.onChange({
      value: {
        min: minTextBox.value,
        max: maxTextBox.value,
      },
      operator: inRange,
      syntheticEvent: event.syntheticEvent,
    });
  };
  
  const onClearButtonClick = event => {
    event.preventDefault();
    props.onChange({
      value: null,
      operator: "",
      syntheticEvent: event,
    });
  };
  
  const value = props.value || null;
  
  return (
    <div className="k-display-flex k-align-items-end">
      <div className="k-display-flex k-flex-column">
        <span>Min:</span>
        <span
          style={{
            margin: "0 16px 0 2px",
          }}
        >
          <NumericTextBox
            width="80px"
            value={value && value.min}
            ref={numeric => {
              minTextBox = numeric;
            }}
            onChange={onChange}
          />
        </span>
      </div>
      <div className="k-display-flex k-flex-column">
        <span>Max:</span>
        <span
          style={{
            margin: "0 8px 0 4px",
          }}
        >
          <NumericTextBox
            width="80px"
            value={value && value.max}
            ref={numeric => {
              maxTextBox = numeric;
            }}
            onChange={onChange}
          />
        </span>
      </div>
      <button
        className="k-button k-button-md k-rounded-md k-button-solid k-button-solid-base k-button k-button-md k-rounded-md k-button-solid k-button-solid-base-icon k-clear-button-visible"
        title="Clear"
        disabled={!value}
        onClick={onClearButtonClick}
      >
        <span className="k-icon k-i-filter-clear" />
      </button>
    </div>
  );
};

Assumons ce qui se passe dans le RangeFilterCell composant.

Le minTextBox et maxTextBox les variables sont utilisées pour stocker les références aux champs d’entrée min et max. Le inRange la fonction vérifie si la valeur fournie est dans la min et max filtres spécifiés par un utilisateur.

Ensuite, nous avons onChange et onClearButtonClick fonctions utilisées pour mettre à jour l’état des filtres. Le premier récupère les valeurs des entrées min et max et passe le inRange fonctionner comme le operator.

Puisque nous avons un filtre et une valeur personnalisés, nous avons également besoin d’un opérateur personnalisé pour filtrer les données. Nous devons également transmettre le synthethicEvent objet. Si c’est la première fois que vous entendez parler d’événements synthétiques dans React, assurez-vous de consulter les nouveaux documents React sur ce sujet. ici.

Le onClearButtonClick, comme son nom l’indique, réinitialise le filtre min-max. Le RangeFilterCell Le composant affiche deux entrées numériques et un bouton pour réinitialiser le filtre. Maintenant, nous pouvons l’utiliser et le passer au Column Composants. Encore une fois, créons un nouveau composant pour la grille de données.

src/components/RecipesGridWithCustomCellFilter.jsx

import { Grid, GridColumn as Column } from "@progress/kendo-react-grid";
import { filterBy } from "@progress/kendo-data-query";
import { useState } from "react";
import { RangeFilterCell } from "./rangeFilterCell";
import originalRecipes from "../assets/recipes.json";
const recipes = originalRecipes.slice(0, 100);

const initialFilter = {
  logic: "and",
  filters: [],
};

export const RecipesGridWithCustomCellFilter = () => {
  const [filter, setFilter] = useState(initialFilter);
  return (
    <Grid
      style={{
        height: "420px",
      }}
      data={filterBy(recipes, filter)}
      pageSize={20}
      filterable
      filter={filter}
      onFilterChange={e => setFilter(e.filter)}
    >
      <Column field="recipe" title="Recipe" width="250px" />
      <Column
        field="numIngredients"
        title="Ingredients"
        width="320px"
        filter="numeric"
        filterCell={RangeFilterCell}
      />
      <Column field="cuisine" title="Cuisine" width="260px" />
      <Column field="course" title="Course" width="260px" />
      <Column
        field="servings"
        title="Servings"
        width="320px"
        filter="numeric"
        filterCell={RangeFilterCell}
      />
      <Column
        field="cookTime"
        title="Cooking Time"
        width="320px"
        filter="numeric"
        format="{0} mins"
        filterCell={RangeFilterCell}
      />
      <Column
        field="prepTime"
        title="Prep Time"
        width="320px"
        filter="numeric"
        format="{0} mins"
        filterCell={RangeFilterCell}
      />
      <Column
        field="totalTime"
        title="Total Time"
        width="320px"
        filter="numeric"
        format="{0} mins"
        filterCell={RangeFilterCell}
      />
    </Grid>
  );
};

export default RecipesGridWithCustomCellFilter;

Le RangeFilterCell Le composant est passé en tant que valeur au filterCell soutenir.

Encore une fois, rendons le nouveau composant.

src/App.jsx

import "./App.css";
import RecipesTable from "./components/RecipesTable.jsx";
import RecipesGridWithColumnFilters from "./components/RecipesGridWithColumnFilters.jsx";
import RecipesGridWithCustomCellFilter from "./components/RecipesGridWithCustomCellFilter.jsx";

function App() {
  return (
    <div className="App">
      <h1>KendoReact Data Grid Filtering</h1>
      {}
      {}
      <h2>Grid with custom column cell filter</h2>
      <RecipesGridWithCustomCellFilter />
    </div>
  );
}

export default App;

Voici à quoi ça ressemble.

Filtre de plage de colonnes personnalisé

Quelques colonnes utilisent maintenant un filtre de plage personnalisé avec des entrées min et max. C’est ainsi qu’un filtre personnalisé peut être ajouté.

Filtres du menu des colonnes

Jusqu’à présent, nous avons expliqué comment ajouter des filtres de colonne par défaut et personnalisés. Cependant, tous les filtres sont visibles immédiatement et affichés pour chaque colonne.

Ne serait-il pas agréable de masquer les filtres et de les afficher uniquement lorsqu’un utilisateur souhaite réellement ajouter un filtre ? Ceci peut être réalisé en fournissant un composant à la colonne columnMenu soutenir. Au lieu d’afficher les filtres dans la deuxième ligne sous les en-têtes de tableau, les filtres seront masqués dans une fenêtre contextuelle qui peut être affichée en cliquant sur un bouton de menu.

Voici comment nous pouvons mettre cela en œuvre. Commençons par créer un composant appelé ColumnMenu qui fournira deux composants—ColumnMenu et ColumnMenuCheckboxFilter. Ces deux composants de rendu fournis par le @progress/kendo-react-grid emballer.

src/components/ColumnMenu.jsx

import {
  GridColumnMenuFilter,
  GridColumnMenuCheckboxFilter,
} from "@progress/kendo-react-grid";
import recipes from "../assets/recipes.json";

export const ColumnMenu = props => {
  return (
    <div>
      <GridColumnMenuFilter {...props} expanded={true} />
    </div>
  );
};

export const ColumnMenuCheckboxFilter = props => {
  return (
    <div>
      <GridColumnMenuCheckboxFilter {...props} data={recipes} expanded={true} />
    </div>
  );
};

Ensuite, nous pouvons utiliser les composants que nous venons de créer pour ajouter de nouveaux filtres.

src/components/RecipesGridWithColumnMenuFilters.jsx

import { Grid, GridColumn as Column } from "@progress/kendo-react-grid";
import { filterBy } from "@progress/kendo-data-query";
import { useState } from "react";
import { ColumnMenu } from "./columnMenu";
import originalRecipes from "../assets/recipes.json";

const recipes = originalRecipes.slice(0, 100);
const initialFilter = {
  logic: "and",
  filters: [
    {
      field: "recipe",
      operator: "contains",
      value: "Chicken",
    },
  ],
};

export const RecipesGridWithColumnMenuFilters = () => {
  const [filter, setFilter] = useState(initialFilter);
  return (
    <Grid
      style={{
        height: "420px",
      }}
      data={filterBy(recipes, filter)}
      pageSize={20}
      filter={filter}
      onFilterChange={e => setFilter(e.filter)}
    >
      <Column
        field="recipe"
        title="Recipe"
        width="250px"
        columnMenu={ColumnMenu}
      />
      <Column
        field="numIngredients"
        title="Ingredients"
        width="180px"
        filter="numeric"
        columnMenu={ColumnMenu}
      />
      <Column
        field="cuisine"
        title="Cuisine"
        width="180px"
        columnMenu={ColumnMenu}
      />
      <Column
        field="course"
        title="Course"
        width="180px"
        columnMenu={ColumnMenu}
      />
      <Column
        field="servings"
        title="Servings"
        width="180px"
        filter="numeric"
        columnMenu={ColumnMenu}
      />
      <Column
        field="cookTime"
        title="Cooking Time"
        width="180px"
        filter="numeric"
        format="{0} mins"
        columnMenu={ColumnMenu}
      />
      <Column
        field="prepTime"
        title="Prep Time"
        width="180px"
        filter="numeric"
        format="{0} mins"
        columnMenu={ColumnMenu}
      />
      <Column
        field="totalTime"
        title="Total Time"
        width="180px"
        filter="numeric"
        format="{0} mins"
        columnMenu={ColumnMenu}
      />
    </Grid>
  );
};

export default RecipesGridWithColumnMenuFilters;

Enfin, ajoutez le RecipesGridWithColumnMenuFilters composant à la App.jsx déposer.

src/App.jsx

import "./App.css";
import RecipesTable from "./components/RecipesTable.jsx";
import RecipesGridWithColumnFilters from "./components/RecipesGridWithColumnFilters.jsx";
import RecipesGridWithCustomCellFilter from "./components/RecipesGridWithCustomCellFilter.jsx";
import RecipesGridWithColumnMenuFilters from "./components/RecipesGridWithColumnMenuFilters";

function App() {
  return (
    <div className="App">
      <h1>KendoReact Data Grid Filtering</h1>
      {}
      {}
      {}
      <h2>Grid with column menu filters</h2>
      <RecipesGridWithColumnMenuFilters />
    </div>
  );
}

export default App;

Le GIF ci-dessous montre à quoi ressemblent les filtres.

Filtre de menu de colonne

Le ColumnMenu filtre permet le filtrage de texte, tandis que ColumnMenuCheckboxFilter fournit toutes les options disponibles sous forme de cases à cocher, et les utilisateurs peuvent choisir celles qu’ils souhaitent voir.

Résumé

Dans cet article, nous avons exploré la fonctionnalité de filtrage de la grille KendoReact, qui vous permet de filtrer, trier et paginer facilement de grands ensembles de données dans vos applications React.

Nous avons couvert les bases du filtrage des colonnes et comment ajouter nos propres filtres personnalisés. Grâce à ces connaissances, vous devriez être en mesure de créer des grilles de données puissantes et efficaces qui répondent aux exigences de votre application.




Source link