9 L'interface d'utilisateur de XForms

Ce chapitre couvre les fonctionnalités de XForms pour la combinaison des commandes de formulaire dans les interfaces d'utilisateur.

9.1 Le module Groupe de XForms

Toutes les commandes de formulaire définies dans 8 Les commandes de formulaire sont traitées comme des unités individuelles pour les besoins de la disposition visuelle, par exemple, dans le traitement XHTML. L'agrégation des commandes de formulaire au balisage défini dans ce chapitre donne une sémantique des relations entre les commandes des interfaces d'utilisateur ; une telle connaissance peut se révéler utile pour fournir une interface d'utilisateur cohérente aux petits appareils. Par exemple, si l'interface d'utilisateur doit se répartir sur plusieurs écrans, les commandes apparaissant à l'intérieur de la même agrégation seraient normalement restituées sur le même écran ou la même page. Les éléments et attributs compris dans ce module sont :

Élément Attributs Modèle de contenu minimal
group Communs, Communs I.U., Liaison de nœud simple (optionnel) label?, ((Commandes de formulaire)|group|switch|repeat|Communs I.U.)*

9.1.1 L'élément group

L'élément group sert de conteneur pour définir une hiérarchie de commandes de formulaire. Les groupes peuvent s'imbriquer pour créer des hiérarchies complexes. Les propriétés d'élément de modèle qui s'appliquent aux commandes de formulaire s'appliquent également à l'élément group, et elles ont priorité sur celles appliquées aux membres individuels du groupe. Un groupe est considéré non pertinent si, et seulement si, la liaison de nœud simple se résoud en un ensemble de nœuds vide ou en un nœud non pertinent.

Attributs communs : Communs, Communs I.U., Liaison de nœud simple (optionnel)

Remarque :

Quand aucune propriété d'élément de modèle ne s'applique à l'expression de liaison de l'élément group, on peut l'assimiler à une commodité de création pour les expressions XPath relatives utilisées par les commandes de formulaire au sein du groupe.

Quand des propriétés d'élément de modèle s'appliquent, alors elles concernent toutes les commandes de formulaire dans l'élément group. Cela signifie, par exemple, que si un groupe est lié à un nœud de données d'instance non pertinent, tous les sous-éléments commandes de formulaire seront également traitées comme non pertinents.

Si un élément group n'est pas pertinent, alors la démarche de restitution employée pour indiquer la non-pertinence s'applique au contenu entier du groupe.

L'élément optionnel label revêt une signification particulière lorsqu'il apparaît comme premier sous-élément de l'élément group : il représente une étiquette pour le groupe entier.

Exemple :

Exemple : Regroupement de commandes apparentées
<group ref="adresse">
  <label>Adresse de livraison</label>
  <input ref="ligne_1">
    <label>Adresse ligne 1</label>
  </input>
  <input ref="ligne_2">
    <label>Adresse ligne 2</label>
  </input>
  <input ref="code_postal">
    <label>Code postal</label>
  </input>
</group>

Le fait de fixer le focus d'entrée sur un groupe revient à fixer le focus sur la première commande de formulaire de ce groupe, dans l'ordre de navigation.

9.2 Le module Commutation de XForms

Cette section définit une structure de bascule qui permet la création d'interfaces d'utilisateur, où l'interface d'utilisateur peut varier en fonction des actions et des événements des utilisateurs. Les éléments et attributs compris dans ce module sont :

Élément Attributs Modèle de contenu minimal
switch Communs, Communs I.U., Liaison de nœud simple (optionnel) case+
case Communs, selected (xsd:boolean) label?, ((Commandes de formulaire)|group|switch|repeat)*
toggle Communs, case (xsd:IDREF) EMPTY

9.2.1 L'élément switch

Cet élément contient un ou plusieurs éléments case dont l'un est restitué à un moment donné. La non-pertinence d'un élément switch se détermine comme pour l'élément group et s'applique de même au contenu entier.

Remarque :

