xpathxformsxsltforms

xf:dispatch : dynamic event name based on context node not working?


I'm trying to define a bank of buttons based on the contents of an instance. I am doing this to de-clutter my view, by placing the actions in the model. I am using the dispatch element to fire off a dynamically named event (using the 'name' element).

It seems the context of the node is lost within a group or repeat? Here's a test case - the first case works - where I hardcode an explicit XPath to my data, the other test-cases show that the context is apparently not available when I try and reference this dynamically.

<?xml
    version="1.0"
    encoding="UTF-8"?>
<?xml-stylesheet
    href="declarative4all/build/xsl/xsltforms.xsl"
    type="text/xsl"?>
<?xsltforms-options
    debug="no"?>
<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:ht="http://www.w3.org/1999/xhtml"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns:xf="http://www.w3.org/2002/xforms"   
      xmlns:ev="http://www.w3.org/2001/xml-events"
      lang="en">
<head>
    <xf:model id="model">
        <xf:instance>
            <data xmlns="">
                <button name="b1" icon="arrow_upward"/>
                <button name="b2" icon="arrow_downward"/>
            </data>
        </xf:instance>

        <xf:action ev:event="b1">
            <xf:message>b1</xf:message>
        </xf:action>

        <xf:action ev:event="b2">
            <xf:message>b2</xf:message>
        </xf:action>

    </xf:model>
</head>
<body>
        <h1>TEST 1: hardcoded XPath in name element (works)</h1>

            <xf:trigger id="t1">
                <xf:label ref="button[1]/@name"/>
                    <xf:dispatch ev:event="DOMActivate">
                        <xf:targetid>model</xf:targetid>
                        <xf:name value="button[1]/@name"/>
                    </xf:dispatch>
            </xf:trigger>

        <h1>TEST 2: XPath implicit reference to context node (doesn't work)</h1>

        <xf:group ref="button[1]">
            <xf:trigger id="t2">
                <xf:label ref="@name"/>
                    <xf:dispatch ev:event="DOMActivate">
                        <xf:targetid>model</xf:targetid>
                        <xf:name value="@name"/>
                    </xf:dispatch>
            </xf:trigger>
        </xf:group>

        <h1>TEST 3: XPath explicit reference to context node (doesn't work)</h1>

        <xf:group ref="button[1]">
            <xf:trigger id="t3">
                <xf:label ref="context()/@name"/>
                    <xf:dispatch ev:event="DOMActivate">
                        <xf:targetid>model</xf:targetid>
                        <xf:name value="context()/@name"/>
                    </xf:dispatch>
            </xf:trigger>
        </xf:group>

</body>
</html>

Workaround: since my buttons are going to be held within a 'repeat' - I can use the 'index()' function to set the correct node.

     <xf:repeat id="r2" ref="button">
            <xf:input ref="@name"/>
            <xf:input ref="@icon"/>
            <xf:trigger>
                <xf:label ref="@name"/>
                <xf:action ev:event="DOMActivate">
                    <xf:dispatch>
                        <xf:targetid>model</xf:targetid>
                        <xf:name value="instance()/button[index('r2')]/@name"/>
                    </xf:dispatch>
                </xf:action>
            </xf:trigger>
        </xf:repeat>

Solution

  • XSLTForms uses the wrong context when evaluating xf:dispatch/xf:name/@value paths. See this GitHub issue.