XForms/Output and Links

Motivation

edit

You want to display a repeated set of URLs in a section of your form. Each URL is created by concatenating a base URL and a URL parameter.

Method

edit

The equivalent of the HTML anchor tag (<a>) in an XForms application is the <xf:load> element.

If in a web page, you want your output to appear like this:

<div class="links">
   <a href="http://www.example.com/myservice.xq?id=1">One</a>
   <a href="http://www.example.com/myservice.xq?id=2">Two</a>
   <a href="http://www.example.com/myservice.xq?id=3">Three</a>
</div>

in an XForms application each anchor will be xf:load.

Your input instance is like the following:

<xf:instance id="link-items" xmlns="">
<data>
   <item>
      <id>1<id>
      <label>One</label>
   </item>
   <item>
      <id>2<id>
      <label>Two</label>
   </item>
   <item>
      <id>3<id>
      <label>Three</label>
   </item>
</data>
</xf:instance>

Discussion

edit

With XForms it is not possible to create dynamic links inside a repeat using a combination of output, value and concat. This would also impact the ability to notify the user that is navigating away from a form.

There are two ways to display a list of links. Both use a trigger with the button appearance turned off. The first uses a load after setting a temporary instance. The second uses a submit/submission combination.

Using load

edit

You can also use the load element as the element.

<xf:instance id="URL-container" xmlns="">
   <URL/>
</xf:instance>
  <!-- ... -->
  <xf:trigger appearance="minimal">
    <xf:label>One</xf:label>
    <xf:action ev:event="DOMActivate">
      <xf:setvalue ref="instance('URL-container')"
                   value="concat('http://www.example.com/my-view.xq?id=', id)"/>
      <xf:load ref="instance('URL-container')"/>
    </xf:action>
  </xf:trigger> 
<xf:instance>
edit

Load XForms Application

Sample Program

edit

The following program displays a list of links in a horizontal row. Each link has a label and a URL suffix that is extracted from an instance document.

<html xmlns="http://www.w3.org/1999/xhtml" 
   xmlns:ev="http://www.w3.org/2001/xml-events" 
   xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
   xmlns:xf="http://www.w3.org/2002/xforms">
    <head>
        <title>Displaying Links in an XForms Application</title>
        <style type="text/css">
          @namespace xf url("http://www.w3.org/2002/xforms");
          body {font-family:Helvetica, sans-serif}
          .links xf|repeat * {display: inline;}
          .url {color: blue; text-decoration:underline; margin: 0 2px;}
       </style>
        <xf:model>
            <xf:instance xmlns="" id="links">
                <data>
                    <link>
                        <label>XForms</label>
                        <wikipedia-id>XForms</wikipedia-id>
                    </link>
                    <link>
                        <label>XQuery</label>
                        <wikipedia-id>XQuery</wikipedia-id>
                    </link>
                    <link>
                        <label>XSLT</label>
                        <wikipedia-id>XSL Transformations</wikipedia-id>
                    </link>
                    <link>
                        <label>XML Database</label>
                        <wikipedia-id>XML_database</wikipedia-id>
                    </link>
                    <link>
                        <label>Declarative Programming</label>
                        <wikipedia-id>Declarative_programming</wikipedia-id>
                    </link>
                    <link>
                        <label>Functional Programming</label>
                        <wikipedia-id>Functional_programming</wikipedia-id>
                    </link>
                </data>
            </xf:instance>
            <xf:instance id="URL-container" xmlns="">
                <URL />
            </xf:instance>
        </xf:model>
    </head>
    <body>
        <h3>Displaying Links in an XForms Application</h3>
        <div class="links">
            <xf:repeat nodeset="instance('links')/link" id="link-repeat">
                <xf:trigger submission="replace-form-with" appearance="minimal" class="url">
                    <xf:label>
                        <xf:output ref="label" />
                    </xf:label>
                    <xf:hint>
                        <xf:output ref="wikipedia-id" />
                    </xf:hint>
                    <xf:action ev:event="DOMActivate">
                        <xf:setvalue ref="instance('URL-container')" value="concat('http://en.wikipedia.org/wiki/', instance('links')/link[index('link-repeat')]/wikipedia-id)" />
                        <xf:load ref="instance('URL-container')" />
                    </xf:action>
                </xf:trigger>
            </xf:repeat>
        </div>
    </body>
</html>

Acknowledgment

edit

This solution was posted to the Mozilla XForms development newsgroup by John Clark on February 27th, 2008.

edit

As an alternative strategy you can replace a form by using the submission statement with a replace="all" attribute. You can then style the submission button using appearance="minimal" and make the button look like a link:

   <style type="text/css">
   @namespace xf url("http://www.w3.org/2002/xforms");
   .url {color: blue; text-decoration:underline; margin: 0 2px;}
   </style>
   ...
   <xf:submission id="replace-form-with" method="get"
      ref="instance('link-items')/item[index('link-repeat')]/id"
          action="http://www.example.com/my-view.xq" 
          replace="all" />
   ...
   <xf:repeat nodeset="instance('link-items')/item" id="link-repeat">
   <xf:submit submission="replace-form-with" appearance="minimal" class="url">
        <xf:label><xf:output ref="label"/></xf:label>
   </xf:submit>

The only disadvantage of this solution over using standard links is that the URL does not display in the status bar. This problem can be mitigated by using the xf:hint element within the label. This text will display when the user hovers over the link.

This method also allows you to interrupt the submission, check for changes in instance data and display warning messages before a form is unloaded.

Next Page: Switch and Case | Previous Page: Formatting Numbers
Home: XForms