Fermer

novembre 9, 2021

Trier, filtrer et regrouper avec la grille KendoReact


Le filtrage, le tri et le regroupement sont trois outils importants que vous pouvez offrir à vos utilisateurs pour les aider à analyser les données présentées dans une grille de données KendoReact. Apprenez à mettre en œuvre ces configurations, ainsi que les cas d'utilisation pour lesquels chacune est la plus adaptée !

Lorsque vous avez une grille avec beaucoup de données, le filtrage, le tri et le regroupement sont des fonctionnalités clés pour vos utilisateurs. capable de donner un sens à toutes ces informations. Si vous voulez juste afficher vos données d'une manière facilement lisible, alors un bon vieux HTML

est probablement tout ce dont vous avez besoin, mais si vous regardez des composants de grille, c'est parce que vous savez déjà que vous avez un complexe cas d'utilisation qui nécessite plus que ce qu'une table de base a à offrir. La grille de données KendoReact est un composant extrêmement puissant pour afficher et organiser les données, mais vous devrez d'abord le configurer afin de permettre à vos utilisateurs de tirer le meilleur parti des fonctionnalités disponibles. Heureusement, c'est pourquoi nous sommes ici aujourd'hui, alors commençons !

Dans cette situation, nous partons du principe que votre grille de données est déjà installée, placée dans votre application et remplie de données. Si ce n'est pas encore le cas, consultez nos documents pour obtenir des conseils sur la mise en routeet revenez ici lorsque vous serez prêt à approfondir vos connaissances !

Ou, si vous recherchez simplement un exemple avec lequel jouer, vous pouvez cloner et jouer avec notre application kendo-demoLKARS Menu System—vous pouvez trouver le repo ici. Il convient de noter que cette application a été fortement thématique pour ressembler au système de menu du vaisseau Star Trek, donc les couleurs et les polices seront différentes de celles de nos documents. Si vous souhaitez appliquer un thème personnalisé à vos composants KendoReact, consultez cette procédure pas à pasainsi que ce blog sur l'utilisation de SASS pour le style de composant personnalisé.

Nous allons ajouter et configurer diverses fonctionnalités de filtrage et de tri pour le composant Grid utilisé dans la section Astrométrie de notre application, afin que les membres d'équipage de notre faux vaisseau puissent facilement examiner tous les objets d'intérêt astrologiques récemment enregistrés. Alors, sans plus tarder, mettons le cap sur l'expertise Data Grid, et… engageons-nous !

Notre configuration actuelle

La version de base de la grille de données dans votre JSX ressemblera à ceci :

<Grid
  style={{ height :  "90%" }}
  données={astrodonnées}
>
  <Colonne field="nom" titre="Nom" />
  <Colonne  field="astronomicalObjectType" title="Object Type" />
  <Column field= "location.name" title="Location"/>
</Grid>

Grille d'astrométrie - colonnes pour le nom, type d'objet, emplacement

Dans notre composant Grid, j'ai spécifié une hauteur de 90% (afin que la grille défile au lieu de déborder) et l'ai remplie avec les données d'un .json que j'ai importé. J'ai également spécifié que la grille devrait avoir trois colonnes : Nom, Type d'objet et Emplacement. Sinon, cette grille ne semble pas trop différente de votre table moyenne.

Et c'est bien, je suppose, mais l'un de mes membres d'équipage fictifs doit rédiger un rapport sur les planètes de classe M récemment rencontrées. À l'heure actuelle, elle devrait faire défiler tout le contenu de la grille pour le faire, mais ce serait beaucoup plus facile si elle pouvait trier la colonne Type d'objet de sorte que toutes les planètes de type M-Class soient ensemble. Et hé, nous avons la technologie, alors allons-y !

