Skip to content

Instantly share code, notes, and snippets.

@dmccreary
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmccreary/1f342729337d7685f6b0 to your computer and use it in GitHub Desktop.
Save dmccreary/1f342729337d7685f6b0 to your computer and use it in GitHub Desktop.
Example Orbeon form for disable Save when not dirty or invalid. Depends on the Orbeon error-summary control.
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://orbeon.org/oxf/xml/formatting"
xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fr="http://orbeon.org/oxf/xml/form-runner" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xxforms="http://orbeon.org/oxf/xml/xforms" xmlns:widget="http://orbeon.org/oxf/xml/widget">
<head>
<!-- fr:error-summary has errors-count-ref which can store number of errors to data. You can use that data to enable button. -->
<title>Example of Visit All Failing</title>
<style type="text/css">
.orbeon .xforms-control {display:block; padding:5px;}
/* not needed in a table display:inline-block; width:10ex; text-align:right; */
.orbeon .xforms-label {font-weight:bold!important; display:inline-block; margin-right: 1ex;}
.xforms-control .xforms-input-input {text-align: right; width:10ex;}
/* don't show initial alerts until after visited */
.orbeon .xforms-control .xforms-alert {display: none;}
.xforms-control.xforms-invalid.xforms-visited .xforms-alert {display: inline-block;}
/* lets put our labels to the right and in the middle of the th cells in the first column */
.orbeon table tbody tr th * {text-align:right;}
.orbeon table tbody tr th {vertical-align: middle!important;}
.orbeon table thead tr th {background:silver; text-align:center!important; font-weight:bold!important;}
/* make the padding of elements in the table cell smaller */
.orbeon table.fr-error-list tbody tr td * {padding:0;}
.orbeon fieldset legend {text-align:left;}
/* style of required field - note that with no label the CSS must be before the control, not the label! */
.orbeon .xforms-required .xforms-input-input {
background-color: moccasin!important;
border: solid gray 1px;
}
.orbeon .xforms-control .xforms-label:after {
content: "*";
color: red;
font-size:large;
}
</style>
<xf:model>
<!-- Main form instance -->
<xf:instance xmlns="" id="save-data">
<data>
<integer1/>
<integer2/>
<integer3/>
</data>
</xf:instance>
<xf:bind id="required" ref="instance('save-data')/*" required="true()"/>
<!-- note that xf:integer allows null values to be valid -->
<xf:bind id="integer" ref="instance('save-data')/*" type="xf:integer"/>
<!-- Control instance -->
<xf:instance id="control-instance">
<control xmlns="">
<!-- should be false initially, just for testing -->
<dirty>true</dirty>
<save-trigger/>
<!-- Note that we have to initialize this to 0 for the initial compare to work. Type should be integer. -->
<error-count>0</error-count>
</control>
</xf:instance>
<!-- Disable the save button when the data is dirty or we have validation errors -->
<xf:bind nodeset="instance('control-instance')/save-trigger" readonly="not(../dirty = 'true') or xs:integer(instance('control-instance')/error-count) gt 0"/>
<!-- Mark data as dirty upon insert/delete -->
<xf:setvalue ev:event="xforms-insert xforms-delete" ref="instance('control-instance')/dirty">true</xf:setvalue>
<!-- Save submission validate turned OFF-->
<xf:submission id="save-submission-no-validate" method="post" replace="none" resource="test:" validate="false">
<!-- Mark data as clean when submission completes -->
<xf:action ev:event="xforms-submit-done">
<xf:setvalue ref="instance('control-instance')/dirty">false</xf:setvalue>
<!-- note that you should only see this message if the form is valid -->
<xf:message>XForms Submit No Validate Done</xf:message>
</xf:action>
</xf:submission>
<!-- Save submission validate turned on (by default)-->
<xf:submission id="save-submission" method="post" replace="none" resource="test:">
<!-- Mark data as clean when submission completes -->
<xf:action ev:event="xforms-submit-done">
<xf:setvalue ref="instance('control-instance')/dirty">false</xf:setvalue>
<!-- note that you should only see this message if the form is valid -->
<xf:message>XForms Submit Validate Done</xf:message>
</xf:action>
</xf:submission>
</xf:model>
</head>
<body>
<p>Demonstration of disabling Save button unless we have invalid or dirty data OR ANY field is not valid.</p>
<xf:group id="error-summary-group">
<!-- Mark data as dirty upon value change -->
<xf:setvalue ev:event="xforms-value-changed" ref="instance('control-instance')/dirty">true</xf:setvalue>
<!-- Controls -->
<xf:input ref="integer1">
<xf:label>Integer 1:</xf:label>
<xf:alert validation="required">Required</xf:alert>
<xf:alert validation="integer">Must be an integer</xf:alert>
</xf:input>
<xf:input ref="integer2">
<xf:label>Integer 2:</xf:label>
<xf:alert validation="required">Required</xf:alert>
<xf:alert validation="integer">Must be an integer</xf:alert>
</xf:input>
<xf:input ref="integer3">
<xf:label>Integer 3:</xf:label>
<xf:alert validation="required">Required</xf:alert>
<xf:alert validation="integer">Must be an integer</xf:alert>
</xf:input>
</xf:group>
<!-- Save button that is read only if the data is not dirty or we have any invalid field -->
<xf:trigger>
<xf:label>Save (No Validate)</xf:label>
<xf:dispatch name="fr-visit-all" targetid="error-summary"/>
<xf:refresh/>
<xf:dispatch name="fr-update" targetid="error-summary"/>
<xf:send ev:event="DOMActivate" submission="save-submission-no-validate"/>
</xf:trigger>
<xf:trigger ref="instance('control-instance')/save-trigger">
<xf:label>Validate Then Save</xf:label>
<xf:dispatch name="fr-visit-all" targetid="error-summary"/>
<xf:refresh/>
<xf:dispatch name="fr-update" targetid="error-summary"/>
<xf:send ev:event="DOMActivate" submission="save-submission"/>
</xf:trigger>
<xf:trigger>
<xf:label>Check All</xf:label>
<xf:action ev:event="DOMActivate">
<xf:dispatch name="fr-visit-all" targetid="error-summary"/>
<xf:refresh/>
<xf:dispatch name="fr-update" targetid="error-summary"/>
</xf:action>
</xf:trigger>
<br/>
<!-- Note that finding out if there are errors depends on the error summary. errors-count-ref must point to an integer. -->
<fr:error-summary observer="error-summary-group" id="error-summary" errors-count-ref="instance('control-instance')/error-count">
<fr:label>Your Form Contains the Following Errors</fr:label>
</fr:error-summary>
<xf:output ref="instance('control-instance')/error-count">
<xf:label>Error Count:</xf:label>
</xf:output>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment