2010-11-03 21 views
1

J'ai des difficultés à insérer une rangée avec des composants xbl dans une position particulière. Cela fonctionne si j'insère une ligne à la fin mais si j'essaie d'insérer une ligne au milieu, alors la méthode init des composants xbl n'est pas appelée.orbeon insert in repeat

Voici le xhtml.

<xhtml:head> 
    <xforms:model id="main" 
        xxforms:session-heartbeat="true" 
        xxforms:show-error-dialog="false" 
        xxforms:external-events="submit-save submit-preview submit-cancel"> 

     <xforms:instance id="instance"> 
      <root> 
       <repeat> 
        <item> 
         <title/> 
        </item> 
       </repeat>   
      </root> 
     </xforms:instance> 

     <xforms:instance id="proto-property"> 
      <item> 
       <title/> 
      </item> 
     </xforms:instance> 

     <xforms:bind nodeset="instance('instance')"> 
      <xforms:bind 
       nodeset="repeat/item/title" 
       required="true()" /> 
     </xforms:bind> 

    </xforms:model> 
    <xbl:xbl xmlns:xhtml="http://www.w3.org/1999/xhtml" 
    xmlns:xforms="http://www.w3.org/2002/xforms" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:ev="http://www.w3.org/2001/xml-events" 
    xmlns:xi="http://www.w3.org/2001/XInclude" 
    xmlns:xxi="http://orbeon.org/oxf/xml/xinclude" 
    xmlns:xxforms="http://orbeon.org/oxf/xml/xforms" 
    xmlns:fr="http://orbeon.org/oxf/xml/form-runner" 
    xmlns:saxon="http://saxon.sf.net/" 
    xmlns:oxf="http://www.orbeon.com/oxf/processors" 
    xmlns:xbl="http://www.w3.org/ns/xbl" 
    xmlns:xxbl="http://orbeon.org/oxf/xml/xbl" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xbl:script src="/apps/xforms-sandbox/samples/input-counted.js" /> 

    <xbl:binding id="fr-input-counted" element="fr|input-counted"> 
     <xbl:template xxbl:transform="oxf:unsafe-xslt"> 
      <xsl:transform version="2.0"> 
       <xsl:import href="oxf:/oxf/xslt/utils/xbl.xsl" /> 
       <xsl:template match="/*"> 
        <xforms:group xbl:attr="model context ref bind" xxbl:scope="outer"> 

         <xbl:content includes="xforms|label" />        

         <xsl:copy-of select="xxbl:parameter(., 'max')" /> 

         <xxforms:script ev:event="xforms-enabled" ev:target="#observer"> 
          YAHOO.xbl.fr.InputCounted.instance(this).initialize(); 
         </xxforms:script> 

         <xforms:group xxbl:scope="inner"> 
          <xxforms:variable name="binding" as="node()?"> 
           <xxforms:sequence select="." xxbl:scope="outer"/> 
          </xxforms:variable> 
          <xforms:input id="input-counted" class="fr-input-counted" ref="$binding" incremental="true" /> 
          <label class="counter-label"></label> 
         </xforms:group> 
        </xforms:group> 
       </xsl:template> 
      </xsl:transform> 
     </xbl:template> 
    </xbl:binding> 

</xbl:xbl> 

</xhtml:head> 

<xhtml:body class="body"> 

    <div> 
     <xforms:trigger appearance="full"> 
      <xforms:label> 
       Add Another 
      </xforms:label> 
      <xforms:insert ev:event="DOMActivate" at="1" 
      nodeset="repeat/item"/> 
     </xforms:trigger> 
    </div> 

    <xforms:repeat nodeset="repeat/item"> 
     <div> 
      <fr:input-counted ref="title" max="10"> 
       <xforms:label>Node Selector </xforms:label> 
      </fr:input-counted> 
     </div> 
    </xforms:repeat> 
</xhtml:body> 

Essayez de cliquer sur Ajouter Une autre plusieurs fois et vous verrez qu'il ne soit pas peuplait la taille à côté de la boîte d'entrée.

