XForms/Displaying Save Results

Motivation

edit

After a save, you want to display a line at the end of your form to confirm that the results have been saved to the server. You also want to notify the user of any errors after a save.

Method

edit

We will use the submission element to save the data and return the save results. We will use the <xf:group> to show either a success (in green) or a failure (in red).

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fr="http://orbeon.org/oxf/xml/form-runner" xmlns:xxforms="http://orbeon.org/oxf/xml/xforms" xmlns:xf="http://www.w3.org/2002/xforms">
    <head>
        <title>Save Test</title>
        <xf:model>
            <xf:instance xmlns="" id="save-data">
                <formdata form-id="unit-tests-save-test">
                    <first-name>Dan</first-name>
                    <last-name>McCreary</last-name>
                </formdata>
            </xf:instance>
            <xf:instance xmlns="" id="save-results">
                <save-results>
                    <message>No Save Results Yet</message>
                </save-results>
            </xf:instance>
            <xf:submission id="save-submission" ref="instance('save-data')" 
                method="post" resource="http://localhost:8088/exist/rest/db/apps/grants/scripts/save.xq" 
                replace="instance"
                instance="save-results">
                <xf:action ev:event="xforms-submit-done">
                    <xf:message>Save Done</xf:message>
                </xf:action>
                <xf:action ev:event="xforms-submit-error">
                    <xf:message>Save Failed</xf:message>
                </xf:action>
            </xf:submission>
            <xf:submission id="save-submission-see-save-results" ref="instance('save-data')" 
                method="post" resource="http://localhost:8088/exist/rest/db/apps/grants/scripts/save.xq" replace="instance" 
                instance="save-results">
                <xf:action ev:event="xforms-submit-done">
                    <xf:message>Save Done</xf:message>
                </xf:action>
                <xf:action ev:event="xforms-submit-error">
                    <xf:message>Save Failed</xf:message>
                </xf:action>
            </xf:submission>
        </xf:model>
        <style type="text/css">
            .success {color: green; background-color: lightgreen;}
            .failure {color: red; background-color: pink;}
        </style>
    </head>
    <body>
        <xf:input ref="first-name">
            <xf:label>First name:</xf:label>
        </xf:input>
        <br/>
        <xf:input ref="last-name">
            <xf:label>Last name:</xf:label>
        </xf:input>
        <a href="http://localhost:8088/exist/rest/db/apps/xforms/scripts/save.xq">Save URL</a>
        <div class="save-controls">
            <xf:submit submission="save-submission" appearance="xxforms:primary" class="button-margin-top">
                <xf:label>Save and Validate</xf:label>
            </xf:submit>
            <xf:submit submission="save-submission-see-save-results" class="button-margin-top">
                <xf:label>Save See Save Results</xf:label>
            </xf:submit>
        </div>
        <xf:group ref="instance('save-results')/.[@code='200']">
            <div class="success">
               <xf:output ref="instance('save-results')//message"/>
            </div>
        </xf:group>
        <xf:group ref="instance('save-results')/.[@code='400']">
            <div class="failure">
                <xf:output ref="instance('save-results')//message"/>
            </div>
        </xf:group>
    </body>
</html>

Sample XQuery

edit
xquery version "1.0";
import module namespace config= "http://danmccreary.com/config" at "../modules/config.xqm";

declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare namespace xf="http://www.w3.org/2002/xforms";
declare namespace dc="http://gov/grantsolutions/dc";

let $log := util:log-system-out('running save.xq')
(: get-data() returns the document node.  We want the root node :)
let $formdata := request:get-data()/*

(: check to make sure we have valid post data :)
return
  if (not($formdata))
     then <save-results code="400">No Post Data</save-results>
     else 

let $save-data-collection := concat($config:app-home-collection, '/save-data')

let $form-id :=
   if (exists($formdata/@code))
      then $formdata/@code/string()
      else
        if (exists($formdata/@form-id))
            then $formdata/@form-id/string()
            else 'unknown-form-id'
      
let $file-name := concat($form-id, '.xml')
let $path-name := concat($save-data-collection, '/', $file-name)

let $overwrite :=
  if (doc-available($path-name))
    then true()
    else false()
    
let $store := xmldb:store($save-data-collection, $file-name, $formdata)

return
<save-results code="200">
    {if ($overwrite)
        then <message>Document updated at {$path-name}</message>
        else <message>New document saved to {$path-name}</message>
    }
</save-results>