concat() function in a ref attribute

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

concat() function in a ref attribute

chrisswick
Hi,

Since the ref attribute of a label is interpreted as an xpath, should
it not be able to perform a concat() function? Below is a sample where
I have a list of contacts, which are displayed in a select1 control,
where the first and last name are to be displayed in each item. I
would expect since <xf:label ref="first_name" /> works given an xpath,
so should <xf:label ref="concat(first_name, ' ', last_name)" />.  I
also tried <xf:label><xf:output value="concat(first_name, ' ',
last_name)" /></xf:label>, which displays the first and last name, but
does not remain selected. Any ideas?

Thanks,
Chris


EXAMPLE:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xf="http://www.w3.org/
2002/xforms"
  xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xs="http://
www.w3.org/2001/XMLSchema">
  <head>
    <xf:model>

      <xf:instance id="selected-contact" xmlns="">
        <data>
          <contact-id />
        </data>
      </xf:instance>

      <xf:instance id="contacts" xmlns="">
        <data>
          <contact id="1">
            <first_name>Chris</first_name>
            <last_name>Swick</last_name>
          </contact>
          <contact id="2">
            <first_name>First</first_name>
            <last_name>Last</last_name>
          </contact>
        </data>
      </xf:instance>

    </xf:model>
  </head>
  <body>

    <!-- show first name only -->
    <xf:select1 ref="instance('selected-contact')/contact-id"
selection="closed">
      <xf:label>Display first name only: </xf:label>
      <xf:itemset nodeset="instance('contacts')/contact">
        <xf:label ref="first_name" />
        <xf:value ref="attribute::id" />
      </xf:itemset>
    </xf:select1>
    <br />
    <br />


    <!-- try to concat first and last name -->
    <xf:select1 ref="instance('selected-contact')/contact-id"
selection="closed">
      <xf:label>Does not concat first and last name: </xf:label>
      <xf:itemset nodeset="instance('contacts')/contact">
        <xf:label ref="concat(first_name, ' ', last_name)" />
        <xf:value ref="attribute::id" />
      </xf:itemset>
    </xf:select1>
    <br />
    <br />


    <!-- output first and last name -->
    <xf:select1 ref="instance('selected-contact')/contact-id"
selection="closed">
      <xf:label>Output first and last name, but will not stay
selected: </xf:label>
      <xf:itemset nodeset="instance('contacts')/contact">
        <xf:label>
          <xf:output value="concat(first_name, ' ', last_name)" />
        </xf:label>
        <xf:value ref="attribute::id" />
      </xf:itemset>
    </xf:select1>

  </body>
</html>

_______________________________________________
dev-tech-xforms mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-xforms
Reply | Threaded
Open this post in threaded view
|

Re: concat() function in a ref attribute

Aaron Reed
Hi Chris,

Concat won't work in @ref.  Yes, @ref is an xpath expression, but it has
to be an xpath expression that returns a DOM node since it is only used
for binding.  You want to use @value (xpath that is evaluated as a
string), which as you mention below, works fine.  Select1 will match the
item in the itemset whose value matches the value in the node that the
select1 is bound to.  So in your case, you'll have two items.  The first
will have a value of '1' and the other will have a value of '2' (since
the xf:values are bound to the @id off of the contact elements.
However, the node that your select1 is bound to (contact_id) has no
value so neither of your items will be selected when the page loads.

--Aaron

[hidden email] wrote:

> Hi,
>
> Since the ref attribute of a label is interpreted as an xpath, should
> it not be able to perform a concat() function? Below is a sample where
> I have a list of contacts, which are displayed in a select1 control,
> where the first and last name are to be displayed in each item. I
> would expect since <xf:label ref="first_name" /> works given an xpath,
> so should <xf:label ref="concat(first_name, ' ', last_name)" />.  I
> also tried <xf:label><xf:output value="concat(first_name, ' ',
> last_name)" /></xf:label>, which displays the first and last name, but
> does not remain selected. Any ideas?
>
> Thanks,
> Chris
>
>
> EXAMPLE:
>
> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:xf="http://www.w3.org/
> 2002/xforms"
>   xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xs="http://
> www.w3.org/2001/XMLSchema">
>   <head>
>     <xf:model>
>
>       <xf:instance id="selected-contact" xmlns="">
>         <data>
>           <contact-id />
>         </data>
>       </xf:instance>
>
>       <xf:instance id="contacts" xmlns="">
>         <data>
>           <contact id="1">
>             <first_name>Chris</first_name>
>             <last_name>Swick</last_name>
>           </contact>
>           <contact id="2">
>             <first_name>First</first_name>
>             <last_name>Last</last_name>
>           </contact>
>         </data>
>       </xf:instance>
>
>     </xf:model>
>   </head>
>   <body>
>
>     <!-- show first name only -->
>     <xf:select1 ref="instance('selected-contact')/contact-id"
> selection="closed">
>       <xf:label>Display first name only: </xf:label>
>       <xf:itemset nodeset="instance('contacts')/contact">
>         <xf:label ref="first_name" />
>         <xf:value ref="attribute::id" />
>       </xf:itemset>
>     </xf:select1>
>     <br />
>     <br />
>
>
>     <!-- try to concat first and last name -->
>     <xf:select1 ref="instance('selected-contact')/contact-id"
> selection="closed">
>       <xf:label>Does not concat first and last name: </xf:label>
>       <xf:itemset nodeset="instance('contacts')/contact">
>         <xf:label ref="concat(first_name, ' ', last_name)" />
>         <xf:value ref="attribute::id" />
>       </xf:itemset>
>     </xf:select1>
>     <br />
>     <br />
>
>
>     <!-- output first and last name -->
>     <xf:select1 ref="instance('selected-contact')/contact-id"
> selection="closed">
>       <xf:label>Output first and last name, but will not stay
> selected: </xf:label>
>       <xf:itemset nodeset="instance('contacts')/contact">
>         <xf:label>
>           <xf:output value="concat(first_name, ' ', last_name)" />
>         </xf:label>
>         <xf:value ref="attribute::id" />
>       </xf:itemset>
>     </xf:select1>
>
>   </body>
> </html>
>
_______________________________________________
dev-tech-xforms mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-xforms
Reply | Threaded
Open this post in threaded view
|

