How to update an instance value with another document - xslt-2.0

We are using XSLTForms and XSLT to display a page.
I have an instance on a page whose value is set as a document.
<xf:instance id="myDetails">
<xsl:copy-of select="$detailDocument" />
</xf:instance>
It works fine and the instance value is set correctly. However, later I need to update the value of this instance with another document. I tried something like follows but didn't work:
<xf:setvalue ref="instance('myDetails')"><xsl:copy-of select="$updatedDetailDocument" /></xf:setvalue>
This just makes the instance empty even though I know updatedDetailDocument is not empty. Does xf:setvalue even support setting instances ? Or is there any other way of doing the same ?

<xf:setvalue> is used to set text within an XML attribute or XML element. In order to set a tree or subtree of XML, you would need the <xf:insert> action instead.
You don't say how you are getting $updatedDetailDocument, but since this is dynamic you probably need to retrieve that updated document using <xf:submission>, in which case you won't need <xf:insert> because <xf:submission> can directly update your instance with replace="instance".

Related

How do you get the value of a data attribute within an event-based rule in Adobe Dynamic Tag Manager (DTM)?

I have an event-based rule configured to fire on click of an element with a specific class. On click, I would like to capture the value of a data attribute that exists. The DTM documentation says you can capture attribute values using this syntax:
%this.data-event%
or
%this.id%
Example HTML:
On click of links with the class "test", I would like to store the value of "event name" within an eVar. When I used the above syntax however, the syntax is converted to a string and in the Adobe server call as:
v25:%this.data-event%
What is the best way to dynamically grab the value of an attribute of an HTML element on click within DTM?
DTM documentation says you can do that, but in practice I too have found that it doesn't seem to work as advertised most of the time, and will instead populate it with a literal (un-eval'd) string like that.
So what I do instead is under Conditions > Rule Conditions I create a Custom condition. In the Custom condition, I add the following:
// example to get id
_satellite.setVar('this_id',this.id);
// example to get href
_satellite.setVar('this_href',this.href);
return true;
Basically I create on-the-fly data elements using javascript, and then return true (so the condition doesn't affect the rule from triggering).
Then I use %this_id%, %this_href%, etc. syntax from the data element I created, in the Adobe Analytics section variable fields.
The easist way to capture the values of a data attribute against an eVar or prop on the element clicked using DTM is to set the input as the following:
%this.getAttribute(data-attributename)%
For example, if there was a data attribute on an element of data-social-share-destination='facebook' simply input %this.getAttribute(data-social-share-destination)%. This will then capture the value of 'facebook'
More detail on data attributes can be found at http://www.digitalbalance.com.au/our-blog/event-based-tracking-using-html5-custom-data-attributes/
I found a solution. The best way to grab the value of an attribute on click is to use this syntax:
%this.getAttribute(data-title)%
The key is to not use quotes around the attribute name AND ensure the attribute has a value.
If the attribute is missing, the expression is not replaced by an empty string as one would normally expect from experience in other platforms, but instead will display the raw un-interpolated code.

Activate xforms button when instance is valid, inactivate otherwise

I have an xforms instance that I have a number of binds set up for so I can warn a user about input errors.
When he is done he needs to be able to submit the data from the instance. I would like to toggle 'active' on the button depending on whether or not the instance is valid.
What's the best way to 'attack' this problem? I'm currently using a group around the button that basically repeats what the model bindings already said which feels redundant and is error prone because of out of sync logic.
Also: this instance has 3 bindings, but I have others with 30-40 bindings.
Current code:
<xforms:group ref=".[instance('new-terminology-association')[matches(#code,'^\S+$')][matches(#codeSystem,'^[0-2](\.(0|[1-9][0-9]*))*$')][string-length(#displayName)>0]]">
<fr:button>
<xforms:label ref="$resources/create-association"/>
<xforms:action ev:event="DOMActivate">
...
</xforms:action>
</fr:button>
</xforms:group>
You could use the xxf:valid() function, pointing to the nodes you want to be valid. You can also point that function to a "parent" node, and ask it to check everything "under" that node is valid.
I think that function does what you're looking for, but because field values are only sent when users stab out of the field, this can create a somewhat unexpected user experience. For instance, imagine that the last field of your form, showing just before your button, is required. The user focuses on that field, and types a value. At this point the button is still disabled, since the value hasn't been sent to the server yet. Now the user hits tab, the value is sent to the server, the button would become enabled when the Ajax responses received, but since the button wasn't enabled at the time tab was pressed, the focus goes on something other than the button, which is somewhat unexpected. So, this is something to keep in mind.
There is absolutely no way in Orbeon 4.7 to make the button/trigger respond directly to xxf:valid. This looks like a bug to me. Workaround code: add observer for xxforms-valid and xxforms-invalid that set true|false in a new instance. Add readonly binding based on ".='false'" for that instance and use ref="instance" on the trigger. On a busy form with lots of buttons that is a bit of a waste, but it'll have to make due. Thanks for you help, appreciated!
<xf:instance id="button-control">
<button btn-term-add="false"/>
</xf:instance>
<xf:action ev:event="xxforms-invalid" ev:observer="new-terminology-association">
<xf:setvalue ref="instance('button-control')/#btn-term-add" >false</xf:setvalue>
</xf:action>
<xf:action ev:event="xxforms-valid" ev:observer="new-terminology-association">
<xf:setvalue ref="instance('button-control')/#btn-term-add">true</xf:setvalue>
</xf:action>
<xf:bind nodeset="instance('button-control')">
<xf:bind ref="#btn-term-add" readonly=".='false'"/>
</xf:bind>
....
<xf:trigger ref="instance('button-control')/#btn-term-add">
....
</xf:trigger>

Unmarshalling using castor mapping

I have a doubt in using castor mapping.
I know Castor will look for classes with the same name as that of element name. I have my castor mapping ready and it is working fine.
My doubt is, what if an element is received as null [I mean no value is being passed]? Castor will try to instantiate the class and assign null? or will it skip those classes?
If it tries to create an instance of that class, what performance are we going to loose? something to discard or does it have much impact on performance?
EDIT-Including the XML
<Order>
<Activity>
<ActivityID>String</ActivityID>
<ActivityName>String</ActivityName>
<CurrentActivityInd>String</CurrentActivityInd>
<Description>String</Description>
<Reason>String</Reason>
<StartDateTime>2001-12-17T09:30:47Z</StartDateTime>
<EndDateTime>2001-12-17T09:30:47Z</EndDateTime>
<Status>String</Status>
<Action>String</Action>
<Owner>String</Owner>
</Activity> </Order>
Above is just a part of my XML. "Order can have any number of activity child within it".My question is,
What if I pass the XML like without any value? Will it instantiate Order and Activity class or Order class alone or none of the two?
Thanks!

insert into instance in a repeat

my situation is the following:
I have a nodeset, through which I iterate and populate a table with some of the data
One of the fields, I do want to sum up
The problem:
Unfortunately I cannot use the sum method for the calculation as the nodeset is custom function that accesses data from other forms. And that seems to mess up things.
My idea of a solution:
I thought, I could create an instance and in each iteration add the value to it. Then I simply could access that data and do whatever calculation required. But I cannot get the xforms:insert to work.
A simplified version looks like this:
<xforms:repeat nodeset="(xxforms:si-source-forms('other_form'))">
<!-- table here -->
<xforms:insert
nodeset="instance('fr-form-instance')//positionen/position"
origin="instance('neue-position')"/>
</xforms:repeat>
The 'neue-position' instance contains bindings to the values in the source form:
<xforms:bind id="neue-position-binds" nodeset="instance('neue-position')">
<xforms:bind id="neue-position-bind" nodeset="position">
<xforms:bind id="neue-position-summe-bind" nodeset="summe" name="summe" type="xforms:string" required="true" xxforms:default="xxforms:si-source-forms('other_form')//gesamtbetrag_ausgabe" />
</xforms:bind>
</xforms:bind>
It does not work as expected though, so obviously something is wrong. I'd appreciate any hints.
About your first code snippet:
Your <xforms:insert> won't have any effet. You're in the view, and an action only runs if it is attached to an event listener. Without an ev:listener on the <xforms:insert> (or on an action around that insert), it just won't run.
About doing a sum over nodes not in an instance:
Assuming there is just one "sum" over the data returns by your custom function, you could write code along those lines:
Store the sequence of nodes returned by the function in an variable <xf:var name="others" ref="xxforms:si-source-forms('other_form')"/>
Use that variable in the repeat: <xf:repeat ref="$others"> (BTW, now XForms is standardizing the use of ref everywhere, in place of nodeset).
Do your calculation: <xf:var name="my-sum" ref="sum($others/path/to/values)"/>.
Finally, I imagine that you want to do something with $my-sum, maybe show it with an <xf:output>.

Creating new Objects With SPRING.Net

I'm new on spring.net, and I'm tring to create an List<> of objects.
The list is initialized by a loop that calls:
IObj obj= (IObj)ContextRegistry.GetContext().GetObject("obj")
change object properties....
add it to the list...
the problem is : I keep getting the same object every step of the loop
so I get a list of the same object
If your object definitions are not singletons, then you will get a new object each time. Note, by default, singleton is set to true, so you have to explicitly set it to false.
For example, if you are using xml files to configure your objects, set the singleton attribute to false:
<object name="name" type="..." singleton="false"/>
It is not clear what you are trying to achieve by looping over the "GetObject("obj")" method. Maybe you can post the loop-code?
What "GetObject("obj")" does is to ask the Container for the Object with the name "obj". You stated that want to change the object's properties and add it to a list. This is something the container can do for you:
Set the properties of an Object:
http://www.springframework.net/doc-latest/reference/html/objects.html#objects-simple-values
Create a list:
http://www.springframework.net/doc-latest/reference/html/objects.html#objects-collections-values
This list can be injected into an Object you choose.
If you just want non-singleton objects of your IObj, naders answer is correct. Spring calls these non-singleton objects "prototypes". An overview of available Scopes can be found here: http://www.springframework.net/doc-latest/reference/html/objects.html#objects-factory-scopes

Resources