Activation du tri dans la grille de données KendoReact

  1. La première étape consiste à définir la propriété sortable sur notre composant Grid sur true.

     <Grille
       style={{ hauteur: "90%" }}
       data={astroData}
         triable={true}
     >
       <Colonne field="nom" titre="Nom" />
       <Colonne  champ="astronomicalObjectType" title="Object Type" />
       <Colonne champ= "location.name" title="Location"/>
     </Grid>
    
  2. Ensuite, nous voulons mettre en place un hook qui gérera notre gestion d'état pour l'état actuel de la grille triée. En haut de notre composant, j'ai ajouté un nouveau hook qui définit sort comme état de tri actuel, setSort comme ce que nous appellerons lorsque l'utilisateur mettra à jour la méthode de tri , et initialSort comme configuration par défaut pour le tri au chargement.

     const [currentSort, setSort] = React.useState(initialSort);
    

    J'ai défini initialSort pour trier la colonne Nom par ordre alphabétique croissant.

     const initialSort = [
       {
     champ : "nom",
     dir : "asc",
       },
     ] ;
    
  3. Une fois que c'est prêt, ajoutons-le à notre composant. Nous utiliserons la propriété sort pour indiquer à la grille que nous voulons qu'elle soit triée selon le sort que nous avons défini ci-dessus. Et nous utiliserons la prop onSortChange pour mettre à jour l'état chaque fois que l'utilisateur modifie la méthode de tri.

     <Grille
       style={{ hauteur: "90%" }}
       data={astroData}
         sortable={true}
         sort={sort}
       onSortChange= {(e) => {setSort(e.sort)}}
     >
       <Colonne field="nom" titre="Nom" />
       <Colonne[19659011]field="astronomicalObjectType" title="Object Type" />
       <Colonne field="location.name" title="Location"/>
     </Grid>
    
  4. Maintenant, si nous regardons notre application, nous pouvons voir que lorsque nous cliquons sur les en-têtes de colonne, nous obtenons une flèche pour indiquer l'état du tri actuel … cependant, les données elles-mêmes ne sont pas encore triées. C'est parce que nous devons en fait, eh bien, faire le tri !

    Sort by name" title="Sort by name"/></p data-recalc-dims=

    Pour ce faire, nous devrons importer { orderBy } de " @progress/kendo-data-query" ainsi que mettre à jour notre prop data pour appeler orderBy et transmettre nos données de base avec notre sort .

Notre code final pour le composant Grid ressemble donc à ceci !

<Grid
style={{ hauteur : "90%" }}
  data={orderBy(astroData, sort)}
  triable={vrai}
  tri={tri}
  onSortChange={(e) => {setSort(e.sort)}}
>
  <Champ de colonne="nom" titre="Nom" />
  <Champ de colonne="astronomicalObjectType" title="Object Type" />
  <Champ de colonne="location.name" title="Location"/>

Et maintenant, notre Ensign peut rapidement trier toutes les planètes de type M-Class vers le haut et compiler sa liste. Attention à l'équipage du pont, cette fille est sur le point d'être promue !

sort_demo" data-displaymode="Original" title="sort_demo"/></p data-recalc-dims=

Configuration des options de tri

Il existe également plusieurs façons de personnaliser la manière dont votre grille peut être triée. Vous pouvez désactivez le déclassement des colonnes en définissant sortable.allowUnsort sur falseet vous pouvez autoriser l'utilisateur à trier plusieurs colonnes en même temps en définissant sortable.mode sur multiple. Notre sortable.mode acceptera soit multiple ou single comme options, et la valeur par défaut est single.

<Grille
  style={{ hauteur : "90%" }}
  data={orderBy(astroData, sort)}
  triable={{
        allowUnsort : false,
        mode : "multiple"
    }}
  tri={tri}
  onSortChange={(e) => {setSort(e.sort)}}
>
  <Champ de colonne="nom" titre="Nom" />
  <Champ de colonne="astronomicalObjectType" title="Object Type" />
  <Champ de colonne="location.name" title="Location"/>

Lorsque les utilisateurs peuvent trier plusieurs colonnes en même temps, un nombre apparaît dans l'interface utilisateur de la colonne pour indiquer l'ordre de préférence de tri.

Tri par colonne de nom priorité décroissante 1, tri par type d'objet priorité ascendante 3, tri par emplacement priorité ascendante 2

Activation du filtrage pour la grille de données KendoReact

