xulfr.org

10.4 Ajout de propriétés

Écrit par Neil Deakin. Traduit par Nadine Henry (13/08/2004).
Page originale : http://www.xulplanet.com/tutorials/xultu/xblprops.html xulplanet.com

Nous allons voir comment ajouter des propriétés personnalisées aux éléments XBL.

L'interface XBL

Javascript et le DOM fournissent un moyen pour obtenir et définir les propriétés des éléments. Avec XBL, vous pouvez définir vos propres propriétés pour les éléments que vous créez. Vous pouvez aussi ajouter des méthodes qui peuvent être appelées. De cette façon, tout ce dont vous avez besoin est d'obtenir une référence à l'élément (en utilisant GetElementById ou une fonction similaire) et ainsi obtenir ou modifier les propriétés additionnelles et appeler leurs méthodes.

Il y a trois types d'items que vous pouvez ajouter. Les champs sont utilisés pour contenir une valeur simple. Les propriétés peuvent aussi être utilisées pour contenir une valeur mais elles peuvent aussi contenir du code pouvant être exécuté lorsqu'une tentative est faite pour récupérer ou modifier la valeur. Les méthodes sont des fonctions qui peuvent être exécutées.

Chacun des trois est défini dans un élément implementation, qui doit être un fils de l'élément de liaison binding. À l'intérieur de la balise implementation, vous définissez pour chacun d'eux un élément field, un élément property et un élément method selon ce que vous voulez. La syntaxe générale est comme suit :


<binding id="element-name">
  <content>
    -- le contenu vient ici --
  </content>
  <implementation>
    <field name="field-name-1"/>

    <field name="field-name-2"/>
    <field name="field-name-3"/>

    <property name="property-name-1"/>
    <property name="property-name-2"/>
    <property name="property-name-3"/>
    .
    .
    .
    <method name="method-name-1/>

      -- le contenu vient ici --
    </method>
    .
    .
    .
  </implementation>
</binding>

Les champs

Chaque champ est défini en utilisant l'élément field. Souvent, les champs correspondraient à un attribut placé sur l'élément comme label ou disabled, mais ils ne le devraient pas.

L'attribut name de field est utilisé pour indiquer le nom du champ. Vous pouvez utiliser le nom à partir d'un script pour obtenir et déterminer une valeur. L'exemple ci-dessous crée un bouton qui génère et stocke un nombre aléatoire. Vous pouvez rechercher ce même nombre plusieurs fois en obtenant la propriété number du bouton. Le plus gros du travail ici est fait par les gestionnaires oncommand. Plus tard, nous verrons comment transformer cela en XBL.


XUL:

<box id="random-box" class="randomizer"/>

<button label="Generate"
           oncommand="document.getElementById('random-box').number=Math.random();"/>

<button label="Show"
           oncommand="alert(document.getElementById('random-box').number)"/>

XBL:

<binding id="randomizer">
  <implementation>
    <field name="number"/>
  </implementation>

</binding>

Un champ number qui stocke le nombre aléatoire a été défini dans la liaison. Les deux boutons spéciaux définissent et obtiennent la valeur de ce champ. La syntaxe est très similaire pour obtenir et définir les propriétés des éléments HTML. Dans cet exemple, aucun contenu n'a été placé à l'intérieur que ce soit la boîte XUL ou sa définition dans XBL, ce qui est parfaitement valide.

Cet exemple n'est pas tout à fait correct car il n'y a pas de valeur par défaut assignée dans le champ. Pour ce faire, ajoutez la valeur par défaut dans le contenu de la balise field. Par exemple :


<field name="number">
  25
</field>

Cela affectera la valeur 25 comme valeur par défaut du champ "number". En fait, vous pouvez à la place insérer un script au sein de la balise field qui calculera la valeur par défaut. Cela pourrait être nécessaire si la valeur a besoin d'être calculée. Par exemple, le champ suivant donne une valeur par défaut égale à l'heure courante :


<field name="currentTime">
  new Date().getTime();
</field>

Les propriétés

Parfois vous pourriez vouloir valider la donnée qui est assignée à la propriété. Ou bien, pour pourriez souhaiter que la valeur soit calculée dynamiquement lorsqu'on le lui demande. Par exemple, si vous souhaitez une propriété qui prenne en compte l'heure courante, vous voudriez que sa valeur soit générée au besoin. Dans ces cas là, vous avez besoin d'utiliser une balise property à la place de la balise field. Sa syntaxe est similaire mais comporte des particularités supplémentaires.

