I have an xhtml+xforms form in which users are viewing or deleting files from their server. (see earlier posts if you want to know more).
The file names are stored in an xml instance that the xforms is based on. The file names are listed as items in an xf:select1 control (actually in this case, it’s an itemset). When they click a file name, voila! they get to view their file (or delete it).
But what if they forgot to click on a file before clicking the load or submit button? It’s unlikely, but if someone happens to be using this particular page frequently in one sitting, it’s not entirely unlikey either, and in such a case they’ll get a nasty error message which will freak them out (especailly if it were a situation where they were saving or deleting –they wouldn’t really know what happened).
So first let’s put an extra model in our xforms (you could just add an extra instance to your current model, I suppose, but It’s much easier, from my perspective, to reference a second model than a second instance–besides, currently, mozilla is having some trouble reading the xml instance when there are multiple instances). So here it is:
<xf:model id=”mod2?>
<xf:instance id=”inst2?>
<data xmlns=”">
<delFileSelected>0</delFileSelected>
<delTriggerOn/>
<delTriggerOff/>
<vwFileSelected>0</vwFileSelected>
<vwTriggerOn/>
<vwTriggerOff/>
</data>
</xf:instance>
<xf:bind nodeset=”delTriggerOn” relevant=”//delFileSelected = 1?/>
<xf:bind nodeset=”delTriggerOff” relevant=”//delFileSelected = 0?/>
<xf:bind nodeset=”vwTriggerOn” relevant=”//vwFileSelected = 1?/>
<xf:bind nodeset=”vwTriggerOff” relevant=”//vwFileSelected = 0?/>
</xf:model>
For now, we’re going to ignore the “del….” parts of the model, I just included it here so that you can see that this model could be built to handle several different types of situations. So let’s just focus on the vw (view) elements, like below:
<xf:model id=”mod2?>
<xf:instance id=”inst2?>
<data xmlns=”">
…
<vwFileSelected>0</vwFileSelected>
<vwTriggerOn/>
<vwTriggerOff/>
</data>
</xf:instance>
…
<xf:bind nodeset=”vwTriggerOn” relevant=”//vwFileSelected = 1?/>
<xf:bind nodeset=”vwTriggerOff” relevant=”//vwFileSelected = 0?/>
</xf:model>
These elements are going to control my controls. Basically it is all set around the value of the “vwFileSelected” element. If the element’s value is zero, we’ll hide one control and show the other. If the element equals one, vice-versa.
We’ll do this by wrapping the controls with xf:group elements and each group element will refer back to vwTriggerOn or vwTriggerOff.
Notice the xf: bind element. The vwTriggers depend on this bind–and hence, the value of vwFileSelected. If someone doesnt’ click on a file in the xf:select1 control, then the vwTriggerOff will show because the vwFileSelected is initially set at zero.
Then, using xf:setvalue with event xforms-select inside the xf:select1 control, the vwFileSelected will be set to one and so the vwTriggers switch roles.
In this example the “view” button will appear unfocused until someone selects a file, then it will appear in full color.
As the images below will also show, it appears as if we have a single “view” trigger. But underneath the hood, they’re really two separate triggers which means, importantly, that even if someone attempts to click on it the trigger won’t work. Here’s the images:
Here’s the code–I left most of the styling out in order not to clutter the code, but you’ll get the same basic effect:
<xf:select1 ref="viewFile" appearance="minimal">
<xf:setvalue model=”mod2? ref=”//vwFileSelected”
value=”‘1?” ev:event=”xforms-select”/>
<xf:label>Select a Form: </xf:label>
<xf:itemset nodeset=”//file”>
<xf:value ref=”@full” />
<xf:label ref=”@text” />
</xf:itemset>
</xf:select1>(opens in new tab or window)
<xf:group model=”mod2? ref=”vwTriggerOff”><h:p/>
<xf:trigger appearance=”minimal”>
<xf:label><h:span style="color:#dododo>
View
</h:span></xf:label>
</xf:trigger>
</xf:group>
<xf:group model=”mod2? ref=”//vwTriggerOn”><h:p/>
<xf:submit id="subm1zaz" class="subm"
submission="xfviewstyle" appearance='minimal'>
<xf:label>
<h:fieldset style="color:#000033;">
View
</h:fieldset>
</xf:label>
</xf:submit>
</xf:group>
/* as a footnote I tried this with xf:load as shown below,
but the trigger wouldn't activate regardless of the vwFileSelected value.
Don't know if it's a bad xpath reference on my part
(and I tried every path route I could think of) or a Mozilla bug.
You can see the code below is exactly like the above only substituting
xf:load control for xf:submit. If anyone has a clue let me know. */
<xf:group model=”mod2? ref=”//vwTriggerOn”><h:p/>
<xf:trigger appearance = “minimal”>
<xf:label><h:span style="color:#000033>
View
</xf:label>
<xf:action ev:event=”DOMActivate” ref=”//viewFile”>
<xf:load ref=”//viewFile” show=”new” />
</xf:action>
</xf:trigger>
</xf:group>
At any rate, it works great with submit control as I tested it quite thoroughly and also use it with my delete files optoin as well.
An alternate solution, is to simply do away with the first xf:group (the fake “view” trigger) . In this case you’d have only the select box showing and then when someone clicked on a file, the “view” trigger would appear.
And yet another approach, if you like, you can add some text right below the trigger (not inside the trigger element but just below it) as such:
<h:span style=’font-size:105%;color:#800000?> <xf:output model=”mod2? value=”if(//vwFileSelected != 1,’NO FILES SELECTED’,”)”/> </h:span>
The above gives a single message that dissappears after a selection is made. However, you can have an alternate text in the xf:output like this:
…’NO FILES SELECTED’,’OK’ )”
If you have a deselect situation (and I saw no need for that in my viewing situation) make sure you set the xfFileSelected value back to zero so the “View” trigger loses focus again (and/or the ‘NO FILES SELECTED’ message reappears). In the situation of a select with apperance = ‘full’ just add this line inside the select or select1 along with the other setvalue.
<xf:setvalue model="mod2" ref="//vwFileSelected"
value="'0'" ev:event=“xforms-deselect”/>
In my case, in my delete files situation, Mozilla won’t allow a deselect on an xf:select (multiple select) appearance=’minimal’, so I added this trigger right above my selection box. Notice that the value of my instance element is set to “” –nothing, and that the value of my “mod2? instance element is reset to zero.
<xf:trigger><xf:label>deselect choice/s</xf:label> <xf:setvalue ref="//deleteFiles" value=”" ev:event=”DOMActivate”/> <xf:setvalue model=”mod2” ref=”//delFileSelected” value=”0? ev:event=”DOMActivate”/> </xf:trigger><h:br/>
Again,what’s cool about this it that we never have to make a trip to the server nor lose the focus of our page while double checking that a control has been, or not been, selected–while simultaneously controlling the active state of the displayed trigger.


[...] also need to look at No files selected (using xf:bind and relevant) –the point of that post not being the file selection but the ability to hide any portion of [...]
Pingback by ClarkePeter’s Weblog » Hiding dropovers with CSS and Xforms — October 21, 2008 @ 10:53 am