XForms/Conditional Styling
Motivation
[edit | edit source]You have a list of items that you want to display inside of a repeat loop. You want some items to have different styling based on the content of items.
Method
[edit | edit source]We will use the XForms group element to conditionally display an item inside of the repeat statement.
Sample XML Fragement
[edit | edit source]Assume your form has the following data in an instance:
<my-nodes>
<my-node>
<element1>true</element1>
<element2>Element2 Value</element2>
</my-node>
<my-node>
<element1>false</element1>
<element2>Element2 Value</element2>
</my-node>
<my-node>
<element1>true</element1>
<element2>Element2 Value</element2>
</my-node>
</my-nodes>
Conditional Display of Items
[edit | edit source]The following text will only output element2 when element1 has a value of true.
<xf:repeat nodeset="//my-node">
<xf:group ref=".[element1='true']">
<xf:output ref="element2"/>
</xf:group>
</xf:repeat>
The syntax .[a='b'] says that from the current node if the element a equals the value b then output the elements within the group.
Conditional Formatting of Items
[edit | edit source]This same strategy can be used to enclose output in different div or span elements.
<xf:repeat nodeset="my-node">
<xf:group ref=".[element1='true']">
<xf:output ref="element2" class="strong"/>
</xf:group>
<xf:group ref=".[element1='false']">
<xf:output ref="element2"/>
</xf:group>
</xf:repeat>
In the above example all nodes with element1='true' will have a class="strong" in the output and any element with element1='false' will not have the attribute in the output.
Sample XForms Appliction
[edit | edit source]Source Code
[edit | edit source]In this example we need to display a list of synonyms for a specific term. The Synonyms are all listed and a preferred term is displayed with a bold font.
<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>Conditional Display</title>
<style type="text/css">
@namespace xf url("http://www.w3.org/2002/xforms");
body {font-family:Helvetica, sans-serif}
.strong {font-weight:bold;}
/* this puts everything under the repeat element into a single line */
xf|repeat * {display:inline;}
</style>
<xf:model>
<xf:instance xmlns="" id="current-synset">
<data>
<synset-id>3</synset-id>
<synonym>
<preferred>false</preferred>
<syn-name>Boolean-Value</syn-name>
</synonym>
<synonym>
<preferred>false</preferred>
<syn-name>Conditional-Value</syn-name>
</synonym>
<synonym>
<preferred>false</preferred>
<syn-name>Flag</syn-name>
</synonym>
<synonym>
<preferred>true</preferred>
<syn-name>Indicator</syn-name>
</synonym>
<synonym>
<preferred>false</preferred>
<syn-name>Yes/No-Value</syn-name>
</synonym>
</data>
</xf:instance>
</xf:model>
</head>
<body>
<h3>Synonym Set</h3>
<span>(preferred term is bold)</span><br/>
<xf:label>Synonyms: </xf:label>
<xf:repeat nodeset="instance('current-synset')/synonym" id="repeat">
<xf:group ref=".[preferred='true']">
<xf:output ref="syn-name" class="strong"/>
</xf:group>
<xf:group ref=".[preferred='false']">
<xf:output ref="syn-name"/>
</xf:group>
</xf:repeat>
</body>
</html>
Discussion
[edit | edit source]XForms 1.1 also includes the if attribute. Some XForms can conditionally use this for display of elements.