XForms Sample


Most of the forms in this chapter have been small to highlight one or more XForms features. In order to show a more realistic example, I'll create an expense report form (see Figure 23-20). This demonstrates how many of the features of XForms interact to enable you to create not just simple forms, but full- blown XML applications.

image from book
Figure 23-20

The first step in creating an XForms form is to define the model. In order to benefit from the automatic data validation and improved controls, I decided to base the form on a schema. In addition, the instance is loaded from a separate file. This means you can easily change the default instance by editing this secondary file. So that I don't need to create a server-side component to process the generated XML, the submission is set to use PUT to write a local file. You may need to adjust the paths to these three files for testing.

      <xf:model schema="http://server/expenseReport.xsd">        <xf:instance src="/books/2/381/1/html/2/http://server/baseReport.xml" />        <xf:submission  method="put"            action="file:///C:/temp/output.xml"            includenamespaceprefixes="exp" />      </xf:model> 

The four fields at the bottom of the form that provide the summary data are populated using binding expressions. This ensures that, as the data changes, these fields are updated automatically. The binding expression ensures the data is displayed using the correct data type and provides the calculation that determines the value. Each of the four expressions is identical, with the exception of the target field and the expense type to sum:

      <xf:bind nodeset="exp:summary/exp:travelSummary"           type="xs:decimal"           calculate="sum(//exp:expenseItem/exp:amount[../exp:type='Travel'])" /> 

Lookup fields are frequently used when designing forms. These provide a set of selections for the user, reducing data entry errors and increasing data consistency. The data for the list part of the lookup field may be part of the primary instance, but it is often necessary to provide the data from elsewhere. This is done by adding secondary instances to the model. You refer to these later by referencing the id attribute of the instance. The department and expense type drop-down lists are populated using the following instances:

      <xf:instance >        <departments>          <department >            <name>Development</name>          </department>          <department >            <name>Sales</name>          </department>        </departments>      </xf:instance>      <xf:instance >        <expenseType xmlns="">          <option value="Travel" />          <option value="Entertainment" />          <option value="Meal" />          <option value="Miscellaneous" />        </expenseType>      </xf:instance>      ...      <xf:select1 ref="exp:dept">        <xf:label>Dept:</xf:label>        <xf:itemset nodeset="instance('departments')/department">          <xf:label ref="name" />          <xf:value ref="@id" />        </xf:itemset>      </xf:select1> 

The central section of the form is composed of a repeating section for each expense item. Adding a new item to the list is done through a trigger. This uses the insert element to add a new item to the appropriate nodeset.

      <xf:repeat  nodeset="exp:expenseItem">        <xf:input ref="exp:date" />        <xf:input ref="exp:amount" />        <xf:select1 ref="exp:type">          <xf:itemset nodeset="instance('expenseTypes')/option">            <xf:label ref="@value" />            <xf:value ref="@value" />          </xf:itemset>        </xf:select1>        <xf:input ref="exp:description" />      </xf:repeat>      <hr />      <xf:trigger>        <xf:label>Insert item</xf:label>        <xf:action ev:event="DOMActivate">          <xf:insert position="after" nodeset="exp:expenseItem"          at="index('lineitems')" />        </xf:action>      </xf:trigger> 

Listing 23-15 shows the complete source for the expense report form.

Listing 23-15: Complete expense report form

