normalyeshelloLet us know!

Replacing jQuery with XForms

This page demonstrates the XForms version of the examples in Replacing jQuery with Vue.js: No Build Step Necessary. For more information about these examples, please see the related post about XForms.

The model

For simplicity, all of the examples on this page are backed by a single model. You probably wouldn’t do this in real life, but then again, you probably wouldn’t have all these forms on a single page either.

You can find the model in the head of this page, but here’s what it looks like:

<model>
  <instance>
    <data xmlns="">
      <name/>
      <name2/>
      <state>normal</state>
      <show>yes</show>
      <greeting>hello</greeting>
      <taco/>
      <tell>Let us know!</tell>
      <ok/>
      <name1/>
      <email/>
      <answer/>
    </data>
  </instance>
  <instance id="response">
    <data xmlns=""><response/></data>
  </instance>
  <bind ref="greeting" relevant="../show = 'yes'"/>
  <bind ref="tell" relevant="string-length(../taco) != 0"/>
  <bind ref="ok"
        readonly="string-length(../name1) = 0
                  and string-length(../email) = 0
                  and string-length(../answer) = 0"/>
  <bind ref="email" type="email"/>
  <submission resource="http://example.com/somewhere"
              replace="instance" instance="response"/>
</model>

In practice, the model (and all of the markup examples), are in the XForms namespace, http://www.w3.org/2002/xforms.

Capturing User Inputs

The first example is trivial. :

<input ref="name" incremental="true">
  <label>Name:</label>
</input>
<output ref="name"/>

Storing User Input on a Single Event

The second example simply leaves out the incremental attribute:

<input ref="name">
  <label>Name:</label>
</input>
<output ref="name"/>

Toggling Classes

XForms supports attribute-value-templates in attributes, which makes this kind of styling straight-forward:

<trigger>
  <label>Toggle me</label>
  <setvalue ref="state" value="if(.!='warning', 'warning', 'normal')" ev:event="DOMActivate"/>
</trigger>
<output class="{state}" value="'Sometimes I need to be styled differently'"/>

Hiding and Showing

Hiding and showing is one of the basic activites of XForms. If a value is not 'relevant', any controls bound to it are not shown.

<bind ref="greeting" relevant="../show='yes'"/>
 ...
<trigger>
  <label>Toggle me</label>
  <setvalue ref="show" value="if(.='yes', 'no', 'yes')" ev:event="DOMActivate"/>
</trigger>
<output ref="greeting" class="box"/>

What’s your favorite kind of taco?

Neither jQuery nor Vue appear to support hints, a builtin feature of XForms that offers a handy solution to this problem:

<input ref="taco">
  <label>What is your favourite kind of taco?</label>
  <hint>Let us know!</hint>
</input>

Simply hover the cursor near the end of the input field.

Let us know!

In the absence of hints, the authors of the original article make the slightly odd choice that the “let us know” message should be displayed when the input is not empty. Okay…

<bind ref="tell" relevant="string-length(../taco) != 0"/>
 ...
<input ref="taco" incremental="true">
  <label>What is your favourite kind of taco?</label>
</input>
<output class="boxy" ref="message"/>

Submitting a Form

Unsurprisingly, submit handling is the stuff XForms eats for breakfast, and we can do much better, such as live checking for valid email addresses, and not allowing submit before that.

<submission resource="http://example.com/somewhere" replace="instance" instance="response"/>
 ...
<bind ref="ok"
      readonly="string-length(../name) = 0
                and string-length(../email) = 0
                and string-length(../answer)=0"/>
<bind ref="email" type="email"/>
 ...
<input ref="name" incremental="true">
  <label>Name: </label>
</input>
<input ref="email" incremental="true">
  <label>Email: </label>
</input>
<textarea ref="answer" incremental="true">
  <label>How do I turn off caps lock: </label>
</textarea>
<submit ref="ok"><label>Submit</label></submit>
<output ref="instance('response')/response">
  <label>Response from server</label>
</output>
Not a valid email (N.B. This is a fake reply for demo purposes)

To see how easily these examples were accomplished, “view source” on this page.