Vous pouvez télécharger le fichier js requis à partir de l'URL suivante. (http://orbeon-forms-ops-users.24843.n4.nabble.com/Error-in-repeat-for-controls-having-relevant-td2331649.html#a2533819). C'est la même erreur mais il est simple en supprimant le pertinent. J'utilise Orbeon 3.8 et xforms.js ligne 3798 a le code suivant. Si j'ai l'attribut "at" dans l'insert, il ne va jamais à l'intérieur. C'est parce que j'essaye d'insérer une rangée où une rangée a été précédemment initialisée.

    if (! this.initialized) { 
         originalInit.call(this); 
         this.initialized = true; 
        } 

Est-ce un bug?

Merci Vous Binesh Gummadi

+0

Pourriez-vous créer un seul fichier contenant le XHTML + XBL + JS, afin que nous puissions le reproduire plus facilement et mettre à jour votre exemple? J'ai essayé de le faire, mais je suis arrivé au point où 'YAHOO.xbl.fr.InputCounted.instance (this) .initialize()' est appelé, et 'initialize()' n'est défini nulle part dans votre code. Voir: http://pastie.org/1272744 – avernet

+0

Merci d'avoir répondu à Alex. Ma faute! S'il vous plaît regardez ce http://pastie.org/1272963 qui a le bon javascript Maintenant, l'insertion a à = "1", donc l'erreur se produira à partir 3e itération. Si vous le changez en 2, vous pouvez voir l'erreur de la 4ème itération. – BinnyG

+0

Merci pour l'exemple complet; ça aide vraiment. J'ai pu exécuter ceci, et voir ma réponse (http://stackoverflow.com/questions/4090978/orbeon-insert-in-repeat/4136986#4136986). – avernet

Répondre

0

Deux choses:

d'abord, assurez-vous que la méthode utilisée pour initialiser votre objet est appelé init() (non initialize()). Cela parce que la plomberie qui est injectée lorsque vous appelez ORBEON.xforms.XBL.declareClass() s'assure qu'à chaque fois que vous appelez instance(), si une instance pour le composant actuel est introuvable, une est créée et init() est appelée sur cet objet. Il assure également que init() est appelée une seule fois.

En second lieu, ajouter xxforms-iteration-moved en plus de xforms-enabled aux événements qui déclenchent l'objet XBL à initialiser:

<xxforms:script ev:event="xforms-enabled xxforms-iteration-moved" ev:target="#observer"> 
    YAHOO.xbl.fr.InputCounted.instance(this).init(); 
</xxforms:script> 

Avec ces deux changements, de ce que je peux voir, le composant semble avoir correctement initialisé (Je reçois le 0/10 sur chaque ligne après le champ de texte).

0

https://gist.github.com/768034

Voici la version simplifiée de la même erreur. Lorsque le contrôle devient pertinent après l'avoir rendu non pertinent, la méthode init n'est pas appelée, ce qui revient à mon observation précédente (xforms.js, ligne 3798).

Étapes pour reproduire

  1. Observe deux alertes à la page de chargement
  2. Décochez la case à cocher
  3. Cochez la case à cocher (observer une seule alerte. "Initialisé" alerte n'est pas affiché)

Est-ce le bon comportement?

+0

J'ai posté une réponse comme une autre réponse au lieu de mettre à jour ma réponse précédente, car cela ressemble à une autre question (liée) (où vous ne l'avez pas répéter ici. – avernet

0

(Ceci est une réponse à un suivi question affiché comme une réponse sur cette page. Hem.)

Oui, c'est le comportement prévu, et je comprends comment cela peut être la confusion. L'idée de la méthode init() consiste à initialiser votre objet JavaScript et à initialiser le DOM. Si vous obtenez une instance de votre objet avec instance(), cette méthode sera appelée automatiquement pour vous avant que toute autre méthode ne soit appelée sur votre objet.

Cela explique pourquoi vous ne voyez pas init() appelé lorsque votre composant est à nouveau activé. Ce que vous voulez faire ici est divisé le code de votre en init() dans:

  • La partie qui initialise vraiment le composant - qui vous gardez à l'init().
  • La partie qui modifie l'apparence de votre composant pour qu'il s'affiche comme activé - que vous mettez dans une nouvelle méthode enabled().

Ensuite, vous écrivez:

<xxforms:script ev:event="xforms-enabled"> 
    YAHOO.xbl.fr.InputCounted.instance(this).enabled(); 
</xxforms:script> 

Notez que vous n'avez pas besoin d'appeler explicitement init(); Cela sera fait pour vous avant toute autre méthode. Quelque chose de similaire est fait dans le code pour le fr:button.