image from book
      <?xml version="1.0" encoding="utf-8"?>      <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:xsi="http://www.w3.org/2001/XMLSchema-instance"      xmlns:xs="http://www.w3.org/2001/XMLSchema"      xmlns:exp="http://example.com/expenseReport">        <head>        <xf:model schema="http://server/expenseReport.xsd">          <xf:instance src="/books/2/381/1/html/2/http://server/baseReport.xml" />          <xf:submission  method="put"          action="file:///C:/temp/output.xml"          includenamespaceprefixes="exp" />          <xf:bind nodeset="exp:summary/exp:travelSummary"          type="xs:decimal"          calculate="sum(//exp:expenseItem/exp:amount[../exp:type='Travel'])" />          <xf:bind nodeset="exp:summary/exp:entSummary"          type="xs:decimal"          calculate="sum(//exp:expenseItem/exp:amount[../exp:type='Entertainment'])" />          <xf:bind nodeset="exp:summary/exp:mealSummary"          type="xs:decimal"          calculate="sum(//exp:expenseItem/exp:amount[../exp:type='Meal'])" />          <xf:bind nodeset="exp:summary/exp:miscSummary"          type="xs:decimal"          calculate="sum(//exp:expenseItem/exp:amount[../exp:type='Miscellaneous'])" />      <xf:instance >            <departments xmlns=""            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">              <department >                <name>Development</name>              </department>              <department >                <name>Sales</name>              </department>            </departments>          </xf:instance>          <xf:instance >            <expenseType xmlns="">              <option value="Travel" />              <option value="Entertainment" />              <option value="Meal" />              <option value="Miscellaneous" />            </expenseType>          </xf:instance>        </xf:model>        <link href="sample.css" type="text/css" rel="stylesheet">        </link>      </head>      <body>        <div >          <div >Expense Report</div>          <div >            <xf:group ref="exp:employee">              <xf:input ref="exp:name">                <xf:label>Employee:</xf:label>              </xf:input>              <xf:input ref="exp:employeeID">                <xf:label>Employee ID:</xf:label>              </xf:input>              <xf:select1 ref="exp:dept">              <xf:label>Dept:</xf:label>              <xf:itemset nodeset="instance('departments')/department">                <xf:label ref="name" />                <xf:value ref="@id" />              </xf:itemset>            </xf:select1>          </xf:group>          <xf:group>            <xf:input ref="exp:date">              <xf:label>Date:</xf:label>            </xf:input>            <br />            <xf:input ref="exp:purpose">              <xf:label>Purpose:</xf:label>            </xf:input>            <br />            <xf:group>              <xf:input ref="exp:startDate">                <xf:label>Start Date:</xf:label>              </xf:input>              <xf:input ref="exp:endDate">                <xf:label>End Date:</xf:label>              </xf:input>            </xf:group>          </xf:group>        </div>        <hr />        <xf:repeat  nodeset="exp:expenseItem">          <xf:input ref="exp:date" />          <xf:input ref="exp:amount" />          <xf:select1 ref="exp:type">            <xf:itemset nodeset="instance('expenseTypes')/option">              <xf:label ref="@value" />              <xf:value ref="@value" />            </xf:itemset>          </xf:select1>          <xf:input ref="exp:description" />        </xf:repeat>        <hr />        <xf:trigger>          <xf:label>Insert item</xf:label>          <xf:action ev:event="DOMActivate">            <xf:insert position="after" nodeset="exp:expenseItem"            at="index('lineitems')" />          </xf:action>        </xf:trigger>        <div >          <xf:group ref="exp:summary">             <xf:label>               <h3>Category Summaries</h3>             </xf:label>             <xf:output ref="exp:travelSummary">               <xf:label>Travel:</xf:label>             </xf:output>                <br />                <xf:output ref="exp:entSummary">                  <xf:label>Entertainment:</xf:label>                </xf:output>                <br />                <xf:output ref="exp:mealSummary">                  <xf:label>Meal:</xf:label>                </xf:output>                <br />                <xf:output ref="exp:miscSummary">                  <xf:label>Miscellaneous:</xf:label>                </xf:output>                <br />              </xf:group>            </div>            <div >              <xf:submit submission="saveXML">                <xf:label>Save</xf:label>              </xf:submit>            </div>          </div>        </body>      </html> 
image from book




Professional XML
Professional XML (Programmer to Programmer)
ISBN: 0471777773
EAN: 2147483647
Year: 2004
Pages: 215

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net