2.8 - Filtrage

Écrit par Neil Deakin. Traduit par Alain B. (18/09/2005).
Page originale : http://developer.mozilla.org/en/docs/XUL:Template_Guide:Filtering xulplanet.com

Attention : Ce tutoriel est ancien, incomplet, et n'est pas mis à jour. Il ne contient pas toutes les nouveautés du système de template de Gecko 1.9 / Firefox 3.0 qui est largement simplifié et permet d'utiliser sqlite ou xml comme source de données. Aussi est-il préférable d'aller consulter la version anglaise sur developer.mozilla.org.

Ajustement des conditions

Parfois, vous pouvez vouloir modifier les conditions ultérieurement. Par exemple, l'utilisateur peut choisir une valeur dans une liste, et les résultats du gabarit devront être filtrés à partir de cette valeur. Il suffit de modifier les noeuds DOM à l'intérieur des conditions et de reconstruire le gabarit. Par exemple, pour appliquer un filtre, vous pouvez ajouter un nouvel élément triple. Pour enlever le filtre, ce triple devra être supprimé. Supposons que nous ayons attribué un id cond sur la balise conditions.

function applyFilter(country)
{
  var cond = document.getElementById("cond");
  var triple = document.getElementById("filterTriple");
  if (country) {
    if (!triple) {
      triple = document.createElement("triple");
      triple.id = "filterTriple";
      triple.setAttribute("subject", "?photo");
      triple.setAttribute("predicate", "http://www.daml.org/2001/09/countries/iso-3166-ont#Country");
    }
    triple.setAttribute("object", country);
    cond.appendChild(triple);
  }
  else if (triple) {
    cond.removeChild(triple);
  }
  document.getElementById("photosList").builder.rebuild();
}

L'argument 'country' de la fonction applyFilter contient la valeur du filtre. Si cette valeur est définie, nous ajoutons un filtre, autrement il est supprimé. Le code est particulièrement direct. Un nouvel élément triple est créé et l'attribut object est défini avec la valeur servant de filtre. Par exemple, le triplet résultant d'un filtre sur les Pays bas serait :

<triple subject="?photo"
        predicate="http://www.daml.org/2001/09/countries/iso-3166-ont#Country"
        object="http://www.daml.org/2001/09/countries/iso#NL"/>

Ce triplet est ajouté aux conditions. Un identifiant id est attribué au triplet afin de pouvoir le retrouver si un filtre différent est appliqué. Naturellement, un seul filtre est appliqué à la fois, donc nous pouvons réutiliser le même triplet pour chaque filtre. Pour supprimer le filtre, nous devons simplement ôter le triplet des conditions. Cet exemple n'ajoute qu'un seul triplet, mais vous pouvez en ajouter d'autres, ou bien même des éléments member. Dès lors qu'un triplet ou un membre est ajouté ou supprimé, le gabarit doit être reconstruit en appelant la méthode rebuild. Cette méthode supprimera tout le contenu généré existant, effacera toutes les informations internes appartenant aux résultats, et redémarrera comme si le gabarit venait tout juste d'être examiné pour la première fois. Le gabarit sera analysé de nouveau et les données seront examinées pour de nouveaux résultats.

Vous pouvez voir l'exemple complet de cette action. Un menu déroulant permet à l'utilisateur de sélectionner soit un pays spécifique, ou soit l'affichage de toutes les photos. Lorsque le choix est effectué, la fonction applyFilter telle que montrée ci-dessus, est appelée et le contenu du gabarit est reconstruit selon le filtre désiré qui a été appliqué.

Dans cet exemple, le menu déroulant est écrit "en dur" pour contenir les items que nous savons être dans la source de données. Par la suite, nous verrons comment générer également cette liste en utilisant un gabarit.

Générer un menu avec des filtres

Les gabarits peuvent être utilisés pour générer n'importe quel type de contenu. Habituellement, un gabarit est utilisé pour générer les items d'un menu, d'une liste de choix ou d'un arbre. La syntaxe est la même quelque soit le type de contenu devant être créé. Dans le précédent exemple, nous avions codé "en dur" un menu déroulant avec la liste des pays, mais nous aurions pu générer cette liste à partir de la source de données. La même source de données peut être utilisée à la fois pour la liste des photos et le menu déroulant. Même si la même source de données est utilisée, elle ne sera chargée qu'une seule fois et les deux gabarits seront informés lorsque les données sont chargées.

Nous devrons ajouter quelques informations à la source de données afin de spécifier la liste des pays disponibles. Il y a deux possibilités. Premièrement, un Seq séparé peut être ajouté pour lister les pays. Deuxièmement, nous pouvons utiliser un type RDF pour spécifier les pays. Ensuite, il nous suffit de rechercher toutes les ressources ayant le type Country. Nous utiliserons cette méthode ici puisque nous avons déjà vu des exemples de la génération de contenu depuis un conteneur.

