AJAX is simple; XForms is Simpler

Leigh L. Klotz, Jr.

Express intent, and let AJAX do the work for you.

I read Daniel Lorch's document Simple AJAX Example, which shows how to use the browser DOM XML, the XHR Microsoft XML browser extension (now copied by others), and Javascript to piece together a simple example of off-browser data, followed by another example of server-side validation.

I decided to produce the same examples in XForms, and have them here running in the Mozilla XForms Extension.

The DOM vs. The Instance

Daniel's example shows how to use the JavaScript DOM access to mutate the DOM of the HTML document. He rightfully eschews the ancient document.write approach and takes a more modern approach and bends JavaScript to a declarative, ID-based solution.

XForms starts off with a declarative solution by allowing you to sprinkle output elements through your HTML document, bound to data stored in something called the instance, which is a DOM outside of the HTML document DOM, thus neatly separating presentation from data.

    <html ...>
      <head>

	<xf:model>
	  <xf:instance>
	    <data xmlns="">
	      <foo>Hello world</foo>
	    </data>
	  </xf:instance>
	</xf:model>

      </head>

      <body>
	<p>
	  <xf:trigger>
	    <xf:label>Replace Text</xf:label>
	    <xf:action ev:event="DOMActivate">
	      <xf:setvalue ref="foo"><![CDATA[Hello <b>XForms</b> world!]]></xf:setvalue>
	    </xf:action>
	  </xf:trigger>
	</p>

	<xf:output ref="foo" mediatype="text/html" />

      </body>
    </html>

The XML HTTP Request Object vs. The Instance

In The XML HTTP Request Object, Daniel shows how to use JavaScript and a small state machine to opreate on the XMLHTTP extension to retrieve a file and display its contents on load.

In XForms, the instance we saw in the previous example can be initialized from a resource (URI) at load time simply by using a src attribute.

<html ...>
  <head>
    <title>instance src</title>
    <xf:model>
      <xf:instance src="test.xml" />
    </xf:model>
  </head>
  <body>

    <p><xf:output ref="/data" /></p>

  </body>
</html>

XHR+JavaScript vs. Submission

In Combining the Two = AJAX, Daniel shows how to use a click to trigger the loading of the resource from the server, and then DOM mutation of a location specified by ID within the HTML document to display the result.

In XForms, you can use the submission element as to list the resource to load and the instance where to put the data returned. Because of the MVC model of XForms, the output from the first example automatically notices the change and displays the updated data.

Note that the XForms example has no scripting in it; it's all declarative.

<html>
  <head>
    <title>instance src</title>
    <xf:model>

      <xf:instance>
        <data xmlns="" />
      </xf:instance>

      <xf:submission id="get-data" method="get" action="test.xml" replace="instance" />
    </xf:model>

  </head>
  <body>

    <p>
      <xf:submit submission="get-data">
        <xf:label>Push Me</xf:label>
      </xf:submit>
    </p>

    <p>
      <xf:output ref="/data" mediatype="text/html" />
    </p>

  </body>
</html>

AJAX is Cool; XForms is Cool too

In his Cool AJAX Example, Daniel shows a server-side PHP script which acts a a resource to HTML snippets for validating username choices, and a Javascript+DOM Mutation approach to retrieve the results of this script via XHR and dispaly them inline.

An XForms approach to the validation issue would be simpler if it used the client-side XForms validation declarations to declare checks for length and membership in a list directly, but I decided to skip the simplification, and hew as close as possible to the original, for the purpose of comparison.

I did make some minor changes; the validate script returns an XML document describing the intent rather than an HTML snippet. The styling and presentation is done entirely in the HTML file, based on CSS classes declared on the output elements, each of which binds to a different validation condition. (In Daniel's example, the CSS refers to element ids that are produced within the script data.)

<html ...>
  <head>
    <title>XForms is cool</title>
    <xf:model>
      <xf:instance id="main">
	<data xmlns="">
	  <name />
	</data>
      </xf:instance>

      <xf:instance id="validation">
	<data xmlns="" />
      </xf:instance>

      <xf:submission id="validate" method="get" action="validate.php"
                        replace="instance" instance="validation" />
    </xf:model>

    <style type="text/css">
      .warn { color: #C20000; background: #FFC5A8 }
      .notice  { color: #248A01; background: #CCFFBC }
    </style>
  </head>
  <body>

    <h1>Please choose your username:</h1>

    <xf:group>
      <xf:input ref="name" incremental="true">
	<xf:send ev:event="xforms-value-changed" submission="validate" />
      </xf:input>
      <br />
      <xf:output class="warn" ref="instance('validation')/warning" mediatype="text/html" />
      <xf:output class="notice" ref="instance('validation')/notice" mediatype="text/html" />

    </xf:group>

  </body>
</html>

shibumi

Point 5 of Daniel's article says, "Doing AJAX by hand is certainly possible and helps understanding it, but using a good library makes the whole experience more comfortable."

The shibumiscript approach is to consider XForms a way of expressing intent, and letting AJAX do the work for you.


Back to shibumuscript [shibumi]