Vous pouvez utiliser les attributs onget et onset pour que le code soit exécuté lorsque la propriété est récupérée ou modifiée. Ajoutez les à l'élément property et définissez leur valeur dans un script qui au choix obtient ou déclare la valeur de la propriété.

Par exemple, vous pourriez assigner un script à la valeur de onget pour calculer le temps courant. Chaque fois qu'un script tente d'accéder à la valeur de la propriété, le script onget sera appelé pour rechercher la valeur. Le script devrait retourner la valeur qui devrait être traitée comme étant la valeur de la propriété.

Le gestionnaire onset est similaire mais est appelé chaque fois qu'un script tente d'assigner une nouvelle valeur à la propriété. Ce script devrait stocker la valeur quelque part, ou la valider. Par exemple, certaines propriétés pourraient juste être capables de stocker des nombres. Tenter d'assigner des caractères alphabétiques à ce genre de propriétés ne devrait pas fonctionner.


<property name="size"
          onget="return 77;"
          onset="alert('Changed to:'+val); return val;"/>

Cette propriété retournera toujours 77 lorsqu'elle sera récupérée. Lorsqu'elle sera affectée, une boîte de dialogue s'affichera et indiquera la valeur à assigner à la propriété. La variable spéciale val contient cette valeur. Utilisez-la pour la valider ou la stocker. La propriété onset devrait aussi retourner la nouvelle valeur.

Ce qui suit décrit ce qui se passe dans un cas typique :

Il y a deux éléments, l'un appelé "banana" et l'autre "orange". Chacun d'eux a une propriété spécifique appelée 'size'. Lorsque la ligne de script suivante est exécutée :


banana.size = orange.size;
  1. Le script onget est appelé pour la propriété "size" de "orange". Il calcule la valeur et la retourne.
  2. Le gestionnaire onset de la propriété "size" de "banana" est appelé. Ce script utilise la valeur passée dans la variable val et l'assigne à la propriété "size" de "banana" de façon quelconque.

Notez que contrairement à un champ, une propriété ne contient pas de valeur. Tenter de définir une propriété qui n'a pas de gestionnaire onset provoquera une erreur. Vous utiliserez souvent un champ séparé pour prendre la valeur actuelle de la propriété. Il est aussi commun que les propriétés correspondent à un attribut dans l'élément défini XBL. L'exemple suivant fait correspondre une propriété à un attribut sur un élément.


<property name="size"
          onget="return this.getAttribute('size');"
          onset="return this.setAttribute('size',val);"
/>

Chaque fois qu'un script tente d'obtenir la valeur de la propriété, elle est récupérée d'un attribut de même nom de l'élément XUL. Chaque fois qu'un script tente de définir la valeur de la propriété, elle est affectée à l'attribut 'size' de l'élément. C'est pratique parce qu'ainsi vous pouvez modifier la propriété ou l'attribut et tous les deux auront la même valeur.

Vous pouvez utiliser une syntaxe alternative pour les attributs onget et onset ce qui est utile si les scripts sont plus longs. Vous pouvez remplacer l'attribut onget par l'élément fils nommé getter. Similairement, vous pouvez remplacer l'attribut onset par l'élément setter. L'exemple ci-dessous le montre :


<property name="number">
  <getter>
    return this.getAttribute('number');
  </getter>
  <setter>

    var v=parseInt(val);
    if (!isNaN(v)) return this.setAttribute('number',''+v);
    else return this.getAttribute('number');"
  </setter>
</property>

La propriété dans cet exemple sera juste capable d'avoir des valeurs d'entiers. Si d'autres caractères sont entrés, ils sont supprimés. S'il n'y a aucun chiffre, la valeur n'est pas changée. Cela est fait dans le code au sein de l'élément setter. La valeur réelle de la propriété est stockée dans l'attribut number.

Vous pouvez utilisez l'une ou l'autre syntaxe pour créer des gestionnaires d'obtention et d'affectation.

Vous pouvez avoir un champ ou une propriété en lecture seule en ajoutant un attribut readonly à la balise field ou à la balise property et en le déclarant à true. Tenter d'affecter une valeur à une propriété en lecture seule échouera.


La prochaine section montre comment ajouter des méthodes aux éléments définis en XBL.