Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Utilisation de Data Islands XML dans Mozilla

 

Cet article est obsolète. S'il vous plaît voir le nouvel article en anglais.

Une fonctionnalité pratique d'Internet Explorer est la possibilité d'utiliser des îlots de données (Data islands, en anglais) pour lier des données aux contrôles HTML sur une page. Cette fonctionnalité n'est pas intégrée telle quelle dans Mozilla, mais on peut aisément imiter ce comportement pour créer des applications Web multi-navigateurs.

L'îlot de données basique que nous allons utiliser est un élément XML simple, soit lié à la page, soit codé explicitement dans celle-ci. Voici un exemple simple pour illustrer ceci :

<xml id="xmlDataIsland">
   <loaninfo>
       <borrower id="1">
           <firstname>Brian</firstname>
           <middlename>Ellis</middlename>
           <lastname>Johnson</lastname>
       </borrower>
   </loaninfo>
</xml>

Avec cet îlot de données, nous pouvons placer sur une page autant de contrôles que désirés en liant simplement l'îlot de données à ces contrôles à l'aide de JavaScript et du DOM.

Pour lier ceci, tout ce que nous avons besoin de faire est de confier le remplissage des contrôles à une fonction telle que :

function loadFields()
{
   var xmlNode = window.document.getElementsByTagName('xml');
   var borrowerNode = xmlNode[0].childNodes[1];
   if(borrowerNode.hasChildNodes())
   {
       var i = 0;
       var xmlChildNode, nodeVal=;
       while(borrowerNode.childNodes[i])
       {
           // Recherche un nœud
           xmlChildNode = borrowerNode.childNodes[i];
           // Vérifie le type de nœud
           if(xmlChildNode.nodeType != 3) // #text == 3
           {
               // Récupère la valeur du nœud (aka texte)
               nodeVal += xmlChildNode.firstChild.nodeValue + ' ';
           }
           i++;
       }
       // Applique la valeur du contrôle au nœud
       window.document.getElementById('txtBorrowerName').value = nodeVal;
   }
}

Exemple 1

Voici un autre exemple d'ilot de données XML utilisable dans Mozilla ou IE :

<xml id="mxxdataisland">
   <mxxdataisland>
       <rowset tagid="DATES"></rowset>
       <rowset tagid="SUBJPRP"></rowset>
       <rowset tagid="PRODUCT"></rowset>
   </mxxdataisland>
</xml>

Le role de cet îlot de données est d'apprendre au serveur d'applications à quels tableaux cette page va accéder.

Les contrôles de cette page sont alors liés au moyen des attributs personnalisés MXXOBJECT et MXXPROPERTY, très semblables aux attributs DATASRC et DATAFLD utilisés par IE. Ceci permet aux données XML retournées d'être analysées et liées ou « attachées » aux contrôles.

Remarque : Les noms MXXOBJECT et MXXPROPERTY ont été créés pour cet article, et peuvent être différents.

Lier les contrôles :

<input
    type="text"
    id="PropertyStAddr1"
    name="PropertyStAddr1"
    style="height:21px;width:302px;text-align:left;"
    maxlength="35"
    class="fldDefault"
    mxxobject="SUBJPRP" mxxproperty="PropertyStAddr1" <-- voici nos balises "d'attache"
>

<input
    type="text"
    class="fldZipCode"
    name="PropertyZip"
    id="PropertyZip"
    size="10"
    style="height:21px;width:69px;"
    mxxobject="SUBJPRP" mxxproperty="PropertyZip" <-- voici nos balises "d'attache"
    mxxxmlnode="xmldef_PropertyZip" <-- this links to a control-level data island
    mxxtype="MXXZipCodeAutoLoadEdit" <-- type personnalisé et optionnel pour manipuler les contrôles
>

Comme nous envoyons du XML au serveur, nous pouvons également lui envoyer certaines informations supplémentaires dont un contrôle particulier pourrait avoir besoin, ou lui signaler d'autres contrôles sur la page liés ou dirigés par un contrôle. Ci-dessous, voici un exemples de DataIsland personnalisé pour un type spécifique de contrôle :

<select
    id="PropertyState"
    name="PropertyState"
    style="height:20px;width:48px;"
    class="cmbDefault"
    mxxtype="GFXStateList"
    mxxxmlnode="xmldef_PropertyState"
    mxxobject="GOXSUBJPRP" mxxproperty="PropertyState"
>
</select>