Re: concat() function in a ref attribute

Ivan Latysh-3
On Jul 20, 12:17 pm, Aaron Reed <[hidden email]> wrote:

> Concat won't work in @ref.  Yes, @ref is an xpath expression, but it has
> to be an xpath expression that returns a DOM node since it is only used
> for binding.  You want to use @value (xpath that is evaluated as a
> string), which as you mention below, works fine.  Select1 will match the
> item in the itemset whose value matches the value in the node that the
> select1 is bound to.  So in your case, you'll have two items.  The first
> will have a value of '1' and the other will have a value of '2' (since
> the xf:values are bound to the @id off of the contact elements.
> However, the node that your select1 is bound to (contact_id) has no
> value so neither of your items will be selected when the page loads.

Is there are any other way to do it ?

_______________________________________________
dev-tech-xforms mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-xforms
Reply | Threaded
Open this post in threaded view
|

RE: concat() function in a ref attribute

Klotz, Leigh
In reply to this post by Aaron Reed
BTW you can use @id instead of attribute::id, unless it's your
preference of course.

[hidden email] wrote:
]         <xf:value ref="attribute::id" />

Leigh.
_______________________________________________
dev-tech-xforms mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-xforms
Reply | Threaded
Open this post in threaded view
|

Re: concat() function in a ref attribute

Aaron Reed
In reply to this post by Ivan Latysh-3
Ivan Latysh wrote:

> On Jul 20, 12:17 pm, Aaron Reed <[hidden email]> wrote:
>
>> Concat won't work in @ref.  Yes, @ref is an xpath expression, but it has
>> to be an xpath expression that returns a DOM node since it is only used
>> for binding.  You want to use @value (xpath that is evaluated as a
>> string), which as you mention below, works fine.  Select1 will match the
>> item in the itemset whose value matches the value in the node that the
>> select1 is bound to.  So in your case, you'll have two items.  The first
>> will have a value of '1' and the other will have a value of '2' (since
>> the xf:values are bound to the @id off of the contact elements.
>> However, the node that your select1 is bound to (contact_id) has no
>> value so neither of your items will be selected when the page loads.
>
> Is there are any other way to do it ?
>

There are a number of ways, depending what you need it for.  If you need
it for a xf:output, put the concat() inside @value.  If you need it for
a label, you could just put an xf:output (with concat inside of its
@value) as a child of the label.  Or, of course, you could use an
instance node.  Use xf:bind to bind to the instance node and put an
@calculate on the xf:bind and put the concat inside of the @calculate.
Then bind whatever xforms control you need to that instance node to
display the concat'd value.

--Aaron
_______________________________________________
dev-tech-xforms mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-xforms
Reply | Threaded
Open this post in threaded view
|

Re: concat() function in a ref attribute

chrisswick
On Jul 23, 1:58 pm, Aaron Reed <[hidden email]> wrote:

> Ivan Latysh wrote:
> > On Jul 20, 12:17 pm, Aaron Reed <[hidden email]> wrote:
>
> >> Concat won't work in @ref.  Yes, @ref is an xpath expression, but it has
> >> to be an xpath expression that returns a DOM node since it is only used
> >> for binding.  You want to use @value (xpath that is evaluated as a
> >> string), which as you mention below, works fine.  Select1 will match the
> >> item in the itemset whose value matches the value in the node that the
> >> select1 is bound to.  So in your case, you'll have two items.  The first
> >> will have a value of '1' and the other will have a value of '2' (since
> >> the xf:values are bound to the @id off of the contact elements.
> >> However, the node that your select1 is bound to (contact_id) has no
> >> value so neither of your items will be selected when the page loads.
>
> > Is there are any other way to do it ?
>
> There are a number of ways, depending what you need it for.  If you need
> it for a xf:output, put the concat() inside @value.  If you need it for
> a label, you could just put an xf:output (with concat inside of its
> @value) as a child of the label.  Or, of course, you could use an
> instance node.  Use xf:bind to bind to the instance node and put an
> @calculate on the xf:bind and put the concat inside of the @calculate.
> Then bind whatever xforms control you need to that instance node to
> display the concat'd value.
>
> --Aaron


Regarding the xf:output with the concat'd value as a child of the
xf:label, that almost works but the selected item will not remain
selected as I've stated in my original post. I've left an example
there if you would like to try it out.

Regarding the xf:bind to the instance with the calculate attribute to
do the concat, this does not seem to maintain its reference to the
sequence of nodes in the itemset, it only calculates the first set of
nodes. If the xf:bind's calculate could refer to the xf:itemset using
a current(), position() or index('id-of-itemset') that would be great,
but I have not seen this documented anywhere.

Could you give an example of an xf:bind to concat a label's value
inside an xf:itemset?

Thanks,
Chris

_______________________________________________
dev-tech-xforms mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-xforms
Reply | Threaded
Open this post in threaded view
|

Re: concat() function in a ref attribute

Aaron Reed
[hidden email] wrote:
>
> Regarding the xf:output with the concat'd value as a child of the
> xf:label, that almost works but the selected item will not remain
> selected as I've stated in my original post. I've left an example
> there if you would like to try it out.

It remains selected.  You'll notice any other control bound to the same
node having its value changed.  The behavior you see is a bug in our
code...we are not setting the input field correctly after you select the
item.  We are getting the text from the item label to insert it into the
field, but the label doesn't have any text since it is all contained in
the inner output element.  There is already a bug open for this ->
https://bugzilla.mozilla.org/show_bug.cgi?id=343443

>
> Regarding the xf:bind to the instance with the calculate attribute to
> do the concat, this does not seem to maintain its reference to the
> sequence of nodes in the itemset, it only calculates the first set of
> nodes. If the xf:bind's calculate could refer to the xf:itemset using
> a current(), position() or index('id-of-itemset') that would be great,
> but I have not seen this documented anywhere.
>
> Could you give an example of an xf:bind to concat a label's value
> inside an xf:itemset?

Here is what I had in mind.  I've modified your original testcase.

<html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:xf="http://www.w3.org/2002/xforms"
       xmlns:ev="http://www.w3.org/2001/xml-events"
       xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <head>
     <xf:model>

       <xf:instance id="selected-contact" xmlns="">
         <data>
           <contact-id />
         </data>
       </xf:instance>

       <xf:instance id="contacts" xmlns="">
         <data>
           <contact id="1">
             <first_name>Chris</first_name>
             <last_name>Swick</last_name>
             <both/>
           </contact>
           <contact id="2">
             <first_name>First</first_name>
             <last_name>Last</last_name>
             <both/>
           </contact>
         </data>
       </xf:instance>
       <xf:bind nodeset="instance('contacts')/contact/both"
                calculate="concat(../first_name, ' ', ../last_name)"/>

     </xf:model>
   </head>
   <body>

     <!-- show first name only -->
     <xf:select1 ref="instance('selected-contact')/contact-id"
selection="closed">
       <xf:label>Display first name only: </xf:label>
       <xf:itemset nodeset="instance('contacts')/contact">
         <xf:label ref="first_name" />
         <xf:value ref="attribute::id" />
       </xf:itemset>
     </xf:select1>
     <br />
     <br />


     <!-- try to concat first and last name -->
<!--
     <xf:select1 ref="instance('selected-contact')/contact-id"
selection="closed">
       <xf:label>Does not concat first and last name: </xf:label>
       <xf:itemset nodeset="instance('contacts')/contact">
         <xf:label ref="concat(first_name, ' ', last_name)" />
         <xf:value ref="attribute::id" />
       </xf:itemset>
     </xf:select1>
-->
     <br />
     <br />


     <!-- output first and last name -->
     <xf:select1 ref="instance('selected-contact')/contact-id"
selection="closed">

       <xf:label>Output first and last name, but will not stay selected:
</xf:label>

       <xf:itemset nodeset="instance('contacts')/contact">
         <xf:label ref="both"/>
         <xf:value ref="attribute::id" />
       </xf:itemset>
     </xf:select1>

   </body>
</html>

I hope that this helps,
--Aaron
_______________________________________________
dev-tech-xforms mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-xforms
Reply | Threaded
Open this post in threaded view
|

Re: concat() function in a ref attribute

chrisswick
On Jul 31, 4:09 pm, Aaron Reed <[hidden email]> wrote:

> [hidden email] wrote:
>
> > Regarding the xf:output with the concat'd value as a child of the
> > xf:label, that almost works but the selected item will not remain
> > selected as I've stated in my original post. I've left an example
> > there if you would like to try it out.
>
> It remains selected.  You'll notice any other control bound to the same
> node having its value changed.  The behavior you see is a bug in our
> code...we are not setting the input field correctly after you select the
> item.  We are getting the text from the item label to insert it into the
> field, but the label doesn't have any text since it is all contained in
> the inner output element.  There is already a bug open for this ->https://bugzilla.mozilla.org/show_bug.cgi?id=343443
>
>
>
> > Regarding the xf:bind to the instance with the calculate attribute to
> > do the concat, this does not seem to maintain its reference to the
> > sequence of nodes in the itemset, it only calculates the first set of
> > nodes. If the xf:bind's calculate could refer to the xf:itemset using
> > a current(), position() or index('id-of-itemset') that would be great,
> > but I have not seen this documented anywhere.
>
> > Could you give an example of an xf:bind to concat a label's value
> > inside an xf:itemset?
>
> Here is what I had in mind.  I've modified your original testcase.
>
> <html xmlns="http://www.w3.org/1999/xhtml"
>        xmlns:xf="http://www.w3.org/2002/xforms"
>        xmlns:ev="http://www.w3.org/2001/xml-events"
>        xmlns:xs="http://www.w3.org/2001/XMLSchema">
>    <head>
>      <xf:model>
>
>        <xf:instance id="selected-contact" xmlns="">
>          <data>
>            <contact-id />
>          </data>
>        </xf:instance>
>
>        <xf:instance id="contacts" xmlns="">
>          <data>
>            <contact id="1">
>              <first_name>Chris</first_name>
>              <last_name>Swick</last_name>
>              <both/>
>            </contact>
>            <contact id="2">
>              <first_name>First</first_name>
>              <last_name>Last</last_name>
>              <both/>
>            </contact>
>          </data>
>        </xf:instance>
>        <xf:bind nodeset="instance('contacts')/contact/both"
>                 calculate="concat(../first_name, ' ', ../last_name)"/>
>
>      </xf:model>
>    </head>
>    <body>
>
>      <!-- show first name only -->
>      <xf:select1 ref="instance('selected-contact')/contact-id"
> selection="closed">
>        <xf:label>Display first name only: </xf:label>
>        <xf:itemset nodeset="instance('contacts')/contact">
>          <xf:label ref="first_name" />
>          <xf:value ref="attribute::id" />
>        </xf:itemset>
>      </xf:select1>
>      <br />
>      <br />
>
>      <!-- try to concat first and last name -->
> <!--
>      <xf:select1 ref="instance('selected-contact')/contact-id"
> selection="closed">
>        <xf:label>Does not concat first and last name: </xf:label>
>        <xf:itemset nodeset="instance('contacts')/contact">
>          <xf:label ref="concat(first_name, ' ', last_name)" />
>          <xf:value ref="attribute::id" />
>        </xf:itemset>
>      </xf:select1>
> -->
>      <br />
>      <br />
>
>      <!-- output first and last name -->
>      <xf:select1 ref="instance('selected-contact')/contact-id"
> selection="closed">
>
>        <xf:label>Output first and last name, but will not stay selected:
> </xf:label>
>
>        <xf:itemset nodeset="instance('contacts')/contact">
>          <xf:label ref="both"/>
>          <xf:value ref="attribute::id" />
>        </xf:itemset>
>      </xf:select1>
>
>    </body>
> </html>
>
> I hope that this helps,
> --Aaron

Thanks very much for the example. Unfortunately the instance data for
the contacts in my above example is coming form a server, so I am
unable to add a <both /> node to each contact. I've voted to have this
bug fixed (https://bugzilla.mozilla.org/show_bug.cgi?id=343443) and in
the meantime will use the first_name node to bind the concat'd value.
<xf:bind nodeset="instance('contacts')/contact/first_name"
calculate="concat(., ' ', ../last_name)"/> seem to work.

Thanks again,
Chris


_______________________________________________
dev-tech-xforms mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-xforms
Reply | Threaded
Open this post in threaded view
|

Re: concat() function in a ref attribute

Aaron Reed
Hi Chris,

Once the insert bug is fixed, you could create a sandbox instance and
clone the server instance into the sandbox and add the 'both' element
(or whatever you want to call it) under each person in the sandbox.  You
could also use JS right now to add the 'both' element under each person
in the instance document or to populate the a sandbox instance.  Just
make sure that you do it after the instance is loaded and then call
rebuild(), recalculate(), revalidate() and refresh() on the model that
contains the modified instance document.

The issue you'll have when you do it your way would be that each time
the calculate runs, the first name will keep having the 'last name'
appended to it.

--Aaron

[hidden email] wrote:

> On Jul 31, 4:09 pm, Aaron Reed <[hidden email]> wrote:
>> [hidden email] wrote:
>>
>>> Regarding the xf:output with the concat'd value as a child of the
>>> xf:label, that almost works but the selected item will not remain
>>> selected as I've stated in my original post. I've left an example
>>> there if you would like to try it out.
>> It remains selected.  You'll notice any other control bound to the same
>> node having its value changed.  The behavior you see is a bug in our
>> code...we are not setting the input field correctly after you select the
>> item.  We are getting the text from the item label to insert it into the
>> field, but the label doesn't have any text since it is all contained in
>> the inner output element.  There is already a bug open for this ->https://bugzilla.mozilla.org/show_bug.cgi?id=343443
>>
>>
>>
>>> Regarding the xf:bind to the instance with the calculate attribute to
>>> do the concat, this does not seem to maintain its reference to the
>>> sequence of nodes in the itemset, it only calculates the first set of
>>> nodes. If the xf:bind's calculate could refer to the xf:itemset using
>>> a current(), position() or index('id-of-itemset') that would be great,
>>> but I have not seen this documented anywhere.
>>> Could you give an example of an xf:bind to concat a label's value
>>> inside an xf:itemset?
>> Here is what I had in mind.  I've modified your original testcase.
>>
>> <html xmlns="http://www.w3.org/1999/xhtml"
>>        xmlns:xf="http://www.w3.org/2002/xforms"
>>        xmlns:ev="http://www.w3.org/2001/xml-events"
>>        xmlns:xs="http://www.w3.org/2001/XMLSchema">
>>    <head>
>>      <xf:model>
>>
>>        <xf:instance id="selected-contact" xmlns="">
>>          <data>
>>            <contact-id />
>>          </data>
>>        </xf:instance>
>>
>>        <xf:instance id="contacts" xmlns="">
>>          <data>
>>            <contact id="1">
>>              <first_name>Chris</first_name>
>>              <last_name>Swick</last_name>
>>              <both/>
>>            </contact>
>>            <contact id="2">
>>              <first_name>First</first_name>
>>              <last_name>Last</last_name>
>>              <both/>
>>            </contact>
>>          </data>
>>        </xf:instance>
>>        <xf:bind nodeset="instance('contacts')/contact/both"
>>                 calculate="concat(../first_name, ' ', ../last_name)"/>
>>
>>      </xf:model>
>>    </head>
>>    <body>
>>
>>      <!-- show first name only -->
>>      <xf:select1 ref="instance('selected-contact')/contact-id"
>> selection="closed">
>>        <xf:label>Display first name only: </xf:label>
>>        <xf:itemset nodeset="instance('contacts')/contact">
>>          <xf:label ref="first_name" />
>>          <xf:value ref="attribute::id" />
>>        </xf:itemset>
>>      </xf:select1>
>>      <br />
>>      <br />
>>
>>      <!-- try to concat first and last name -->
>> <!--
>>      <xf:select1 ref="instance('selected-contact')/contact-id"
>> selection="closed">
>>        <xf:label>Does not concat first and last name: </xf:label>
>>        <xf:itemset nodeset="instance('contacts')/contact">
>>          <xf:label ref="concat(first_name, ' ', last_name)" />
>>          <xf:value ref="attribute::id" />
>>        </xf:itemset>
>>      </xf:select1>
>> -->
>>      <br />
>>      <br />
>>
>>      <!-- output first and last name -->
>>      <xf:select1 ref="instance('selected-contact')/contact-id"
>> selection="closed">
>>
>>        <xf:label>Output first and last name, but will not stay selected:
>> </xf:label>
>>
>>        <xf:itemset nodeset="instance('contacts')/contact">
>>          <xf:label ref="both"/>
>>          <xf:value ref="attribute::id" />
>>        </xf:itemset>
>>      </xf:select1>
>>
>>    </body>
>> </html>
>>
>> I hope that this helps,
>> --Aaron
>
> Thanks very much for the example. Unfortunately the instance data for
> the contacts in my above example is coming form a server, so I am
> unable to add a <both /> node to each contact. I've voted to have this
> bug fixed (https://bugzilla.mozilla.org/show_bug.cgi?id=343443) and in
> the meantime will use the first_name node to bind the concat'd value.
> <xf:bind nodeset="instance('contacts')/contact/first_name"
> calculate="concat(., ' ', ../last_name)"/> seem to work.
>
> Thanks again,
> Chris
>
>
_______________________________________________
dev-tech-xforms mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-xforms
Reply | Threaded
Open this post in threaded view
|

Re: concat() function in a ref attribute

chrisswick
Hi Aaron,

That raises two questions of which I've had some problems with thus
far. (Maybe this should be moved to another topic, but it relates to
your last reply)

1) Is there an xforms way of cloning or copying a chunk of XML into
another instance? The xf:insert seems to copy only into the same
instance.

Here's what I've done:
I have an instance which contains empty nodes for a contact which are
<first_name/>, <last_name/> and <email/>. After I fill them up and
save the new contact, I need to reset the instance to empty values,
but not reset the entire model, just the instance. I could of course
use multiple xf:setvalue's and set the values of each node to null,
but in the case where there are many nodes to reset, this gets
cumbersome. My workaround is to have a 'template' instance and a
'working' instance, where I use an xf:submission to send the empty
'template' instance to the server and have it replace the 'working'
instance to a clean copy. It seems unnecessary to make a server
request to get an xml structure from one instance into another, but I
have not found another solution so far.

2) Will xforms provide a way of adding nodes and attributes, and
changing node names rather than using JS? The xf:insert works for
adding a new node, but the initial node must be present to copy and
add the second node.

Thanks,
Chris

On Jul 31, 8:04 pm, Aaron Reed <[hidden email]> wrote:

> Hi Chris,
>
> Once the insert bug is fixed, you could create a sandbox instance and
> clone the server instance into the sandbox and add the 'both' element
> (or whatever you want to call it) under each person in the sandbox.  You
> could also use JS right now to add the 'both' element under each person
> in the instance document or to populate the a sandbox instance.  Just
> make sure that you do it after the instance is loaded and then call
> rebuild(), recalculate(), revalidate() and refresh() on the model that
> contains the modified instance document.
>
> The issue you'll have when you do it your way would be that each time
> the calculate runs, the first name will keep having the 'last name'
> appended to it.
>
> --Aaron
>
> [hidden email] wrote:
> > On Jul 31, 4:09 pm, Aaron Reed <[hidden email]> wrote:
> >> [hidden email] wrote:
>
> >>> Regarding the xf:output with the concat'd value as a child of the
> >>> xf:label, that almost works but the selected item will not remain
> >>> selected as I've stated in my original post. I've left an example
> >>> there if you would like to try it out.
> >> It remains selected.  You'll notice any other control bound to the same
> >> node having its value changed.  The behavior you see is a bug in our
> >> code...we are not setting the input field correctly after you select the
> >> item.  We are getting the text from the item label to insert it into the
> >> field, but the label doesn't have any text since it is all contained in
> >> the inner output element.  There is already a bug open for this ->https://bugzilla.mozilla.org/show_bug.cgi?id=343443
>
> >>> Regarding the xf:bind to the instance with the calculate attribute to
> >>> do the concat, this does not seem to maintain its reference to the
> >>> sequence of nodes in the itemset, it only calculates the first set of
> >>> nodes. If the xf:bind's calculate could refer to the xf:itemset using
> >>> a current(), position() or index('id-of-itemset') that would be great,
> >>> but I have not seen this documented anywhere.
> >>> Could you give an example of an xf:bind to concat a label's value
> >>> inside an xf:itemset?
> >> Here is what I had in mind.  I've modified your original testcase.
>
> >> <html xmlns="http://www.w3.org/1999/xhtml"
> >>        xmlns:xf="http://www.w3.org/2002/xforms"
> >>        xmlns:ev="http://www.w3.org/2001/xml-events"
> >>        xmlns:xs="http://www.w3.org/2001/XMLSchema">
> >>    <head>
> >>      <xf:model>
>
> >>        <xf:instance id="selected-contact" xmlns="">
> >>          <data>
> >>            <contact-id />
> >>          </data>
> >>        </xf:instance>
>
> >>        <xf:instance id="contacts" xmlns="">
> >>          <data>
> >>            <contact id="1">
> >>              <first_name>Chris</first_name>
> >>              <last_name>Swick</last_name>
> >>              <both/>
> >>            </contact>
> >>            <contact id="2">
> >>              <first_name>First</first_name>
> >>              <last_name>Last</last_name>
> >>              <both/>
> >>            </contact>
> >>          </data>
> >>        </xf:instance>
> >>        <xf:bind nodeset="instance('contacts')/contact/both"
> >>                 calculate="concat(../first_name, ' ', ../last_name)"/>
>
> >>      </xf:model>
> >>    </head>
> >>    <body>
>
> >>      <!-- show first name only -->
> >>      <xf:select1 ref="instance('selected-contact')/contact-id"
> >> selection="closed">
> >>        <xf:label>Display first name only: </xf:label>
> >>        <xf:itemset nodeset="instance('contacts')/contact">
> >>          <xf:label ref="first_name" />
> >>          <xf:value ref="attribute::id" />
> >>        </xf:itemset>
> >>      </xf:select1>
> >>      <br />
> >>      <br />
>
> >>      <!-- try to concat first and last name -->
> >> <!--
> >>      <xf:select1 ref="instance('selected-contact')/contact-id"
> >> selection="closed">
> >>        <xf:label>Does not concat first and last name: </xf:label>
> >>        <xf:itemset nodeset="instance('contacts')/contact">
> >>          <xf:label ref="concat(first_name, ' ', last_name)" />
> >>          <xf:value ref="attribute::id" />
> >>        </xf:itemset>
> >>      </xf:select1>
> >> -->
> >>      <br />
> >>      <br />
>
> >>      <!-- output first and last name -->
> >>      <xf:select1 ref="instance('selected-contact')/contact-id"
> >> selection="closed">
>
> >>        <xf:label>Output first and last name, but will not stay selected:
> >> </xf:label>
>
> >>        <xf:itemset nodeset="instance('contacts')/contact">
> >>          <xf:label ref="both"/>
> >>          <xf:value ref="attribute::id" />
> >>        </xf:itemset>
> >>      </xf:select1>
>
> >>    </body>
> >> </html>
>
> >> I hope that this helps,
> >> --Aaron
>
> > Thanks very much for the example. Unfortunately the instance data for
> > the contacts in my above example is coming form a server, so I am
> > unable to add a <both /> node to each contact. I've voted to have this
> > bug fixed (https://bugzilla.mozilla.org/show_bug.cgi?id=343443) and in
> > the meantime will use the first_name node to bind the concat'd value.
> > <xf:bind nodeset="instance('contacts')/contact/first_name"
> > calculate="concat(., ' ', ../last_name)"/> seem to work.
>
> > Thanks again,
> > Chris


_______________________________________________
dev-tech-xforms mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-xforms
Reply | Threaded
Open this post in threaded view
|

Re: concat() function in a ref attribute

Aaron Reed
Hi Chris,

I suggest that you check out 1.1's insert ->
http://www.w3.org/TR/xforms11/#action-insert which we should fully
support when our latest insert bug is fixed.  And that bug deals with
insertions into an empty nodeset so it might not even block your work
(since you seem to be dealing with an already populated nodeset).  I
think it should support most of what you asked about.  For example, the
idea of a template and the idea of copying from one instance to another
(both achieved using @origin).

--Aaron

[hidden email] wrote:

> Hi Aaron,
>
> That raises two questions of which I've had some problems with thus
> far. (Maybe this should be moved to another topic, but it relates to
> your last reply)
>
> 1) Is there an xforms way of cloning or copying a chunk of XML into
> another instance? The xf:insert seems to copy only into the same
> instance.
>
> Here's what I've done:
> I have an instance which contains empty nodes for a contact which are
> <first_name/>, <last_name/> and <email/>. After I fill them up and
> save the new contact, I need to reset the instance to empty values,
> but not reset the entire model, just the instance. I could of course
> use multiple xf:setvalue's and set the values of each node to null,
> but in the case where there are many nodes to reset, this gets
> cumbersome. My workaround is to have a 'template' instance and a
> 'working' instance, where I use an xf:submission to send the empty
> 'template' instance to the server and have it replace the 'working'
> instance to a clean copy. It seems unnecessary to make a server
> request to get an xml structure from one instance into another, but I
> have not found another solution so far.
>
> 2) Will xforms provide a way of adding nodes and attributes, and
> changing node names rather than using JS? The xf:insert works for
> adding a new node, but the initial node must be present to copy and
> add the second node.
>
> Thanks,
> Chris
>
> On Jul 31, 8:04 pm, Aaron Reed <[hidden email]> wrote:
>> Hi Chris,
>>
>> Once the insert bug is fixed, you could create a sandbox instance and
>> clone the server instance into the sandbox and add the 'both' element
>> (or whatever you want to call it) under each person in the sandbox.  You
>> could also use JS right now to add the 'both' element under each person
>> in the instance document or to populate the a sandbox instance.  Just
>> make sure that you do it after the instance is loaded and then call
>> rebuild(), recalculate(), revalidate() and refresh() on the model that
>> contains the modified instance document.
>>
>> The issue you'll have when you do it your way would be that each time
>> the calculate runs, the first name will keep having the 'last name'
>> appended to it.
>>
>> --Aaron
>>
>> [hidden email] wrote:
>>> On Jul 31, 4:09 pm, Aaron Reed <[hidden email]> wrote:
>>>> [hidden email] wrote:
>>>>> Regarding the xf:output with the concat'd value as a child of the
>>>>> xf:label, that almost works but the selected item will not remain
>>>>> selected as I've stated in my original post. I've left an example
>>>>> there if you would like to try it out.
>>>> It remains selected.  You'll notice any other control bound to the same
>>>> node having its value changed.  The behavior you see is a bug in our
>>>> code...we are not setting the input field correctly after you select the
>>>> item.  We are getting the text from the item label to insert it into the
>>>> field, but the label doesn't have any text since it is all contained in
>>>> the inner output element.  There is already a bug open for this ->https://bugzilla.mozilla.org/show_bug.cgi?id=343443
>>>>> Regarding the xf:bind to the instance with the calculate attribute to
>>>>> do the concat, this does not seem to maintain its reference to the
>>>>> sequence of nodes in the itemset, it only calculates the first set of
>>>>> nodes. If the xf:bind's calculate could refer to the xf:itemset using
>>>>> a current(), position() or index('id-of-itemset') that would be great,
>>>>> but I have not seen this documented anywhere.
>>>>> Could you give an example of an xf:bind to concat a label's value
>>>>> inside an xf:itemset?
>>>> Here is what I had in mind.  I've modified your original testcase.
>>>> <html xmlns="http://www.w3.org/1999/xhtml"
>>>>        xmlns:xf="http://www.w3.org/2002/xforms"
>>>>        xmlns:ev="http://www.w3.org/2001/xml-events"
>>>>        xmlns:xs="http://www.w3.org/2001/XMLSchema">
>>>>    <head>
>>>>      <xf:model>
>>>>        <xf:instance id="selected-contact" xmlns="">
>>>>          <data>
>>>>            <contact-id />
>>>>          </data>
>>>>        </xf:instance>
>>>>        <xf:instance id="contacts" xmlns="">
>>>>          <data>
>>>>            <contact id="1">
>>>>              <first_name>Chris</first_name>
>>>>              <last_name>Swick</last_name>
>>>>              <both/>
>>>>            </contact>
>>>>            <contact id="2">
>>>>              <first_name>First</first_name>
>>>>              <last_name>Last</last_name>
>>>>              <both/>
>>>>            </contact>
>>>>          </data>
>>>>        </xf:instance>
>>>>        <xf:bind nodeset="instance('contacts')/contact/both"
>>>>                 calculate="concat(../first_name, ' ', ../last_name)"/>
>>>>      </xf:model>
>>>>    </head>
>>>>    <body>
>>>>      <!-- show first name only -->
>>>>      <xf:select1 ref="instance('selected-contact')/contact-id"
>>>> selection="closed">
>>>>        <xf:label>Display first name only: </xf:label>
>>>>        <xf:itemset nodeset="instance('contacts')/contact">
>>>>          <xf:label ref="first_name" />
>>>>          <xf:value ref="attribute::id" />
>>>>        </xf:itemset>
>>>>      </xf:select1>
>>>>      <br />
>>>>      <br />
>>>>      <!-- try to concat first and last name -->
>>>> <!--
>>>>      <xf:select1 ref="instance('selected-contact')/contact-id"
>>>> selection="closed">
>>>>        <xf:label>Does not concat first and last name: </xf:label>
>>>>        <xf:itemset nodeset="instance('contacts')/contact">
>>>>          <xf:label ref="concat(first_name, ' ', last_name)" />
>>>>          <xf:value ref="attribute::id" />
>>>>        </xf:itemset>
>>>>      </xf:select1>
>>>> -->
>>>>      <br />
>>>>      <br />
>>>>      <!-- output first and last name -->
>>>>      <xf:select1 ref="instance('selected-contact')/contact-id"
>>>> selection="closed">
>>>>        <xf:label>Output first and last name, but will not stay selected:
>>>> </xf:label>
>>>>        <xf:itemset nodeset="instance('contacts')/contact">
>>>>          <xf:label ref="both"/>
>>>>          <xf:value ref="attribute::id" />
>>>>        </xf:itemset>
>>>>      </xf:select1>
>>>>    </body>
>>>> </html>
>>>> I hope that this helps,
>>>> --Aaron
>>> Thanks very much for the example. Unfortunately the instance data for
>>> the contacts in my above example is coming form a server, so I am
>>> unable to add a <both /> node to each contact. I've voted to have this
>>> bug fixed (https://bugzilla.mozilla.org/show_bug.cgi?id=343443) and in
>>> the meantime will use the first_name node to bind the concat'd value.
>>> <xf:bind nodeset="instance('contacts')/contact/first_name"
>>> calculate="concat(., ' ', ../last_name)"/> seem to work.
>>> Thanks again,
>>> Chris
>
>
_______________________________________________
dev-tech-xforms mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-xforms