Un type RDF peut être assigné à un noeud par l'emploi du prédicat http://www.w3.org/1999/02/22-rdf-syntax-ns#type défini vers une ressource de ce type. En RDF/XML, une syntaxe raccourcie permet de remplacer la balise Description avec le type. Nous allons ajouter les deux pays dans la source de données, après s'être assuré que l'espace de nommage a été déclaré dans la balise RDF racine :

<nso:Country about="http://www.daml.org/2001/09/countries/iso#IT"
             dc:title="Italy"/>
<nso:Country about="http://www.daml.org/2001/09/countries/iso#NL"
             dc:title="Netherlands"/>

Le type de ces deux ressources, après complétion de l'espace de nommage (non montré ici), sera http://www.daml.org/2001/09/countries/country-ont#Country. Les triplets RDF résultants pour le premier pays seront :

http://www.daml.org/2001/09/countries/iso#IT
  -> http://www.w3.org/1999/02/22-rdf-syntax-ns#type
  -> http://www.daml.org/2001/09/countries/country-ont#Country
http://www.daml.org/2001/09/countries/iso#IT
  -> http://purl.org/dc/elements/1.1/title
  -> Italie

Le type ressemble à tous ceux des autres triplets dans la source de données, donc aucune syntaxe spéciale n'est requise pour naviguer dans celle-ci. Il suffit simplement d'utiliser le prédicat adéquat pour rechercher tous les pays. On peut se demander comment doit être défini l'attribut ref ou le point de départ puisque les pays n'ont pas de conteneur. En fait, le type servira de point de départ.

<menulist datasources="template-guide-photos4.rdf"
          ref="http://www.daml.org/2001/09/countries/country-ont#Country">

Souvenez vous que la seule nécessité est d'avoir une ressource comme point de départ, quelque soit cette ressource. Les conditions auront besoin de parcourir les arcs pointant vers les ressources de type. Puisque les arcs pointent vers le type, nous devons déterminer la source ou le sujet du triplet. Regardez une nouvelle fois les triplets RDF obtenus ci-avant si ce n'est pas clair. Le sommet initial est http://www.daml.org/2001/09/countries/country-ont#Country. Nous devons parcourir les données selon le prédicat 'type' pour trouver les pays individuellement. Un second triplet est utilisé pour obtenir le nom du pays.

<conditions>
  <content uri="?start"/>
  <triple subject="?country"
          predicate="http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
          object="?start"/>
  <triple subject="?country"
          predicate="http://purl.org/dc/elements/1.1/title"
          object="?countrytitle"/>
</conditions>

Le corps d'action devra ensuite générer un menuitem pour chaque résultat. Il devra également inclure un élément menupopup autour de ces items. Comme un seul menupopup devra être généré, il devra être placé en dehors de l'élément ayant l'attribut uri. Seul le contenu à partir de l'élément ayant l'attribut uri et ceux qu'il contient seront dupliqués pour chaque résultat. Les éléments en dehors ne le seront pas.

<action>
  <menupopup>
    <menuitem uri="?country" label="?countrytitle" value="?country"/>
  </menupopup>
</action>

Le résultat sera deux menuitem générés, un pour chaque pays, à l'intérieur d'un menupopup. L'attribut value reçoit la variable ?country afin que la fonction applyFilter puisse facilement se servir de cette valeur lors du filtrage. L'exemple complet en montre le fonctionnement.

Notez qu'à cause d'un bogue avec la génération des listes de menu dans les gabarits alors que la source de données n'est pas encore chargée, vous devez charger l'exemple une deuxième fois pour qu'il fonctionne. Le problème affecte seulement l'élément menulist. Plusieurs solutions peuvent être utilisées dans ce simple exemple. Tout d'abord, vous pouvez déplacer l'élément menupopup en dehors du gabarit et de lui affecter l'attribut datasources à la place de l'élément menulist. Cela fonctionnera dans cet exemple simple, mais aura l'inconvénient que le constructeur ne générera paresseusement le contenu que lorsque le menu déroulant sera ouvert. Une autre méthode consisterait à reconstruire le gabarit dès que les données ont été chargées.

Ensuite, nous verrons comment ajouter le choix de tous les pays au menu, cette indication ne figurant pas dans la source de données.


Mozilla® est une marque déposée de la fondation Mozilla.
Mozilla.org™, Firefox™, Thunderbird™, Mozilla Suite™ et XUL™ sont des marques de la fondation Mozilla.