<?php
/**
* PhpXforms usage example.
* The example should be run in FireFox with XForms extension installed.
* (Possibly will run in X-Smiles)
*
* @author Victor Bolshov <crocodile2u@yandex.ru>
* @package PHP_XFORMS
* @subpackage EXAMPLE
*
*/
function fake_validation_callback($data) {
if (rand(0, 100) > 50) throw new Exception("Server-side validation error!");
}
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
include_once dirname(__FILE__) . '/../PhpXforms.php';
$px = new PhpXforms(dirname(__FILE__) . '/schema.xsd');
$px->setValidatorCallback('fake_validation_callback');
$px->setDefaultExceptionHandler();
$px->setDefaultSuccessProcessor();
$px->run();
exit();
}
header('Content-Type: application/xhtml+xml; charset=utf-8');
echo "<?xml version='1.0' encoding='utf-8' ?>\n";
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xi="http://www.w3.org/2001/XInclude">
<head>
<title>PhpXforms Example</title>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<h1>PhpXforms Example</h1>
<!--The model.
This is the heart-concept of XForms, which allows for separating business-logic from
presentation.
Validation of data on client/server is done with a help of XMLSchema
(pay attention to the "schema" attribute) -->
<xf:model id="theOnlyModel" schema="schema.xsd">
<!-- 1. Instance documents.
Instance documents are arbitrary XML documents,
containing data that the form will work with.
The instance documents may be specified as URLs,
but in this example I use inline documents -->
<!-- 1.1. errorList instance data are not submitted.
They are used just to provide the user with server-side validation/processing error messages
(if any) -->
<xf:instance id="errorList" xmlns="">
<errorList />
</xf:instance>
<!-- 1.2. This is our main instance.
The data from this instance will be submitted to server,
validated and processed -->
<xf:instance id="data" xmlns="">
<article>
<publishdate>2006-09-05</publishdate>
<title></title>
<content></content>
</article>
</xf:instance>
<!-- 2. The binds.
Here we bind data pieces (specified by the "nodeset" attribute, with a help of XPath expressions) -
to their datatypes. We may also specify a condition on which a data piece is required
(see XForms specification or "XForms Essentials" book by Micah Dubinko for more details)
id="publishdate" - we may reference this bind with IDref "publishdate"
nodeset="instance('data')/publishdate" - defines data to be bound (here we bind <publishdate>
element from instance with id="data")
type="xs:date" - XMLSchema type
required="true()" - this data piece is alwayse required.
(notice the parethesis, and remember you
can specify any XPath expression here) -->
<xf:bind id="publishdate" nodeset="instance('data')/publishdate" type="xs:date" required="true()" />
<xf:bind id="title" nodeset="instance('data')/title" type="title" required="true()" />
<xf:bind id="content" nodeset="instance('data')/content" type="content" required="true()" />
<!-- 3. Submission.
Here we define what, where and how to submit
id="sendData" we may reference this submission with IDref "sendData"
ref="instance('data')" - what to submit
action="" - where to submit ("" means the current URL)
method="post" - data transfer method
mediatype="application/xml" - how to submit (well, actually, application/xml is the default so we could
skip this attribute)
includenamespaceprefixes="" - strip namespace definitions from submitted data (as I have noticed, this is often needed)
replace="instance" - the data *read* from server should be a valida XML and they will replace a certain instance
document in our model
instance="errorList" - the instance to replace (see "replace" attribute) -->
<xf:submission id="sendData"
ref="instance('data')"
action=""
method="post"
mediatype="application/xml"
includenamespaceprefixes=""
replace="instance"
instance="errorList" />
</xf:model>
<script language="javascript"><![CDATA[
/**
* Here is a little JavaScript code. I use something like this in my XForms,
* because there are some limitations in W3C specifications for XForms and XMLEvents, so
* I need a little scripting.
*
* This function will be called after xforms-submit is done.
* It will check the 'errorList' instance document in our model,
* and, in case it finds no <error> elements below it,
* it will show a modal window saying 'No server-side errors occured during validation'
*
* The JS code uses features special for Mozilla XForms implementation!
*/
function performOnSuccess() {
var inst = document.getElementById('theOnlyModel').getInstanceDocument('errorList')// will work in Mozilla
if (! inst.documentElement.getElementsByTagName('error').length)
{
alert('No server-side errors occured during validation')
}
}
window.addEventListener('xforms-submit-done', performOnSuccess, false)
]]></script>
<div style="width:70%">
<!-- Here is our XForms layout -->
<!-- Display server-side validation/processing errors -->
<ul class="errorList" id="errorListContainer">
<xf:repeat nodeset="instance('errorList')/error">
<li><xf:output ref="."/></li>
</xf:repeat>
</ul>
<!-- Input controls -->
<xf:input bind="publishdate" class="date">
<xf:label>Example date field: </xf:label>
</xf:input>
<xf:input bind="title" class="text">
<xf:label>Example title: </xf:label>
<xf:action ev:event="xforms-invalid">
<xf:message level="modal">Minimum 1, maximum 255 symbols</xf:message>
</xf:action>
</xf:input>
<xf:textarea bind="content">
<xf:label>Example text: </xf:label>
</xf:textarea>
<!-- And the submit button -->
<xf:submit submission="sendData">
<xf:label>Save</xf:label>
</xf:submit>
</div>
<h2>Note:</h2>
<ol>
<li>To run the example you will need Firefox web-browser with XForms extension.
Both are free software, and you may download them at
<a href="http://www.mozilla.com/">http://www.mozilla.com/</a> and
<a href="https://addons.mozilla.org/firefox/824/">https://addons.mozilla.org/firefox/824/</a>
respectively.
</li>
<li>The server-side validation in this example is just a fake one. It will randomly generate an error or
pass validation.</li>
</ol>
</body>
</html>
|