I have the control shown below which has a repeating grid in it that contains 5 other elements. When the control gets an xforms-enabled event it adds a new entry to its model and then displays the control. The repeat should show a set of the 5 controls for each entry in the model with the 2nd and subsequent entries read only.
If I use this in a form template with a model that already has one entry in it I see two sets of controls displayed as expected but both are showing the same data, the second set of data. The data that was inserted on enable is not shown. Examination of the model via the inspector shows that the model does contain two different sets of data like so: <progress-note> <note> <user>somebody</user> <date>Wednesday April 5, 2017</date> <time>22:12:05</time> <remark></remark> <ward></ward> </note> <note> <user>some user</user> <date>A Date</date> <time>10:23:11</time> <remark>Some text</remark> <ward>A ward</ward> </note> </progress-note> so the insert must have worked but the grid display is not showing it. Any ideas what I've done wrong here? <xbl:xbl 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:ev="http://www.w3.org/2001/xml-events" xmlns:xxf="http://orbeon.org/oxf/xml/xforms" xmlns:fr="http://orbeon.org/oxf/xml/form-runner" xmlns:fb="http://orbeon.org/oxf/xml/form-builder" xmlns:xbl="http://www.w3.org/ns/xbl" xmlns:xxbl="http://orbeon.org/oxf/xml/xbl" xmlns:im="http://www.infomedix.com.au/cpf/forms"> <fb:metadata> <fb:display-name lang="en">CPF Controls</fb:display-name> </fb:metadata> <xbl:binding element="im|progress-note" id="im-progress-note" xxbl:mode="lhha custom-lhha binding"> <metadata xmlns="http://orbeon.org/oxf/xml/form-builder"> <display-name lang="en">Progress Note</display-name> <templates> <view> <im:progress-note> <xf:label ref="" /> <xf:hint ref="" /> <xf:help ref="" /> <xf:alert ref="" /> </im:progress-note> </view> </templates> </metadata> <xbl:template> <!-- Local model --> <xf:model id="progress-note-model"> <xf:instance id="progress-note-instance"> <note> <user /> <date /> <time /> <remark /> <ward /> </note> </xf:instance> <xf:instance xxf:readonly="true" xxf:exclude-result-prefixes="#all" id="noteList-template"> <note> <user /> <date /> <time /> <remark /> <ward /> </note> </xf:instance> <xf:bind id="noteList-bind" ref="xxf:binding('im-progress-note')" name="progress-note"> <xf:bind id="note-bind" ref="note" name="note" readonly="position() > 1"> <xf:bind id="user-bind" ref="user" name="user" /> <xf:bind id="date-bind" ref="date" name="date" /> <xf:bind id="time-bind" ref="time" name="time" /> <xf:bind id="ward-bind" ref="ward" name="ward" xxf:whitespace="trim" /> <xf:bind id="remark-bind" ref="remark" name="remark"> </xf:bind> </xf:bind> </xf:bind> </xf:model> <xf:group id="im-component-group" model="progress-note-model"> <xf:action ev:event="xforms-enabled" ev:target="im-component-group" if="contains('new edit test',fr:mode()) and not(fr:is-design-time())"> <xf:insert context="xxf:binding('im-progress-note')" origin="instance('noteList-template')" /> <xf:setvalue ref="xxf:binding('im-progress-note')/note/user" value="concat('some','body')" /> <xf:setvalue ref="xxf:binding('im-progress-note')/note/date" value="format-date(current-date(),'[F] [MNn] [D], [Y0001]')" /> <xf:setvalue ref="xxf:binding('im-progress-note')/note/time" value="format-time(current-time(),'[H01]:[m01]:[s01]')" /> </xf:action> <xf:output value="xxf:label('im-progress-note')"/> <xh:br/> <fr:grid id="noteList-control" bind="noteList-bind" repeat="content" apply-defaults="false" readonly="true"> <xh:tr> <xh:td> <xf:output id="user-control" bind="user-bind"> </xf:output> </xh:td> <xh:td> <xf:output id="date-control" bind="date-bind"> </xf:output> </xh:td> <xh:td> <xf:output id="time-control" bind="time-bind"> </xf:output> </xh:td> </xh:tr> <xh:tr> <xh:td colspan="3"> <xf:input id="ward-control" bind="ward-bind"> </xf:input> </xh:td> </xh:tr> <xh:tr> <xh:td colspan="3"> <fr:tinymce xmlns:xxbl="http://orbeon.org/oxf/xml/xbl" xmlns:f="http://orbeon.org/oxf/xml/formatting" id="remark-control" bind="remark-bind"> </fr:tinymce> </xh:td> </xh:tr> </fr:grid> </xf:group> </xbl:template> </xbl:binding> </xbl:xbl> |
Administrator
|
Brian,
Just looking at the source, I can't think of anything wrong. Would you be able to create a minimal stand-alone example that I could run here to reproduce the issue? Alex
--
Follow Orbeon on Twitter: @orbeon Follow me on Twitter: @avernet |
Hi Alex,
I can't create a standalone version as it seems to be something to do with the binding into the xbl control. The simplest version of the control I can come up with is shown below as is a simple from (copied from the builder) that uses that control. You would need to deploy the control into your server to reproduce it. The form has a model with two elements pre-inserted in it. The behaviour in this example is that you get the three rows displayed in the control but the first one (inserted via the action on the xforms-ready event in the xbl control) doesn't display its input element and the 2nd and 3rd are not set to readonly as specified by the bind. If I take the insert and setvalue out of the action then it displays two rows with their input elements and the second one is readonly as specified by the bind. It looks like the insert is mucking up the binding somehow when run inside a control. When I do the same thing all in a standalone form it works as it should (see CPF:progressnotes-wounds at http://demo.orbeon.com/demo/fr/orbeon/builder/summary) The control: <xbl:xbl 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:ev="http://www.w3.org/2001/xml-events" xmlns:xxf="http://orbeon.org/oxf/xml/xforms" xmlns:fr="http://orbeon.org/oxf/xml/form-runner" xmlns:fb="http://orbeon.org/oxf/xml/form-builder" xmlns:xbl="http://www.w3.org/ns/xbl" xmlns:xxbl="http://orbeon.org/oxf/xml/xbl" xmlns:im="http://www.infomedix.com.au/cpf/forms"> <fb:metadata> <fb:display-name lang="en">CPF Controls</fb:display-name> </fb:metadata> <xbl:binding element="im|progress-note" id="im-progress-note" xxbl:mode="lhha custom-lhha binding"> <metadata xmlns="http://orbeon.org/oxf/xml/form-builder"> <display-name lang="en">Progress Note</display-name> <templates> <view> <im:progress-note> <xf:label ref="" /> <xf:hint ref="" /> <xf:help ref="" /> <xf:alert ref="" /> </im:progress-note> </view> </templates> </metadata> <xbl:template> <!-- Local model --> <xf:model id="progress-note-model"> <xf:instance id="progress-note-instance"> <note> <remark /> </note> </xf:instance> <xf:instance xxf:readonly="true" xxf:exclude-result-prefixes="#all" id="noteList-template"> <note> <remark /> </note> </xf:instance> <xf:bind id="noteList-bind" ref="xxf:binding('im-progress-note')" name="progress-note"> <xf:bind id="note-bind" ref="note" name="note" readonly="position() > 1"> <xf:bind id="remark-bind" ref="remark" name="remark"/> </xf:bind> </xf:bind> <xf:action ev:event="xforms-ready" if="contains('new edit test',fr:mode()) and not(fr:is-design-time())"> <xf:insert context="xxf:binding('im-progress-note')" origin="instance('noteList-template')" /> <xf:setvalue ref="xxf:binding('im-progress-note')/note/remark" value="concat('some',' text')" /> <xf:message value="concat('mode is ',fr:mode(), ', nodes is ',count(xxf:binding('im-progress-note')/note))"/> </xf:action> </xf:model> <xf:group id="im-component-group" model="progress-note-model"> <xf:var name="binding" value="xxf:binding('im-progress-note')" /> <fr:grid id="noteList-control" bind="noteList-bind" repeat="content" apply-defaults="false" readonly="false" template="instance('noteList-template')"> <xh:tr> <xh:td> <xf:input id="remark-control" bind="remark-bind"> </xf:input> </xh:td> </xh:tr> </fr:grid> </xf:group> </xbl:template> </xbl:binding> </xbl:xbl> and a simple form using it: <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>Untitled Form</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" xxf:index="id"> <form> <section-1> <progress-note> <note> <remark>Some text</remark> </note> <note> <remark>2 Some text</remark> </note> </progress-note> </section-1> </form> </xf:instance> <!-- Bindings --> <xf:bind id="fr-form-binds" ref="instance('fr-form-instance')"> <xf:bind id="section-1-bind" name="section-1" ref="section-1"> <xf:bind id="progress-note-bind" ref="progress-note" name="progress-note"/> </xf:bind> </xf:bind> <!-- Metadata --> <xf:instance xxf:readonly="true" id="fr-form-metadata" xxf:exclude-result-prefixes="#all"> <metadata> <application-name>CPF</application-name> <form-name>progressnotes-wounds</form-name> <title xml:lang="en">Untitled Form</title> <description xml:lang="en"/> <version-comment/> </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 --> <xf:instance xxf:readonly="true" id="fr-form-resources" xxf:exclude-result-prefixes="#all"> <resources> <resource xml:lang="en"> <progress-note> <label>This is a Progress Note </label> <hint>Hint hint...</hint> </progress-note> <section-1> <label>The Section</label> </section-1> </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:p="http://www.orbeon.com/oxf/pipeline" xmlns:oxf="http://www.orbeon.com/oxf/processors"> <fr:section id="section-1-control" bind="section-1-bind"> <xf:label ref="$form-resources/section-1/label"/> <fr:grid> <xh:tr> <xh:td> <im:progress-note xmlns:im="http://www.infomedix.com.au/cpf/forms" xmlns="http://orbeon.org/oxf/xml/form-builder" xmlns:xxbl="http://orbeon.org/oxf/xml/xbl" id="progress-note-control" bind="progress-note-bind"> <xf:label ref="$form-resources/progress-note/label"/> <xf:hint ref="$form-resources/progress-note/hint"/> <xf:alert ref="$fr-resources/detail/labels/alert"/> </im:progress-note> </xh:td> </xh:tr> </fr:grid> </fr:section> </fr:body> </fr:view> </xh:body> </xh:html> |
Forgot to mention, I'm running 2016.3
|
Administrator
|
Hi Brian,
I am: 1. Putting progress-note.xbl in WEB-INF/resources/xbl/im/progress-note.xbl. 2. In properties-local.xml, mapping your namespace to the `im`, so Orbeon Forms can find the XBL. 3. Creating a form in Form Builder, pasting the form.xml source you included earlier. 4. Publish, open the new page, and with this I get: I can see there the missing input in the first row, and the 2 other inputs not being read-only, per your description. The trouble is that you can't make a node in an instance outside of the XBL component read-only from inside an XBL component. Instead, you would need to mirror the bound node in a local instance, have the binds apply to the local instance, and the controls in the XBL use that local instance. If I find some time, I'll try to change your control to do that and post a follow-up. But no guarantee! :) Alex
--
Follow Orbeon on Twitter: @orbeon Follow me on Twitter: @avernet |
Thanks for the explanation Alex.
There is an example in the xbl tutorial document that uses a local model instance and copies it back and forth. I'll see if I can make sense of that and do something similar in my component. brian... |
Administrator
|
OK Brian, then I'll let you have a stab at it, and if for some reason you hit a snag, just post here the XBL you have, and I'll try to help.
Alex
--
Follow Orbeon on Twitter: @orbeon Follow me on Twitter: @avernet |
Hi Alex,
I now have a working version (below). I am using the xforms-ready event to copy the model into the component and then using xforms-value-changed to copy it back out again when changes are made. I think it might be doing too many copies each time as I am listening for value changed on the parent grid object rather than the child as my final form will have multiple modifiable child elements. Does this look like the right way to do this? thanks brian... <xbl:xbl 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:ev="http://www.w3.org/2001/xml-events" xmlns:xxf="http://orbeon.org/oxf/xml/xforms" xmlns:fr="http://orbeon.org/oxf/xml/form-runner" xmlns:fb="http://orbeon.org/oxf/xml/form-builder" xmlns:xbl="http://www.w3.org/ns/xbl" xmlns:xxbl="http://orbeon.org/oxf/xml/xbl" xmlns:im="http://www.infomedix.com.au/cpf/forms"> <fb:metadata> <fb:display-name lang="en">CPF Controls</fb:display-name> </fb:metadata> <xbl:binding element="im|progress-note" id="im-progress-note" xxbl:mode="lhha custom-lhha binding"> <metadata xmlns="http://orbeon.org/oxf/xml/form-builder"> <display-name lang="en">Progress Note</display-name> <templates> <view> <im:progress-note> <xf:label ref="" /> <xf:hint ref="" /> <xf:help ref="" /> <xf:alert ref="" /> </im:progress-note> </view> </templates> </metadata> <xbl:template> <!-- Local model --> <xf:model id="progress-note-model"> <xf:instance id="progress-note-instance"> <progress-note> <note> <remark>Design Time Place Holder Text</remark> </note> </progress-note> </xf:instance> <xf:instance xxf:readonly="true" xxf:exclude-result-prefixes="#all" id="noteList-template"> <note> <remark /> </note> </xf:instance> <xf:bind id="noteList-bind" ref="instance('progress-note-instance')" name="progress-note"> <xf:bind id="note-bind" ref="note" name="note" readonly="position() > 1 or contains('view', fr:mode())"> <xf:bind id="remark-bind" ref="remark" name="remark"/> </xf:bind> </xf:bind> <xf:action ev:event="xforms-ready" if="contains('view',fr:mode()) and not(fr:is-design-time())"> <xf:delete ref="instance('progress-note-instance')/note" /> <xf:insert context="instance('progress-note-instance')" origin="xxf:binding('im-progress-note')/note"/> <!-- <xf:message value="concat('mode is ',fr:mode(), ', nodes is ',count(instance('progress-note-instance')/note))"/> --> </xf:action> <xf:action ev:event="xforms-ready" if="contains('new edit test',fr:mode()) and not(fr:is-design-time())"> <xf:delete ref="instance('progress-note-instance')/note" /> <xf:insert context="instance('progress-note-instance')" origin="xxf:binding('im-progress-note')/note"/> <xf:insert context="instance('progress-note-instance')" origin="instance('noteList-template')" /> <!-- <xf:message value="concat('mode is ',fr:mode(), ', nodes is ',count(instance('progress-note-instance')/note))"/> --> </xf:action> <xf:action ev:event="xforms-value-changed" ev:observer="noteList-control" if="contains('new edit test',fr:mode()) and not(fr:is-design-time())"> <xf:delete ref="xxf:binding('im-progress-note')/*" /> <xf:insert context="xxf:binding('im-progress-note')" origin="instance('progress-note-instance')/*"/> <!-- <xf:message value="concat('value',' changed')"/> --> </xf:action> </xf:model> <xf:group id="im-component-group" model="progress-note-model"> <fr:grid id="noteList-control" bind="noteList-bind" repeat="content" apply-defaults="false" readonly="true"> <xh:tr> <xh:td> <xf:input id="remark-control" bind="remark-bind"> </xf:input> </xh:td> </xh:tr> </fr:grid> </xf:group> </xbl:template> </xbl:binding> </xbl:xbl> |
Administrator
|
Hi Brian,
As they say, the best way is the one that works. So, it this works, you're good! :) But you can save yourself some work using xxbl:mirror="true". See: https://doc.orbeon.com/xforms/xbl/extensions.html#xxblmirror-attribute And the Image Annotation component would be one example of built-in XBL that uses that feature: https://github.com/orbeon/orbeon-forms/blob/master/form-runner/jvm/src/main/resources/xbl/orbeon/wpaint/wpaint.xbl Alex
--
Follow Orbeon on Twitter: @orbeon Follow me on Twitter: @avernet |
Thanks for the help Alex. I now have a reasonably functional control.
I decided not to use the mirror functionality as I want some particular behaviour for the control in the designer where I inject some data into the control when it is being edited in the designer or running in test mode. |
Administrator
|
Hi Brian, understood, perfect then, and I'm glad you got this to work to your satisfaction.
Alex
--
Follow Orbeon on Twitter: @orbeon Follow me on Twitter: @avernet |
Free forum by Nabble | Edit this page |