À l'heure actuelle, notre Ensign peut trier la grille afin de déplacer toutes les planètes de classe M en haut de la liste, mais il semble que ce dont elle a vraiment besoin n'est pas de trier, mais plutôt de filtrer le contenu de la grille afin de supprimer chaque objet astrologique qui est ]pas une planète de classe M. Voici comment procéder :

  1. Tout d'abord, nous allons ajouter une propriété filterable à notre composant Grid et la définir sur true.

    La colonne Nom est affichée dans l'ordre croissant. Le champ de filtre, sous l'en-tête de colonne, est vide. Le bouton Filtre à côté est ouvert au menu avec les options : contient, ne contient pas, est égal à, n'est pas égal à, commence par, se termine par, est nul

    Dès que vous faites cela, vous verrez qu'il y a une nouvelle section en haut de chaque colonne de votre grille de données, avec un champ pour la saisie utilisateur et un bouton pour modifier le type de filtre en fonction de la façon dont ils souhaitent structurer leur filtre. Vous remarquerez également que cela ne fonctionne pas encore, c'est parce que nous devons toujours l'accrocher à notre état et gérer les modifications des choix de l'utilisateur.

  2. Pour ce faire, nous devrons créer un hook qui nous permet de définir le filtre en fonction du choix de l'utilisateur :

     const [filtersetFilter ] = React.useState(initialFilter);
    

    Ensuite, nous définirons ce initialFilter pour renvoyer l'état de filtre souhaité lors du chargement du composant. Dans ce cas, je l'ai défini comme vide :

     const initialFilter = {
     logique : "et",
     filtres : [
         {
     champ : "nom",
    Opérateur  : "contient",
     valeur : "",
         },
       ],
     } ;
    
  3. Ensuite, nous allons le connecter à notre composant Grid en définissant les accessoires filter et onFilterChange. Nous allons définir filter sur notre variable filter et utiliser onFilterChange pour appeler setFilter pour mettre à jour l'état chaque fois que l'utilisateur modifie le filtrage méthode.

     <Grille
           style={{
             hauteur : "420px",
           }}
           data={filterBy(sampleProducts, filter)}
           filtrable={vrai}
           filtre={filtre}
           onFilterChange={(e) => setFilter(e.filter)}
         >
    
  4. Maintenant, lorsque nous revenons sur notre application, nous pouvons tester l'entrée du filtre et voir le contenu de la grille commencer immédiatement à filtrer les données au fur et à mesure que nous tapons. Désormais, notre coéquipier peut filtrer rapidement et facilement la grille pour ne renvoyer que les planètes de classe M qu'elle recherchait.

    filter_demo avec la saisie par l'utilisateur dans la colonne de type d'objet M_Class_planet et le filtre fonctionne comme les types d'utilisateur

Configuration des options de filtrage

Le paramètre par défaut de l'interface utilisateur de filtrage de grille consiste à ajouter ce champ de saisie utilisateur juste en dessous de l'en-tête de colonne. Cependant, si vous essayez de conserver autant d'espace que possible dans votre interface utilisateur, vous pouvez choisir une autre disposition qui imbrique les entrées de filtrage dans un menu déroulant. Bien qu'il soit intéressant de noter que cette méthode modifie légèrement l'UX, en ce sens qu'elle ne filtrera plus au fur et à mesure que l'utilisateur tape.

Filtre alternatif - À côté de la colonne Nom se trouve l'icône à trois points verticaux. Il a été cliqué et le filtre est défini sur : contient : III. Le bouton de filtre a été cliqué et la colonne affiche les noms de planète avec III, tels que Rubican III

Afin de configurer le menu, nous voulons importer GridColumnMenuFilter à partir de @progress/kendo-react-grid et utilisez-le pour créer un nouveau composant. Nous appellerons ce composant ColumnMenuet il devrait ressembler à ceci :

import { Grid, GridColumn as Column, GridColumnMenuFilter }  de  "@progress/kendo-react-grid" ;

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

Ensuite, nous ajusterons notre composant Grid pour ajouter le nouveau menu à chaque colonne où nous voulons qu'il apparaisse :

<Grid
  style={{  hauteur : "90%" }}
  data={filterBy(astroData, filter)}
  filter={filter}
  onFilterChange={(e) => setFilter(e.filter)}
>
  <Column columnMenu={ColumnMenu} field="nom" titre="Nom"  />
  <Column columnMenu={ColumnMenu} field="astronomicalObjectType" titre="Type d'objet" />
  <Column columnMenu={ColumnMenu} field="location.name"[19659011]title="Location"/>
