4

I have a XBL component which creates a checkbox control in javascript. Value is set in javascript during the component initialization. Component works well when not used inside repeat but inside repeat when I try to move rows up or down XBL control doesn't change the state.

xxforms-iteration-moved event is fired on the row which is moved but doesn't fire on the row which changes position during this move. For instance, if I move row 3 to row 2 then xxforms-iteration-moved is fired on row 3 but I want to reinitialize components in row 2 as well as my state is saved in javascript.

I think xxforms-iteration-moved should be fired on both rows which changed position? This is really a swap which involves both rows. Please comment.

Edit: I am using Orbeon Form Runner

BinnyG
  • 601
  • 9
  • 19

1 Answers1

1

To what components the xxforms-iteration-moved is dispatched is a matter of how xxforms-iteration-moved is defined. Right now, it is dispatched to controls inside iterations that moved. What you might need is to handle the xforms-enabled event, in addition to xxforms-iteration-moved. Consider the following example: you start with a list with "a, c, d". If you insert "b" after "a", then the new "b" gets an xforms-enabled and "c, d" each get a xxforms-iteration-moved. So by reacting to both events, you should be able to (re)initialize your component as necessary.

<xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml"
      xmlns:xforms="http://www.w3.org/2002/xforms"
      xmlns:xxforms="http://orbeon.org/oxf/xml/xforms"
      xmlns:ev="http://www.w3.org/2001/xml-events"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns:fr="http://orbeon.org/oxf/xml/form-runner">
    <xhtml:head>
        <xhtml:title>Iteration moved</xhtml:title>
        <xforms:model>
            <xforms:instance>
                <instance>
                    <letter>a</letter>
                    <letter>c</letter>
                    <letter>d</letter>
                    <letter>e</letter>
                </instance>
            </xforms:instance>
        </xforms:model>
    </xhtml:head>
    <xhtml:body>
        <fr:button>
            <xforms:label>Insert b</xforms:label>
            <xforms:insert ev:event="DOMActivate" nodeset="letter" at="1" position="after" origin="xxforms:element('letter', 'b')"/>
        </fr:button>
        <fr:button>
            <xforms:label>Delete c</xforms:label>
            <xforms:delete ev:event="DOMActivate" nodeset="letter[. = 'c']"/>
        </fr:button>
        <xforms:repeat id="letter-repeat" nodeset="letter">
            <xforms:output id="letter" value=".">
                <xforms:message ev:event="xxforms-iteration-moved" level="modal" value="concat('xxforms-iteration-moved : ', .)"/>
                <xforms:message ev:event="xforms-enabled" level="modal" value="concat('xforms-enabled : ', .)"/>
            </xforms:output>
        </xforms:repeat>
    </xhtml:body>
</xhtml:html>

I should add that if you expect your component to be used in a repeat (and sooner or later every component is), right now, because of how repeats work on the client side, if you are doing some work to initialize the component on xforms-enabled, you most likely need to do that as well on xxforms-iteration-moved. For instance, see how this is done in the fr:button component.

avernet
  • 30,895
  • 44
  • 126
  • 163
  • Agree Alex. This is how I have it in my RTE xbl control. YAHOO.xbl.fr.RTE.instance(this).init(); You said "Right now, it is dispatched to controls inside iterations that moved." So when 3rd iteration is moved to 2nd iteration, xxforms-iteration-moved event is dispatched to RTE control which is in 3rd iteration. It is not dispatched to the 2nd iteration. I was under impression that xxforms-iteration-moved will be dispatched to both iterations. – BinnyG Nov 03 '10 at 18:02
  • BinnyG, how did the 3rd iteration move to become the 2nd one? Was the 1st or 2nd delete? – avernet Nov 03 '10 at 18:31
  • 1
    BinnyG, adding to my previous comment, if you delete 2nd one and the 3rd one becomes the 2nd one, the now 2nd one should receive an `xxforms-iteration-moved` event. To confirm this, run the above code (to which I added a "Delete c" button), click on that button: you'll go from "a, c, d, e" to "a, d, e"; at that point "d" and "e" receive an `xxforms-iteration-moved` event. – avernet Nov 03 '10 at 22:33
  • I am not deleting the second row, rather I am moving the 3rd row up to make it the second row. "a, c, d, e" now becomes "a, d, c, e". In this case two rows changed their position and I thought two xxforms-iteration-moved will be fired. One to "c" and other to "d". – BinnyG Nov 05 '10 at 01:36
  • Binesh, so you are saying that you are swapping two items? I am not 100% sure if that this is the problem, but there is no "move" in XForms, just an "insert". So there is no such thing are "swapping c and d", you can only "insert a copy of d before c, and remove the d after c". When you insert a copy of a node, it is not the same node anymore (Orbeon Forms doesn't do a deep compare to figure out what moved). Does this explain what you are seeing? – avernet Nov 05 '10 at 02:11
  • I see your point. But basically this is what I am trying to solve. http://pastie.org/1274024. I have two rows. Select the check box in the first row and click on Up button in the second row. Since checkbox's state is not part of the model instance, it is not moved. In my application it is not as simple as selecting a checkbox. I have state coming from different control and I have a group of checkboxes whose state is set in javascript. This data is saved as part of the control instance(this.data = mydata). What event should I catch to repopulate the checkbox state? – BinnyG Nov 05 '10 at 02:43
  • Binesh, I see, the value for the checkbox will need to be persisted in an instance for this to work. Typically, I would use a boolean input bound to a node in a local model. Otherwise, with just an HTML control, when the context for the XBL component changes, the HTML elements won't update, which is exactly what you are seeing in this case. – avernet Nov 05 '10 at 18:28