Cela se distingue du traitement de l'élément relevant de XForms (cf. 6.1.4 La propriété relevant), lequel se fonde sur l'état courant du modèle XForms. Comme exemple, les parties d'un questionnaire ayant trait au véhicule d'un utilisateur pourront seulement devenir pertinentes lorsque l'utilisateur aura répondu par l'affirmative à la question Possédez-vous une voiture ?.

Attributs communs : Communs, Communs I.U., Liaison de nœud simple (optionnel)

Exemple :

Exemple : switch
<switch>
  <case id="in" selected="true">
    <input ref="votre_nom">
      <label>Veuillez indiquer votre nom</label>
      <toggle ev:event="DOMActivate" case="out"/>
    </input>
  </case>
  <case id="out" selected="false">
    <html:p>Bonjour <output ref="votre_nom" />
      <trigger id="boutonEditer">
        <label>Éditer</label>
        <toggle ev:event="DOMActivate" case="in"/>
      </trigger>
    </html:p>
  </case>
</switch>

Dans cet exemple, la partie de l'interface d'utilisateur contenue dans le premier élément case sera initialement affichée. Elle invite l'utilisateur à donner son nom ; son remplissage suivi de l'activation de la commande, par exemple, en pressant la touche d'entrée, entraîne un basculement vers l'autre élément case, avec une restitution en lecture seule de l'élément output. L'activation ensuite de l'élément trigger, étiqueté Éditer, provoquera un retour au cas original.

9.2.2 L'élément case

Cet élément englobe un balisage à restituer conditionnellement. L'attribut selected qui détermine l'état sélectionné peut se manipuler par programme via le DOM, ou de manière déclarative via l'action XForms toggle détermine l'état sélectionné initial.

Attributs communs : Communs

Attributs particuliers :

selected

Statut de sélection optionnel du cas. La valeur implicite est "false".

Si plusieurs éléments case dans un élément switch sont marqués selected="true", alors le premier élément case reste sélectionné et tous les autres sont désélectionnés. Si aucun n'est sélectionné, alors le premier le devient.

9.2.3 L'élément toggle

Cette action XForms sélectionne un cas possible à partir d'une liste exclusive d'alternatives dans un élément switch.

Cette action ajuste tous les attributs selected sur les éléments case affectés afin de refléter le nouvel état, et opère ensuite ce qui suit :