</Grid>

Parfois, vous savez à l'avance comment vos utilisateurs devront filtrer les informations dans votre Grille. Dans ces cas, vous pouvez améliorer l'UX de votre application en supprimant l'étape de sélection de filtre du processus et en faisant en sorte que la grille n'affiche que le type de filtre correspondant à cette colonne. Par exemple, si vous avez une colonne affichant le nombre de fois qu'un objet astronomique particulier a été rencontré, vous pouvez spécifier dans le composant Colonne filter={"numeric"} , et la cellule de filtre sera mise à jour pour spécifier l'entrée numérique.

<Grille
  style={{ hauteur: "90%" }}
  données={filterBy(astroData, filter)}
  filter={filter}
  onFilterChange={(e) => setFilter(e.filter)}
>
  <Colonne field="nom" titre="Nom" />
  <Colonne[19659011]field="astronomicalObjectType" title="Object Type" />
  <Column field="location.name" title="Location"/>
    <Column field="rencontres"[19659011]title="Rencontres" filter={"numeric"}/>
</Grid>

numeric_demo montrant le filtre pertinent dans la colonne Rencontres avec un filtre numérique incrémenté/décrémenté

Enfin, si vous savez que vos utilisateurs voudront filtrer de manière spécifique (comme notre Enseigne qui toujours filtrer à partir d'une liste de types prédéfinis), vous pouvez optimiser votre interface utilisateur pour rendre ce processus clair r à vos utilisateurs en utilisant la propriété filterCell dans le composant enfant. Cela vous permettra de remplacer l'interface utilisateur de filtrage par défaut sous l'en-tête de catégorie par un contenu entièrement personnalisé : tout ce que vous aimez.

Pour ce faire, vous utiliserez la même approche que ci-dessus, où vous créez un nouveau composant pour gérer la demande de filtrage. Mais alors, au lieu de passer cela dans columnMenuvous utiliserez plutôt filterCell. Notez que votre composant personnalisé devra gérer toutes les entrées utilisateur (événements onClicketc.) car il s'agit d'un ajout à la fonctionnalité standard du composant KendoReact.

<Column filterCell={MyCustomFilter} field="nom" titre="Nom"  />

Activation du regroupement pour la grille de données KendoReact

Pour la troisième fois, nous sommes approchés par ce coéquipier. « S'il vous plaît », disent-ils, « Je sais avant de dire que je voulais trier, puis filtrer, mais ce dont j'ai vraiment besoin, c'est d'un moyen de regrouper les données par type tout en étant capable de tout voir ! » Eh bien, pourquoi ne l'avez-vous pas dit en premier lieu? Bien sûr, nous pouvons le faire avec la grille de données KendoReact !

  1. Tout d'abord, nous allons définir la propriété groupable du composant Grid sur true

     <Grid
       style={ { hauteur : "90%" }}
       data={filterBy(astroData, filter)}
       groupable={true}
       onFilterChange={(e) => setFilter(e.filter)}
     >
       <Colonne field="nom" titre="Nom" />
       <Colonne[19659011]field="astronomicalObjectType" title="Object Type" />
       <Colonne field="location.name" title="Location"/>
     </Grid>
    

    Une fois cela fait, vous verra le changement reflété dans notre interface utilisateur, avec une nouvelle ligne au-dessus des en-têtes de colonne avec des instructions sur la façon de regrouper. Cela ne fonctionnera pas encore, mais réglons cela !

     L'instruction de regroupement dit de "Faites glisser un en-tête de colonne et déposez-le ici pour le grouper par cette colonne

  2. Pour que ce glisser-déposer fonctionne, nous devrons configurer notre gestionnaire onGroupChange pour mettre à jour l'état. Cela suit le même schéma que les approches de filtrage et de tri, vous le connaissez donc probablement déjà ! Créons donc notre hook avec group , setGroup et initialGroup. Dans ce cas, je vais configurer mon initialGroup pour commencer par regrouper le contenu de la grille par type d'objet.

     const initialGroup = {
          champ : "astronomicalObjectType",
       } ;
    
     const [groupsetGroup] = React.useState(initialGroup);
    
  3. Maintenant, nous allons utiliser ceux avec onGroupChange pour mettre à jour les paramètres de groupe lorsque l'utilisateur fait glisser et dépose ces en-têtes de colonne.

     <Grille
         style={{ hauteur: "90%" }}
         data={groupBy(astroData, group)}
         groupable={true}
         group={group}
         onGroupChange={(e) => setGroup(e.group)}
       >
         <Colonne field="nom" titre="Nom" />
         <Colonne[19659011]field="astronomicalObjectType" title="Object Type" />
         <Column field="location.name" title="Location"/>
       </Grid>
     </div>
    

    group_demo montre que l'utilisateur fait glisser l'en-tête 'Location' vers les instructions de regroupement. Lorsqu'il est déposé, il apparaît avec sa flèche ascendante et une option X pour le supprimer. Les données de la grille se regroupent par emplacement. Ensuite, l'utilisateur fait glisser et dépose l'en-tête 'Object Type', qui est ajouté à côté de Location. Les données sont affichées regroupées d'abord par emplacement, puis en sous-groupes de type d'objet. Ensuite, l'utilisateur supprime le regroupement d'emplacements, de sorte que les données sont regroupées uniquement par type d'objet.

Comme vous pouvez le voir dans l'exemple de gif, toutes les colonnes peuvent être regroupées plusieurs fois. L'ordre dans lequel les colonnes sont regroupées est basé sur l'ordre dans lequel l'utilisateur les fait glisser dans la section d'en-tête. Vous pouvez empêcher n'importe quelle colonne d'être regroupée en définissant grouped={false} dans le composant Column. Lorsque cela est défini, l'utilisateur ne pourra pas faire glisser et déposer cette colonne spécifique, mais pourra toujours se regrouper en fonction des autres.

Combiner le tri, le filtrage et le regroupement dans la grille de données KendoReact

Parfois, nous avons besoin de plus d'une méthode d'organisation activée sur notre grille ensemble. Lorsque c'est le cas, certaines modifications doivent être apportées au code afin de gérer ces multiples formes de traitement.

  1. Pour commencer, nous devrons changer les pièces spécifiques au processus que nous utilisions. Au lieu de sort/setSort ou filter/setFiltervous voudrez utiliser le plus générique dataState et setDataState.

     const [dataState, setDataState] = React.useState(initialDataState);
    
  2. Si vous importiez auparavant sortBy ou filterByvous devrez le remplacer par processune méthode plus générale qui peut gérer la mise à jour des trois types d'organisation.

     import { process } de "@progress/kendo-data-query" ;
    
  3. Nous voudrons également créer un autre hook, en utilisant dataResult et setDataResult. Ce hook remplace les méthodes sortBy ou filterBy que nous utilisions avec onSortChange et onFilterChange. Désormais, chaque fois que l'état des données change de quelque manière que ce soit (par tri, filtrage ou regroupement), nous utilisons la méthode process pour le gérer et transmettre notre ensemble de données avec le dataState actuel , qui contient les configurations actuelles pour tout tri, filtrage ou regroupement.

     const [dataResult, setDataResult] = React.useState(
       process(astroData, dataState)
     );
    
     const dataStateChange = (event) => {
       setDataResult(process(astroData, event.dataState));
       setDataState(event.dataState);
     } ;
    
  4. Vous devrez également maintenant mettre à jour vos variables initialSort ou initialFilter pour les combiner dans un nouveau initialDataState. La syntaxe restera la même, nous les mettons simplement tous dans un seul gros objet.

     const initialDataState = {
     trier : [
           {
     champ : "nom",
     dir : "asc",
           },
         ],
     logique : "et",
     filtres : [
           {
     champ : "astronomicalObjectType",
    Opérateur  : "contient",
     valeur : "M_CLASS",
           },
         ],
       }
    
  5. Maintenant, examinons notre composant Grid. Nous devrions toujours avoir sortable , filterable et groupable réglés sur les configurations que vous souhaitez, mais nous devrions remplacer le filter et triez les propriétés avec les data plus génériques et définissez-les sur {dataResult}{...dataState}.

     <Grid
       style={{ hauteur : "90%" }}
       data={dataResult}{...dataStateChange}
       triable={{
         mode : 'multiple'
       }}
       filtrable={vrai}
         groupable={vrai}
       onDataStateChange={dataStateChange}
     >
    

Et voilà ! Désormais, votre grille de données peut gérer n'importe quelle combinaison de paramètres de tri, de filtrage et de regroupement saisis par vos utilisateurs. Mais comment décidez-vous quelle combinaison de ces fonctionnalités convient à votre application ?

Comment choisir les éléments à activer pour ma grille de données ? Dois-je simplement tout activer ?

Dans ce dernier exemple, nous avons parcouru trois fonctionnalités très puissantes : le tri, le filtrage et le regroupement—et les avons toutes activées. Cependant, cette approche globale n'est pas toujours la meilleure UX pour votre application.

Bien qu'il puisse être tentant de voir une liste de fonctionnalités comme celle-ci et de dire : « Allumez tout !! » En fait, je vous encourage à activer uniquement les fonctionnalités qui seront les plus bénéfiques pour vos utilisateurs et à laisser de côté celles que vous pensez être moins utilisées. L'activation de chaque fonctionnalité (et chaque configuration de chaque fonctionnalité) peut être une expérience écrasante pour vos utilisateurs et pourrait créer une interface utilisateur complexe. Des grilles comme celle-ci, alors laissez-leur absolument toute liberté ! Mais si la majorité de vos utilisateurs ne sont pas à ce niveau, vous pouvez améliorer leur expérience en réfléchissant à la façon dont vous configurez votre composant Grid.

Trier est idéal pour les situations où vos utilisateurs auront besoin de comparer vos données ou de les voir toutes d'une manière spécifiquement organisée. Par exemple, pouvoir comparer les prix de différentes offres en triant les coûts du plus bas au plus élevé, ou en regardant tous vos employés classés par ordre alphabétique par nom. C'est un excellent moyen d'organiser des données qui sont déjà toutes dans une catégorie similaire.

Le filtrage est préférable lorsque vos utilisateurs n'ont besoin de voir qu'un certain sous-ensemble de vos données, et pas toutes à la fois. Par exemple, afficher uniquement les produits d'une certaine catégorie ou uniquement les employés avec un titre spécifique. C'est bien lorsque vous avez plusieurs sous-ensembles de données inclus dans votre grille, mais vos utilisateurs n'auront pas besoin de les voir tous en même temps. Cela peut être particulièrement puissant lorsqu'il est combiné avec le tri, permettant à vos utilisateurs de filtrer jusqu'à un sous-ensemble spécifique de données, puis de l'organiser de manière progressive.

Grouping doit être utilisé lorsque vos utilisateurs ont besoin de voir l'intégralité des données, mais divisées en catégories plus petites. C'est une sorte de mélange entre les fonctionnalités de filtrage et de tri, d'un point de vue UX. Il permet à vos utilisateurs de créer ces mêmes sous-ensembles que le filtrage, mais sans supprimer les données de la vue comme le fait le filtrage. Cela permet à vos utilisateurs de toujours voir les autres catégories à des fins de comparaison, mais d'une manière plus différenciée visuellement qu'une liste triée peut offrir. C'est particulièrement utile lorsque vous avez beaucoup de données, mais tout doit rester dans la vue. Le diviser en catégories plus petites facilite l'analyse pour vos utilisateurs, mais garantit que l'intégralité des données leur est toujours disponible dans une seule vue.

Je vous recommande de prendre un peu de temps pour réfléchir à ce que vos utilisateurs feront avec les données de votre grille. Quels sont leurs objectifs ? Quelles conclusions essaient-ils de tirer? Quels problèmes essaient-ils de résoudre ? Quels types de connexions tentent-ils d'établir ? Les réponses à ces questions peuvent vous aider à déterminer si le tri, le filtrage, le regroupement ou une combinaison de ceux-ci conviennent le mieux à votre application. afin que vous puissiez utiliser la même grille de données KendoReact dans plusieurs contextes et scénarios différents au sein de votre application, mais cela ne signifie pas nécessairement que vos utilisateurs bénéficieront également d'une solution tout-en-un dans l'interface utilisateur. Lorsque vous combinez vos connaissances et votre expertise sur votre propre base d'utilisateurs avec la puissance de la grille de données KendoReact, les possibilités sont vraiment infinies !




Source link