[form-builder]
Ok, so this has become two questions due to a problem trying to get some example code to work.
I have a form that has an action on a Password
control that is hooked onto the password-check
event to run some custom actions and submissions that event is dispatched to that control. The form builder submit button has been configured with custom actions, one of which is to dispatch the password-check
event to the Password
control. This all works.
As there is a need to create multiple forms with this same Password
control on them, I want to move the section containing the Password
control and its associated actions and submissions to a section library. I have moved the section to the section library for the application and rebuilt the form using the section template.
The published form includes the required submissions and actions as expected, but the dispatched event does not reach the Password
control (in the debug logs, I can see the custom actions running and the event being dispatched, but it doesn't find(?) the control (see below):
2016-03-15 12:07:10,439 DEBUG XFormsServer - process: combining with then {action: "ActionNode(xf:dispatch,Map(Some(name) -> password-check, Some(targetid) -> Password-control))"}
2016-03-15 12:07:10,439 DEBUG XFormsServer - start process: running action {action: "ActionNode(xf:dispatch,Map(Some(name) -> password-check, Some(targetid) -> Password-control))"}
2016-03-15 12:07:10,439 DEBUG XFormsServer - end process: running action {time (ms): "0", result: "success"}
(as opposed to below):
2016-03-15 12:09:26,385 DEBUG XFormsServer - start process: running action {action: "ActionNode(xf:dispatch,Map(Some(name) -> password-check, Some(targetid) -> Password-control))"}
2016-03-15 12:09:26,386 DEBUG XFormsServer - start dispatching {name: "password-check", target: "SignOff-control≡xf-637≡Password-control"}
2016-03-15 12:09:26,386 DEBUG XFormsServer - start handler {name: "password-check", phase: "target", observer: "SignOff-control≡xf-637≡Password-control"}
2016-03-15 12:09:26,386 DEBUG XFormsServer - interpreter - start executing {action name: "xf:action"}
2016-03-15 12:09:26,386 DEBUG XFormsServer - interpreter - start executing {action name: "xxf:script"}
To include some source code in this question, I created a form and library with just the Password
control (and a test button), but noticed that the actions aren't being included in the published form (form1).
So the main question is how do I get the event to be dispatched to the Password
control if the Password
control is in an included section from a library?
The sub question is why weren't actions included in the published version of form1? I saw "Actions involving controls in a given section are automatically included with the section template, along with the services called by the actions.", which I thought would have been the case with the example code below.
properties-local.xml
<property as="xs:string" name="oxf.fr.detail.buttons.TEST.*">
cancel
submit
</property>
<property as="xs:string" name="oxf.fr.detail.process.submit.TEST.*">
xf:dispatch(name = "password-validate", targetid = "field-control")
then require-valid
then xf:send("StoreDocument-submission")
</property>
TEST/library
<xh:html xmlns:xh="http://www.w3.org/1999/xhtml"
xmlns:xxi="http://orbeon.org/oxf/xml/xinclude"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:saxon="http://saxon.sf.net/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fb="http://orbeon.org/oxf/xml/form-builder"
xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
xmlns:sql="http://orbeon.org/oxf/xml/sql"
xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:exf="http://www.exforms.org/exf/1-0">
<xh:head>
<xh:title>Test Library</xh:title>
<xf:model id="fr-form-model" xxf:expose-xpath-types="true">
<!-- Main instance -->
<xf:instance id="fr-form-instance" xxf:exclude-result-prefixes="#all">
<form>
<Section>
<field/>
<button/>
</Section>
</form>
</xf:instance>
<!-- Bindings -->
<xf:bind id="fr-form-binds" ref="instance('fr-form-instance')">
<xf:bind id="Section-bind" name="Section" ref="Section">
<xf:bind id="field-bind" name="field" ref="field"/>
<xf:bind id="button-bind" ref="button" name="button"/>
</xf:bind>
</xf:bind>
<!-- Metadata -->
<xf:instance xxf:readonly="true" id="fr-form-metadata" xxf:exclude-result-prefixes="#all">
<metadata>
<application-name>TEST</application-name>
<form-name>library</form-name>
<title xml:lang="en">Test Library</title>
<description xml:lang="en"/>
<singleton>false</singleton>
</metadata>
</xf:instance>
<!-- Attachments -->
<xf:instance id="fr-form-attachments" xxf:exclude-result-prefixes="#all">
<attachments>
<css mediatype="text/css" filename="" size=""/>
<pdf mediatype="application/pdf" filename="" size=""/>
</attachments>
</xf:instance>
<!-- All form resources -->
<!-- Don't make readonly by default in case a service modifies the resources -->
<xf:instance id="fr-form-resources" xxf:readonly="false" xxf:exclude-result-prefixes="#all">
<resources>
<resource xml:lang="en">
<Section>
<label>Section</label>
</Section>
<field>
<label/>
<hint/>
</field>
<button>
<label>Button</label>
<hint/>
</button>
</resource>
</resources>
</xf:instance>
<!-- Utility instances for services -->
<xf:instance id="fr-service-request-instance" xxf:exclude-result-prefixes="#all">
<request/>
</xf:instance>
<xf:instance id="fr-service-response-instance" xxf:exclude-result-prefixes="#all">
<response/>
</xf:instance>
<xf:action id="field-revalidate" ev:event="password-check" ev:observer="field-control">
<xxf:script>
console.log('running revalidate');
</xxf:script>
</xf:action>
<xf:action id="button-action" ev:event="DOMActivate" ev:observer="button-control">
<xf:dispatch name="password-check" targetid="field-control"/>
</xf:action>
</xf:model>
</xh:head>
<xh:body>
<fr:view>
<fr:body xmlns:xbl="http://www.w3.org/ns/xbl"
xmlns:oxf="http://www.orbeon.com/oxf/processors"
xmlns:p="http://www.orbeon.com/oxf/pipeline">
<fr:section id="Section-control" bind="Section-bind">
<xf:label ref="$form-resources/Section/label"/>
<fr:grid>
<xh:tr>
<xh:td>
<xf:input id="field-control" bind="field-bind">
<xf:label ref="$form-resources/field/label"/>
<xf:hint ref="$form-resources/field/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:input>
</xh:td>
<xh:td>
<xf:trigger id="button-control" bind="button-bind">
<xf:label ref="$form-resources/button/label"/>
<xf:hint ref="$form-resources/button/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:trigger>
</xh:td>
</xh:tr>
</fr:grid>
</fr:section>
</fr:body>
</fr:view>
</xh:body>
</xh:html>
TEST/form1
<xh:html xmlns:xh="http://www.w3.org/1999/xhtml" xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xxi="http://orbeon.org/oxf/xml/xinclude"
xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
xmlns:exf="http://www.exforms.org/exf/1-0"
xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
xmlns:saxon="http://saxon.sf.net/"
xmlns:sql="http://orbeon.org/oxf/xml/sql"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:fb="http://orbeon.org/oxf/xml/form-builder">
<xh:head>
<xh:title>Form 1</xh:title>
<xf:model id="fr-form-model" xxf:expose-xpath-types="true">
<!-- Main instance -->
<xf:instance id="fr-form-instance" xxf:exclude-result-prefixes="#all">
<form>
<Section>
<field/>
<button/>
</Section>
</form>
</xf:instance>
<!-- Bindings -->
<xf:bind id="fr-form-binds" ref="instance('fr-form-instance')">
<xf:bind id="Section-bind" ref="Section" name="Section"/>
</xf:bind>
<!-- Metadata -->
<xf:instance xxf:readonly="true" id="fr-form-metadata" xxf:exclude-result-prefixes="#all">
<metadata>
<application-name>TEST</application-name>
<form-name>form1</form-name>
<title xml:lang="en">Untitled Form</title>
<description xml:lang="en"/>
<singleton>false</singleton>
</metadata>
</xf:instance>
<!-- Attachments -->
<xf:instance id="fr-form-attachments" xxf:exclude-result-prefixes="#all">
<attachments>
<css mediatype="text/css" filename="" size=""/>
<pdf mediatype="application/pdf" filename="" size=""/>
</attachments>
</xf:instance>
<!-- All form resources -->
<!-- Don't make readonly by default in case a service modifies the resources -->
<xf:instance id="fr-form-resources" xxf:readonly="false" xxf:exclude-result-prefixes="#all">
<resources>
<resource xml:lang="en">
<Section>
<label>Section</label>
<help/>
</Section>
</resource>
</resources>
</xf:instance>
<!-- Utility instances for services -->
<xf:instance id="fr-service-request-instance" xxf:exclude-result-prefixes="#all">
<request/>
</xf:instance>
<xf:instance id="fr-service-response-instance" xxf:exclude-result-prefixes="#all">
<response/>
</xf:instance>
</xf:model>
</xh:head>
<xh:body>
<fr:view>
<fr:body xmlns:xbl="http://www.w3.org/ns/xbl"
xmlns:oxf="http://www.orbeon.com/oxf/processors"
xmlns:p="http://www.orbeon.com/oxf/pipeline">
<fr:section id="Section-control" bind="Section-bind">
<xf:label ref="$form-resources/Section/label"/>
<component:Section xmlns:component="http://orbeon.org/oxf/xml/form-builder/component/TEST/library"
xmlns="http://orbeon.org/oxf/xml/form-builder"
xmlns:xxbl="http://orbeon.org/oxf/xml/xbl"
xmlns:fbf="java:org.orbeon.oxf.fb.FormBuilder"/>
</fr:section>
</fr:body>
</fr:view>
</xh:body>
</xh:html>
You can't target a control inside a section template with an xf:dispatch()
, as controls within section templates are "insulated" from the "outside world" using XBL. (Consider that you could have multiple instance of a section template in a form, which means that you can't use the control names you picked when creating the section template to refer to those controls in the form.)
We could imagine some version of xf:dispatch()
that could target controls inside a section template, but it would need to also take the name of that section template as a parameter. As things stand, here is a workaround you could use:
xf:dispatch()
, use xf:setvalue()
and increment the value of the field by 1.xforms-value-changed
on the output field, dispatch the password-check
event. That will work since it is done from within the section template.