Composant visuel intermediaire qui affiche un champ de recherche DSFR et filtre les données en amont avant de les redistribuer aux composants en aval.

Visuel et intermediaire : Ce composant affiche un champ de recherche ET redistribue les données filtrees aux composants en aval via le systeme d'événements. Il se combine naturellement avec dsfr-data-facets.

Position dans le pipeline

dsfr-data-source → dsfr-data-normalize → dsfr-data-search → dsfr-data-facets → dsfr-data-display / dsfr-data-list

La recherche reduit le jeu de données, les facettes affinent ensuite. Les compteurs de facettes se recalculent dynamiquement.

Cas d'usage

Attributs

AttributTypeDéfautDescription
idString-Requis. Identifiant de la sortie (données filtrees).
sourceString""ID de la source de données a ecouter
fieldsString""Champs sur lesquels rechercher (virgule-séparés). Vide = tous les champs
placeholderStringRechercher\u2026Placeholder du champ de saisie
labelStringRechercherLabel du champ (accessible)
debounceNumber300Délai en ms avant déclenchement du filtre après la dernière frappe
min-lengthNumber0Nombre minimum de caractères avant déclenchement
highlightBooleanfalseAjoute un champ _highlight a chaque record avec les termes trouves marques en <mark>
operatorSearchOperatorcontainsMode de recherche : contains, starts, words
sr-labelBooleanfalseSi true, le label est en sr-only (visuellement masque, accessible)
countBooleanfalseAffiche un compteur de résultats sous le champ (compte serveur meta.total en server-search), séparateur de milliers français (#728). Ce compteur reste visible dès qu'une donnée a circulé ; seule sa nature de région live dépend de la chaîne aval (#654). Tant que l'amont attend un filtre (require-where), il cède la place au message d'attente : annoncer « 0 résultats » avant toute requête laisserait croire à une page vide.
count-labelString""Nom compté par le compteur de count, à la place de « résultat » : count-label="établissement" affiche « 12 345 établissements ». Une forme seule prend un « s » au pluriel ; pour un pluriel irrégulier, donner les deux formes séparées par une barre verticale : count-label="cheval|chevaux", count-label="prix|prix".
url-search-paramString""Nom du paramètre d'URL à lire comme terme de recherche initial. Vide = désactivé
url-syncBooleanfalseSynchronise l'URL quand l'utilisateur tape (replaceState)
server-searchBooleanfalseActive le mode recherche serveur. Au lieu de filtrer localement, envoie une commande { where } au source upstream (dsfr-data-query server-side) qui re-fetche les données avec le filtre search.
search-templateString""Template pour la recherche serveur. {q} est remplacé par le terme de recherche, {fields} par les champs de fields séparés par | (#1026) — la grammaire colon des champs multiples, un OU entre eux. Si vide et server-search activé, lu depuis l'adaptateur de la source amont (gabarit par défaut de chaque adaptateur déclarant serverSearch : recherche plein texte native, ou {fields}:contains:{q} traduit en OU entre colonnes — la casse et les accents suivent l'API ; table des capacités d'ARCHITECTURE). Ex. personnalisés : '{q} IN nom', 'nom|commune:contains:{q}'. Une clause que l'adaptateur ne sait pas transmettre (caractère que son API ne sait pas porter), ou une source sans adaptateur, retombe sur une recherche locale, signalée en console.
contextString""Id du dsfr-data-context auquel s'enregistrer (#678, ADR-104) : la recherche devient un filtre contains du contexte sur le champ UNIQUE de fields (un filtre de contexte porte un seul champ ; le OU entre champs, a|b:contains:q #1026, reste propre à server-search). Le contexte diffuse à ses cibles et porte l'URL (url-sync et url-search-param sont ignorés — le paramètre est nommé d'après le champ, ou via url-param-map du contexte). Le contexte peut être déclaré après la recherche dans la page. Vide = comportement autonome.
idle-messageStringIDLE_MESSAGE_DEFAULTMessage rendu quand l'amont attend un filtre (require-where, #690). Distinct de « aucune donnée » : aucune requête n'a été faite. Vide, le libellé par défaut est utilisé.

Recherche serveur sur plusieurs colonnes (#1026)

En server-search, le gabarit search-template accepte {fields} : il devient les champs de fields séparés par |, la grammaire des champs multiples (nom|commune:contains:martin, un OU entre les champs). C'est le gabarit par défaut sur Tabular, {fields}:contains:{q}, traduit en or=(nom__contains.martin,commune__contains.martin) : le compteur lit le total serveur, juste sur tout le jeu et non sur les lignes chargées. fields est alors obligatoire. Côté serveur, contains est insensible à la casse mais sensible aux accents ; la recherche locale, elle, les ignore — on ne l'aligne pas, pour ne pas rendre deux compteurs différents selon le chemin. Un terme que l'API ne sait pas transmettre (, . ( ) " & sur Tabular) retombe sur une recherche dans le navigateur, sur les seules lignes chargées, et un avertissement le dit.

En attente d'un filtre

Quand l'amont porte require-where, aucune requête n'est partie : le compteur de count céderait la place à un « 0 résultat » trompeur. Il est remplacé par le texte de idle-message (« Choisissez un filtre pour afficher les données » par défaut), qui dit que rien n'a encore été demandé. Le champ de saisie, lui, reste utilisable — c'est souvent lui qui pose le premier filtre et débloque la source. Le mécanisme est décrit sur dsfr-data-source.

Modes de recherche :
contains (défaut) : sous-chaine insensible a la casse et aux accents.
starts : chaque mot du champ doit commencer par le terme.
words : tous les mots saisis doivent etre presents (dans n'importe quel champ, n'importe quel ordre). Le plus utile pour la recherche multi-criteres.

Exemple 1 : recherche simple + tableau

Recherche textuelle sur les champs Produit, Marque et Catégorie. Le tableau se filtre en temps reel avec un compteur de resultats.

Code

<dsfr-data-search id="searched" source="clean"
  fields="Produit, Marque, Catégorie"
  placeholder="Produit, marque ou catégorie..."
  operator="words"
  min-length="2"
  count>
</dsfr-data-search>

<dsfr-data-list source="searched"
  columns="Produit, Catégorie, Marque, Date"
  sort="Date:desc"
  pagination="10">
</dsfr-data-list>

Exemple 2 : recherche + facettes + cartes

La recherche et les facettes se combinent. La recherche reduit le jeu de données, les facettes affinent. Les cartes affichent les resultats.

Code

<dsfr-data-search id="searched" source="clean"
  fields="Produit, Marque, Catégorie"
  placeholder="Rechercher un produit rappele..."
  operator="words"
  count>
</dsfr-data-search>

<dsfr-data-facets id="filtered" source="searched"
  fields="Catégorie, Marque"
  labels="Catégorie:Catégorie | Marque:Marque"
  max-values="6">
</dsfr-data-facets>

<dsfr-data-display source="filtered" cols="3" pagination="9">
  <template>
    <div class="fr-card">
      <div class="fr-card__body">
        <div class="fr-card__content">
          <h3 class="fr-card__title">{{Produit}}</h3>
          <p class="fr-card__desc">{{Marque}}</p>
        </div>
        <div class="fr-card__footer">
          <p class="fr-badge fr-badge--sm">{{Catégorie}}</p>
        </div>
      </div>
    </div>
  </template>
</dsfr-data-display>

Exemple 3 : recherche + KPI + graphique

Les KPI et le graphique se recalculent en temps reel selon la recherche. Rechercher par nom d'entreprise, departement ou region.

Code

<dsfr-data-search id="searched" source="clean"
  fields="Entreprise, Region, Departement"
  placeholder="Entreprise, region, departement..."
  operator="words"
  count>
</dsfr-data-search>

<dsfr-data-kpi source="searched" value="count" label="Projets" color-token="bleu"></dsfr-data-kpi>
<dsfr-data-kpi source="searched" value="montant_investissement:sum" label="Investissement" format="euro"></dsfr-data-kpi>

<dsfr-data-query id="stats" source="searched"
  group-by="Region"
  aggregate="nombre_beneficiaires:sum:Beneficiaires"
  order-by="Beneficiaires:desc"
  limit="10">
</dsfr-data-query>

<dsfr-data-chart source="stats" type="bar"
  label-field="Region"
  value-field="Beneficiaires"
  selected-palette="categorical">
</dsfr-data-chart>

Événements

En plus de la ré-émission des données filtrées sur le data-bridge sous son propre id (dsfr-data-loaded / -loading / -error), le composant émet un événement custom à chaque recherche effective :

ÉvénementdetailDescription
dsfr-data-search-change { sourceId, term, count } Émis sur document (bubbles, composed) après application d'un terme : sourceId = id du composant, term = terme recherché, count = nombre de résultats.
document.addEventListener('dsfr-data-search-change', (e) => {
  const { sourceId, term, count } = e.detail;
  console.log(`${count} résultats pour « ${term} » (${sourceId})`);
});