Cette action ajuste tous les états sélectionnés (pas les valeurs d'attribut) sur les éléments case affectés afin de refléter le nouvel état de l'élément switch contenant l'élément case identifié, et opère ensuite ce qui suit :

  1. La distribution d'un événement xforms-deselect à l'élément case actuellement sélectionné ;

  2. La distribution d'un événement xform-select à l'élément case à sélectionner.

Attributs communs : Communs, Événements

Attributs particuliers :

case

Une référence obligatoire à une section case dans la structure conditionnelle.

9.3 Le module Répétition de XForms

La spécification XForms permet de définir des structures de répétition tels que de multiples articles dans un ordre d'achat. Dans la définition du modèle XForms, ces collections de niveau supérieur sont assemblées à partir de blocs de construction de base ; de même, cette section définit la structure d'interface d'utilisateur repeat qui peut se lier à des structures de données telles que les listes et les collections. Les éléments et attributs compris dans ce module sont :

Élément Attributs Modèle de contenu minimal
repeat Communs, Communs I.U., Liaison d'ensemble de nœuds, startindex (xsd:positiveInteger), number (xsd:nonNegativeInteger) ((Commandes de formulaire)|group|repeat)*
itemset Communs, Liaison d'ensemble de nœuds label, (value|copy), (Communs I.U.)*
copy Communs, Liaison de nœud simple (optionnel) EMPTY
insert Communs, Événements, Liaison d'ensemble de nœuds, at (expression-XPath), position ("before"|"after") EMPTY
delete Communs, Événements, Liaison d'ensemble de nœuds, at (expression-XPath) EMPTY
setindex Communs, Événements, repeat (xsd:IDREF), index (expression-XPath) EMPTY
(divers) [repeat-nodeset, repeat-bind, repeat-model] (Attributs de liaison d'ensemble de nœuds), repeat-startindex (xsd:positiveInteger), repeat-number (xsd:nonNegativeInteger) non disponible

9.3.1 L'élément repeat

Cet élément définit une application d'interface d'utilisateur sur une collection homogène sélectionnée par des attributs de liaison d'ensemble de nœuds. Cet ensemble de nœuds doit se composer de nœuds de sous-éléments contigüs, ayant le même nom local et le même nom d'espace de nommage que le nœud d'un parent commun. Le comportement de l'élément repeat en ce qui concerne les ensembles de nœuds non homogènes n'est pas défini.

Par exemple :

Exemple : Chariot d'achat
<repeat nodeset="/cart/items/item">

  <input ref="." .../><html:br/>

    <input ref="." ...>
     <label>...</label>
  </input>
  <html:br/>

</repeat>

Attributs communs : Communs, Communs I.U., Liaison d'ensemble de nœuds

Attributs particuliers :

startindex

Valeur initiale optionnelle de l'index de répétition commençant à "1". La valeur implicite est "1".

number

Indication optionnelle, destinée au processeur XForms, du nombre des éléments de la collection à afficher.

Cet élément opère sur une collection homogène en liant les commandes de l'interface d'utilisateur encapsulées à chaque élément de la collection. Les attributs de cet élément définissent combien de membres de la collection sont présentés à l'utilisateur à un instant donné. On peut utiliser les actions XForms insert, delete et setindex pour agir sur la collection (cf. 10 Les actions XForms). Une autre manière de voir le traitement de la répétition, en ne tenant pas compte des interactions particulières de l'interface d'utilisateur, consiste à dérouler celle-ci. L'exemple précédent est similaire à celui qui suit (en supposant quatre éléments item dans l'ensemble de nœuds renvoyé) :

Exemple : Répétition déroulée
<!-- répétition déroulée -->
  <input ref="/cart/items/item[1]" .../><html:br/>
  <input ref="/cart/items/item[2]" .../><html:br/>
  <input ref="/cart/items/item[3]" .../><html:br/>
  <input ref="/cart/items/item[4]" .../><html:br/>

  <group ref="/cart/items/item[1]"><input ref="." .../><html:br/></group>
  <group ref="/cart/items/item[2]"><input ref="." .../><html:br/></group>
  <group ref="/cart/items/item[3]"><input ref="." .../><html:br/></group>
  <group ref="/cart/items/item[4]"><input ref="." .../><html:br/></group>
Exemple : Collection homogène
<model>
  <instance>
    <my:lignes>
      <my:ligne name="a">
        <my:prix>3.00</my:prix>
      </my:ligne>
      <my:ligne name="b">
        <my:prix>32.25</my:prix>
      </my:ligne>
      <my:ligne name="c">
        <my:prix>132.99</my:prix>
      </my:ligne>
      </my:lignes>
  </instance>
</model>
  ...
<repeat id="ensemble_lignes" nodeset="/my:lignes/my:ligne">
  <input ref="my:prix">
    <label>Élément de ligne</label>
  </input>
  <input ref="@name">
    <label>Nom</label>
  </input>
</repeat>
        
<trigger>
  <label>Insérer un nouvel élément après celui courant</label>
  <action ev:event="DOMActivate">
    <insert nodeset="/my:lignes/my:ligne" at="index('ensemble_lignes')"
      position="after"/>
    <setvalue ref="/my:lignes/my:ligne[index('ensemble_lignes')]/@name"/>
    <setvalue ref="/my:lignes/my:ligne[index('ensemble_lignes')]/prix">0.00</setvalue>
  </action>  
</trigger>
          
<trigger>
  <label>Supprimer l'élément courant</label>
  <delete ev:event="activate" nodeset="/my:lignes/my:ligne"
    at="index('ensemble_lignes')"/>
</trigger>

9.3.2 La création des structures de répétition via des attributs

L'élément repeat permet la création d'interfaces d'utilisateur pour peupler les structures de répétition. Lorsqu'on utilise XForms dans des langages hôtes comme XHTML, il est souvent nécessaire de créer des structures de répétition à l'intérieur d'autres structures comme l'élément table. Ainsi on pourrait vouloir utiliser un élément repeat dans un élément table afin de créer les rangées d'un tableau, chacune des rangées se liant à un membre distinct d'une collection homogène. Dans la mesure où html:table n'admet pas (et n'admettra probablement jamais) d'éléments xforms:repeat comme sous-éléments, il faut alors une autre syntaxe.

Exemple : Tableaux et structures de répétition
<table>
  <repeat nodeset="...">
    <tr>
      <td>...</td>
      ...
    </tr>
  </repeat>
</table>

Plus généralement, on peut avoir besoin d'intégrer un comportement de répétition dans des langages hôtes à des endroits où le modèle de contenu du langage hôtel n'offre pas, ou ne peut pas offrir, de crochets d'extension appropriés via une modularisation. Le langage XForms 1.0 s'en accomode en définissant une autre syntaxe, fonctionnellement équivalente à l'élément repeat, qui utilise les attributs suivants :

  • repeat-model
  • repeat-bind
  • repeat-nodeset
  • repeat-startindex
  • repeat-number

Ces attributs équivalent aux attributs de même nom de l'élément repeat, sans le préfixe repeat-. Un langage hôte peut inclure ces attributs aux endroits appropriés afin de permettre des structures de répétition. Par exemple, une version XHTML en serait :

Exemple : Tableaux et structures de répétition
<html:table xforms:repeat-nodeset="...">
  <html:tr>
    <html:td><xforms:output ref="..."/></html:td>
  </html:tr>
</html:table>

... laquelle pourrait être validée contre un schéma XHTML, contenant le module Répétition de XForms, qui serait configuré de manière adéquate. Remarquez que ce sont les sous-éléments de l'élément avec des attributs repeat qui seront répétés.

On devrait simplement considérer ce mécanisme comme une transformation syntaxique, c'est-à-dire que la sémantique du traitement de répétition ne subit aucun changement. En outre, pour faire comprendre qu'il s'agit d'une simple transformation syntaxique, on peut voir l'élément repeat comme contenant un élément group anonyme qui enveloppe le contenu de l'élément repeat. Ainsi ce qui suit :

<repeat ...>
  ...
</repeat>

... équivaut à :

<repeat ...>
  <group ref=".">...</group>
</repeat>

... qui équivaut à :

<group repeat-...>
  ...
</group>

Remarque :

Une conséquence de ces équivalences est que la liaison de nœud simple exprimée sur le groupe implique une applicabilité de la non-pertinence.

De plus, lorsqu'on utilise l'action XForms setindex, un attribut repeat de type IDREF peut pointer vers n'importe quel élément porteur d'un attribut de répétition. De la même façon, lorsqu'on utilise la fonction index() sur une structure de répétition créée via les attributs repeat-..., l'attribut id de cet élément peut servir d'argument à la fonction index().

9.3.3 L'élément itemset

Cet élément permet la création de sélections dynamiques dans les commandes select et select1, pour lesquelles les choix disponibles se déterminent à l'exécution. L'ensemble de nœuds qui contient ces choix disponibles est défini par l'attribut nodeset. Comme avec l'élément repeat, cet ensemble de nœuds devrait se référer à une collection homogène. Les sous-éléments label et value définissent l'étiquette et les valeurs de stockage. Notez que l'effet produit par l'élément itemset à l'exécution est le même que celui produit en utilisant l'élément choices pour créer les choix disponibles statiques.

Attributs communs : Communs, Liaison d'ensemble de nœuds

Remarque :

Dès qu'un événement refresh est distribué, l'attribut nodeset est réévalué afin de mettre à jour la liste des choix disponibles.

L'exemple suivant montre un élément itemset, dans une commande select, qui définit une liste dynamique de parfums de glace :

Exemple : Choix dynamique de parfums de glace
<model id="cone">
  <instance>
    <my:glace>
      <my:commande/>
    </my:glace>
  </instance>
</model>
<model id="parfums">
  <instance>
    <my:parfums>
      <my:parfum type="v">
        <my:description>Vanille</my:description>
      </my:parfum>
      <my:parfum type="f">
        <my:description>Fraise</my:description>
      </my:parfum>
      <my:parfum type="c">
        <my:description>Chocolat</my:description>
      </my:parfum>
    </my:parfums>
  </instance>
</model>
<!-- balisage d'interaction avec l'utilisateur -->
<select model="cone" ref="my:commande">
  <label>Parfums</label>
  <itemset model="parfums" nodeset="/my:parfums/my:parfum">
    <label ref="my:description"/>
    <copy ref="my:description"/>
  </itemset>
</select>
          
<!-- Pour chacun des trois éléments sélectionnés,
      cet exemple produit des données d'instance comme
     <my:glace>
       <my:commande>
         <my:description>Vanille</my:description>
         <my:description>Fraise</my:description>
         <my:description>Chocolat</my:description>    
       </my:commande>
     </my:glace>
-->

9.3.4 L'élément copy

Structurellement, cet élément est similaire à celui décrit dans 8.2.3 L'élément value. L'élément copy en diffère par le fait qu'on ne peut l'utiliser que dans un élément itemset, et qu'il fonctionne avec des sous-arbres de donnée d'instance plutôt qu'avec des valeurs simples.

Attributs communs : Communs, Liaison de nœud simple (optionnel)

Lorsque qu'un élément item est sélectionné, les règles suivantes s'appliquent :

  • Le nœud cible, sélectionné par les attributs de liaison sur la commande de formulaire de liste, doit être un nœud d'élément, sinon il se produit une exception (cf. 4.5.1 L'événement xforms-binding-exception) ;

  • Le nœud d'élément associé à l'élément item, sélectionné par les attributs de liaision sur l'élément copy, est copié en profondeur en tant que sous-élément du nœud cible ;

  • Une reconstruction complète des dépendances de calcul a lieu.

Lorsqu'un élément item est désélectionné, les règles suivantes s'appliquent :

  • Le nœud cible, sélectionné par les attributs de liaison sur la commande de formulaire de liste, doit être un nœud d'élément, sinon il se produit une exception (cf. 4.5.1 L'événement xforms-binding-exception) ;

  • Le nœud du sous-élément associé à l'élément item, sélectionné par les attributs de liaison sur l'élément copy, est supprimé ;

  • Une reconstruction complète des dépendances de calcul se produit.

9.3.5 L'élément insert

Cette action sert à insérer de nouvelles entrées dans une collection homogène, par exemple, un ensemble d'articles dans un panier d'achat. Les attributs de l'action insert définissent l'insertion en fonction de la collection dans laquelle la nouvelle entrée doit s'insérer, et de l'emplacement dans cette collection où le nouveau nœud apparaîtra. Le nouveau nœud est créé par clonage du dernier membre de la collection homogène, lequel est défini par les données d'instance d'initialisation. Au cours de ce processus, les nœuds de type xsd:ID sont modifiés afin de rester des valeurs uniques dans les données d'instance.

Attributs communs : Communs, Événements, Liaison d'ensemble de nœuds

Attributs particuliers :

at

Une expression XPath obligatoire qui est évaluée pour déterminer l'emplacement de l'insertion.

position

Un sélecteur obligatoire (valeurs "before" et "after") du comportement d'insertion avant/après.

Les règles de traitement de l'élément insert sont les suivantes :

  1. La collection homogène à mettre à jour est déterminée par l'évaluation de l'attribut de liaison nodeset.

    La collection homogène à mettre à jour est déterminée par l'évaluation de la liaison de l'ensemble de nœuds. Si la collection est vide, l'action insert n'a aucu effet ;

  2. L'ensemble de nœuds des données d'instance initiales est localisé afin de déterminer le membre prototype de la collection. La liaison de l'ensemble de nœuds identifie une collection homogène dans les données d'instance. Le dernier membre de cette collection est cloné afin de produire le nœud qui sera inséré. Enfin, ce nœud nouvellement créé est inséré dans les données d'instances à l'emplacement défini par les attributs position et at.

    L'attribut at est évalué afin de déterminer l'index d'insertion (une valeur numérique qui est l'index dans l'ensemble de nœuds). Son évaluation a lieu dans l'ordre du document, avec pour nœud contextuel, le premier de la liaison de l'ensemble de nœuds, avec pour dimension contextuelle, la dimension de la liaison de l'ensemble de nœuds et pour valeur contextuelle de position, la valeur "1". L'attribut position définit si le nouveau nœud s'insère avant ("before") ou après ("after") cet index.

    Les règles de sélection de l'index sont les suivantes :

    1. La valeur de renvoi de l'expression XPath dans l'attribut at est traitée selon les règles de la fonction Xpath round(). Par exemple, le littéral "1.5" devient "2" et le littéral "chaîne" devient "NaN" ;

    2. Si le résultat est "NaN", l'insertion se produit à la fin de l'ensemble de nœuds ;

    3. Si l'index obtenu dépasse les limites valides de l'ensemble de nœuds, il est remplacé soit par la valeur "1", soit par la valeur de la dimension de l'ensemble de nœuds, selon celle qui est la plus proche.

  3. L'index de toute séquence, qui se répète, liée à la collection homogène dans laquelle le nœud aura été ajouté, est mis à jour afin de pointer vers le nœud nouvellement ajouté. Les index des collections de répétition imbriquées internes sont réinitialisés à "1" à la valeur de startindex ;

  4. Si l'insertion a réussi, alors l'événement xforms-insert est distribué.

Cette action aboutit à l'insertion des nœuds de donnée nouvellement créés dans les données d'instance XForms. Ces nœuds sont construits comme défini dans la section sur l'initialisation du modèle de traitement (cf. 4.2 Les événements d'initialisation. Par exemple, elle cause l'instanciation de l'interface d'utilisateur nécessaire pour peupler une nouvelle entrée dans la collection sous-jacente lorsqu'on l'utilise en conjonction avec des structures de répétition.

Remarque :

Si cette action est contenue dans un élément action, elle a un comportement particulier de mise à jour différé (voir 10.1.1 L'élément action).

On trouvera un exemple d'utilisation de l'élément insert avec une structure de répétition dans 9.3.1 L'élément repeat. Remarquez que l'action XForms setvalue peut s'utiliser en conjonction avec l'élément insert afin de fournir les valeurs initiales des nœuds nouvellement insérés.

9.3.6 L'élément delete

Cette action supprime des nœuds dans les données d'instance.

Attributs communs : Communs, Événements, Liaison d'ensemble de nœuds

Attributs particuliers :

at

Une expression XPath obligatoire qui est évaluée pour déterminer l'emplacement de l'insertion.

Les règles de traitement de l'élément delete sont les suivantes :

  1. La collection homogène à mettre à jour est déterminée par l'évaluation de l'attribut de liaison nodeset. Si la collection est vide, l'action delete n'a aucun effet ;

    La collection homogène à mettre à jour est déterminée par l'évaluation de la liaison de l'ensemble de nœuds. Si la collection est vide, l'action delete n'a aucu effet ;

  2. Le nème nœud d'élément est supprimé des données d'instance, où n représente le nombre renvoyé par l'évaluation de l'index de l'ensemble de nœuds, laquelle est définie dans 9.3.5 L'élément insert. S'il n'existe pas de nème nœud, l'opération est sans effet ;

  3. Après une suppression, l'index devrait pointer vers le même nœud qu'avant, sauf :

    • Quand le dernier élément restant de la collection est retiré, auquel cas la position de l'index revient à "0" ;

    • Quand l'index pointait vers le nœud supprimé, qui était le dernier élément de la collection, alors l'index pointera vers le nouveau dernier nœud de la collection ; les index des répétitions internes seront réinitialisés ;

    • Quand l'index pointait vers le nœud supprimé, qui n'était pas le dernier élément de la collection, alors la position de l'index reste inchangée ; les index des répétitions internes seront réinitialisés.

    Réinitialiser une répétition signifie changer l'index pour "0" s'il est vide, sinon pour "1" ;

  4. Si la suppression a réussi, l'événement xforms-delete est distribué.

Cette action aboutit à la suppression de nœuds dans les données d'instance.

Remarque :

Si cette action est contenue dans un élément action, elle a un comportement particulier de mise à jour différée (cf. 10.1.1 L'élément action).

On trouvera un exemple d'utilisation de l'élément delete avec une structure de répétition dans 9.3.1 L'élément repeat.

9.3.7 L'élément setindex

Cette action marque un élément particulier comme étant courant dans une séquence de répétition (dans l'élément repeat voir 9.3.1 L'élément repeat).

Attributs communs : Communs, Événements

Attributs particuliers :

repeat

Référence obligatoire à un élément de répétition.

index

Une expression XPath obligatoire évaluée comme un décalage, commençant à "1", dans la séquence.

Si l'index sélectionné est "0", ou inférieur, un événement xforms-scroll-first est distribué et l'index est fixé à "1". Si l'index sélectionné est supérieur à celui du dernier élément de répétition, un événement xforms-scroll-last est distribué et la valeur de l'index est fixée à celle de l'index de ce dernier élément. Si l'index est évalué à "Nan", l'action n'a aucun effet. Les index des collections de répétition imbriquées internes sont réinitialisés à "1" à la valeur de startindex. En conséquence de cette action, les structures de données des mises en œuvre pour le suivi des dépendances de calcul sont reconstruites ou mises à jour.

9.3.8 Le traitement des répétitions

Le balisage contenu dans le corps des éléments repeat définit l'interface d'utilisateur à générer pour chaque membre de la collection sous-jacente. Pendant l'initialisation de l'interface d'utilisateur (voir 4.2.2 L'événement xforms-model-construct-done), les étapes suivantes sont effectuées pour l'élément repeat :

  1. L'attribut nodeset est évalué afin de localiser la collection homogène sur laquelle doit opérer l'élément repeat ;

    La liaison de l'ensemble de nœuds est évaluée afin de localiser la collection homogène sur laquelle doit opérer l'élément repeat ;

  2. Les nœuds correspondants dans l'élément instance dans le document source sont localisés (ces nœuds fournissent les valeurs initiales et servent aussi d'instances prototypes pour la construction des membres de la collection de répétition) ;

  3. L'index de cette structure de répétition est initialisé à la valeur de l'attribut startindex. Si la valeur initiale de startindex est inférieure à "1", elle devient "1" par défaut. Si la valeur d'index est supérieure à l'ensemble de nœuds initial, alors elle devient celle de la dimension de l'ensemble de nœuds ;

  4. Le modèle de l'interface d'utilisateur défini dans l'élément repeat est lié à cette instance prototype. S'il y a une contradiction de type entre l'instance prototype et les restrictions de liaison des commandes d'interface d'utilisateur, une erreur est signalée et le traitement se termine ;

  5. L'interface d'utilisateur, telle qu'elle est définie par l'élément repeat, est générée pour le nombre requis de membres de la collection comme défini par les attributs sur l'élément repeat.

Le modèle de traitement des structures de répétition utilise un index qui pointe vers l'élément courant dans les données d'instance. On accède à cet index de répétition via la fonction XForms index() ( voir 7.8.5 La fonction index() et on la manipule via l'action XForms setindex (cf. 9.3.7 L'élément setindex). Cet index sert de point de référence aux opérations insert et delete. Notez que les commandes de formulaire XForms contenues dans l'élément repeat ne définissent pas explicitement l'index de l'entrée de collection qui est en cours de population. Ceci est délibéré afin de garder le processus de création et le modèle de traitement simples.

L'expression de liaison jointe à la séquence de répétition renvoie un ensemble de nœuds de la collection en cours de population, et non un nœud individuel. Dans le corps de l'élément repeat, les expressions de liaison sont évaluées par rapport au nœud de contexte du nœud déterminé par l'index. Le traitement des répétitions emploie des expressions XPath pour accéder à la collection sur laquelle l'élément repeat opère. Les données d'instance initiales produisent le membre prototype de la collection homogène, lequel sert à construire les membres de la collection homogène pendant l'initialisation de l'interface d'utilisateur (cf. 4.2.2 L'événement xforms-model-construct-done). Cette instance prototype sert également à l'action insert dans la création des nouveaux membres de la collection. Pour créer des collections homogènes, les données d'instance initiales doivent définir au moins un membre de la collection ; cette condition revient à imposer les données d'instance en plus d'un schéma, et la même justification s'applique.

Les commandes de formulaire apparaissant dant l'élément repeat doivent convenir à la population des éléments individuels de la collections. Une conséquence simple mais puissante : si le modèle XForms définit des collections imbriquées, alors une interface d'utilisateur correspondante peut imbriquer des éléments repeat.

9.3.9 Les répétitions imbriquées

Il est possible d'imbriquer des éléments de répétition afin de créer des interfaces d'utilisateur plus évoluées pour la création de données structurées. On trouvera dans G.2 La création de signets hiérarchiques avec XForms un exemple de formulaire utilisant des répétitions imbriquées pour créer des données hiérarchiques composant des signets dans des sections multiples. Notez que l'index d'une répétition interne commence toujours à "1". Prenons la déclaration insert qui fait partie de cet exemple :

Exemple : Index de répétition et répétitions imbriquées
<xforms:insert nodeset="/signets/section[index('repeterSections')]/signet"
               at="index('repeterSignets')"
               position="after"/>

La déclaration insert précédente sert à ajouter des nouvelles entrées de signet dans la section actuellement sélectionnée. La répétition interne (imbriquée) opère sur les signets dans cette section sélectionnée. L'index, renvoyé par la fonction XForms index(), de cette répétition interne commence à "1". De ce fait, après qu'une nouvelle section vide de signets a été créée et qu'elle est devenue courante, la première opération d'insertion de signet ajoute le signet nouvellement créé au début de la liste.

9.3.10 L'interaction avec l'interface d'utilisateur

L'élément repeat permet la liaison d'une interaction d'utilisateur à une collection homogène. Le nombre d'éléments affichés pourrait se trouver inférieur à la totalité de ceux disponibles dans la collection. Auquel cas, la représentation ne restituerait qu'une partie des éléments se répétant à un moment donné. Par exemple, une interface d'utilisateur graphique pourrait présenter un tableau défilant. L'élément courant indiqué par l'index de répétition devrait être disponible pour l'utilisateur à tout instant, par exemple, ne pas permettre qu'il défile hors de vue. Les actions énumérées dans 10 Les actions XForms peuvent être utilisées au sein de guetteurs d'événements afin de manipuler la collection homogène en cours de peuplement par défilement, insertion et suppression des entrées.

Notez que le balisage encapsulé par un élément repeat agit comme modèle pour l'interaction d'utilisateur présentée à l'utilisateur. Par conséquent, il n'est pas possible d'appeler des parties de l'interface d'utilisateur générée via des attributs idref créés de manière statique. Une conséquence nécessaire est que le langage XForms 1.0 ne définit pas le comportement d'une structure switch dans un élément repeat. Des versions futures de XForms pourront définir ce comportement en fonction des résultats de mise en œuvres et des retours des utilisateurs.