<div style="width:0px; height:0px; visibility:hidden;z-index:1">
    <xml id="xmldef_PropertyState">
        <mxxstatelist>
            <status value="initialize"></status>
            <contenttype value="abbrev"></contenttype>
            <controls>
                <control type="countylist" tagid="PropertyCounty" contenttype="name"
                         valuetype ="name"></control>
            </controls>
        </mxxstatelist>
    </xml>
</div>

Telles quelles, ces XMLDataIslands ne nous sont d'aucune utilité. Il nous faut d'abord accomplir deux choses.

  1. Construire un gestionnaire de contrôle pour gérer les mises à jour et le rendu des différents types de contrôles.
    (Note : Les types de contrôles peuvent être n'importe quoi ; objet formulaire, tableau, spans, divs, iFrames, et tout ce à quoi vous avez accès via le DOM et un ID est valide)
  2. Construire un gestionnaire pour créer un DOM à envoyer au serveur, et transmettre la réponse une fois analysée aux contrôles.

Tout ce qu'un gestionnaire de contrôle doit être capable est de mettre à jour une valeur de contrôle. Cela signifie que tous les TextInputs peuvent partager un même gestionnaire, les selects un autre, etc. Une façon d'y parvenir est de regrouper les contrôles d'une page donnée dans un tableau associatif. Puis, lorsqu'une réponse est retournée, nous pouvons analyser le code XML à l'aide d'un attribut ID pour faire correspondre les données utiles XML avec un contrôle.

<input type="text" id="FirstName" ...>

Exemple de fonction de collection d'objets :

   // Extraction de tous les éléments pour les analyser 
   var tags = window.document.body.getElementsByTagName("*");
   var pPrevElem = null;
   var pNextElem = null;
   for (var i = 0; i < tags.length; i++)
   {
       pHTMLElement = tags[i];

       switch (pHTMLElement.tagName.toLowerCase())
       {
           case "span":
           case "table":
               // this indexes by controlID and stores the elementObject
               m_MXXPageObjectsArray[pHTMLElement.id] = pHTMLElement;
               break;
           case "input":
           case "select":
           case "textarea":
           case "button":
               // this indexes by controlID and stores the elementObject
               m_MXXPageObjectsArray[pHTMLElement.id] = pHTMLElement;
               break;
           case "div":
               // this indexes by controlID and stores the elementObject
               m_MXXPageObjectsArray[pHTMLElement.id] = pHTMLElement;
               break;
       }
   }

La charge XML sortante pourrait être :

<page id="NewUser">
    <formcontrols>
        <control id="FirstName">
            <value />
        </control>
    </formcontrols>
</page>

Le retour sera alors :

<page id="NewUser">
    <formcontrols>
        <control id="FirstName">
            <value>Dennis</value>
        </control>
    </formcontrols>
</page>

L'analyseur prend alors la réponse retournée, la charge dans un DOM XML, et passe chaque nœud au gestionnaire de contrôle approprié.

   processTextControl(control, xmlNode);

Exemple d'analyse XML retournée :

   // parseout to controls
   var formControlNodes = xmlDoc.getElementsByTagName('formcontrols');
   for(i=0; i<formControlNodes.length;++i)
   {
       var pFormControlNode = formControlNodes[i];
       var pPageObject = m_MXXPageObjectsArray[pFormControlNode.getAttribute('id')];
       if(!pPageObject)
           continue;
       processTextControl(pPageObject, pBoundControlNode);
   }

Le gestionnaire de contrôles va alors extraire les données nécessaires pour remplir le contrôle. Dans ce cas, la valeur nodevalue sera utilisée pour l'attribut control.value. Un Select pourrait créer de nouvelles Options() avec ces données, ou même remplacer le noeud ou le HTML par les nouvelles données.

Voici une page exemple.

Finalement, voici un exemple simple de tableau utilisant les Data Islands XML qui fonctionne dans IE6 et dans Mozilla.

Pour que tout ce qui est décrit ci-dessus fonctionne, il nous faut envoyer cette information au serveur. Il y a plusieurs moyens, dont ASP, JSP et CGI. J'utilise XMLHTTP car il me permet de mettre à jour la page sans avoir à la recharger, qu'il permet aux contrôles de mettre à jour d'autres contrôles et qu'il agit comme une application 2-tiers classique en fournissant des mises à jour instantanées et la gestion des évènements.

 

Informations sur le document original

Liens Interwikis

 

Étiquettes et contributeurs liés au document

Étiquettes : 
 Contributeurs à cette page : tregagnon, Hsivonen, BenoitL, VincentN, Fredchat
 Dernière mise à jour par : tregagnon,