Iteration and conditional in XForms

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

Iteration and conditional in XForms

Jimmy Royer
Hi everyone, apprentice here and I have an easy question.

I need to iterate through a list from my main instance. At first I was
doing so with XSLT tags <choose> and
<when>, but then I decided to do it via XForms tag <repeat> so I could
easily manipulate elements after
the page loading.

<xforms:repeat nodeset="post:comments/post:comment">
  <xforms:output ref="post:person/post:name"/>
  (<xforms:output ref="post:person/post:email"/>)
</xforms:repeat>

It works quite well. My problem now is that I need to change the color
of the police when
the post:person/@registered attribute is true or false. I need a simple
XForms conditional to check
whether the attribute is true or false, so I can enclose the outputs in
a xhtml:div tag.

Is it possible to put a condition on a xforms tag that I could use like
that?

<xforms:condition value="my condition>
  <div style="color: #0099CC">
    <xforms:output ref="post:person/post:name"/>
    (<xforms:output ref="post:person/post:email"/>)
  </div>
</xforms:condition>


I thought I had a solution with binds with the relevant property:

<head>
<xforms:model>
   ...
   ...
      <xforms:instance id="control-instance">
        <control xmlns="">
          <poster-status>
            <registered/>
            <unregistered/>
          </poster-status>
        </control>
      </xforms:instance>

      <xforms:bind nodeset="instance('control-instance')/poster-status">
        <xforms:bind nodeset="registered"
                     
relevant="instance('posts-instance')/post:comments/*/post:person/@registered
= 'true'"/>
        <xforms:bind nodeset="unregistered"
                     
relevant="instance('posts-instance')/post:comments/*/post:person/@registered
= 'false'"/>
      </xforms:bind>
</xforms:model>
</head>

<body>
<xforms:repeat nodeset="post:comments/post:comment">
  <xforms:group ref="instance('control-instance')/poster-status/registered">
    <div style="color: #0099CC">
      <xforms:output ref="post:person/post:name"/>
      (<xforms:output ref="post:person/post:email"/>)
    </div>
  </xforms:group>
  <xforms:group
ref="instance('control-instance')/poster-status/unregistered">
      <xforms:output ref="post:person/post:name"/>
      (<xforms:output ref="post:person/post:email"/>)
  </xforms:group>
</xforms:repeat>
</body>

It doesn't work though as first I can't reference element of the loop
inside a different group. Second
it doesn't seem the relevant condition in the xform binds apply for each
individual element in the loop.
If I put
instance('posts-instance')/post:comments/comment[1]/post:person/@registered
then it works
but.. yeah that is not what I need.

Anyone know how to make it work? If there is a simpler solution?

I'll attach a simplified file with the mentioned code.

Jimmy Royer





--
You receive this message as a subscriber of the [hidden email] mailing list.
To unsubscribe: mailto:[hidden email]
For general help: mailto:[hidden email]?subject=help
ObjectWeb mailing lists service home page: http://www.objectweb.org/wws

post-view.xhtml (6K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

RE: Iteration and conditional in XForms

Ryan Puddephatt
Jimmy

Try

<div style="{if(post:person/@registered = true()) then 'color: #0099CC' else
''}">

That should work

Ryan Puddephatt
Software Engineer
TFX Group - IT UK
1 Michaelson Square
Livingston
West Lothian
Scotand
EH54 7DP
 
* [hidden email]
( 01506 407 110
7  01506 407 108
 

>-----Original Message-----
>From: Jimmy Royer [mailto:[hidden email]]
>Sent: 12 April 2006 17:14
>To: [hidden email]
>Subject: [ops-users] Iteration and conditional in XForms
>
>Hi everyone, apprentice here and I have an easy question.
>
>I need to iterate through a list from my main instance. At first I was
>doing so with XSLT tags <choose> and
><when>, but then I decided to do it via XForms tag <repeat> so I could
>easily manipulate elements after
>the page loading.
>
><xforms:repeat nodeset="post:comments/post:comment">
>  <xforms:output ref="post:person/post:name"/>
>  (<xforms:output ref="post:person/post:email"/>)
></xforms:repeat>
>
>It works quite well. My problem now is that I need to change the color
>of the police when
>the post:person/@registered attribute is true or false. I need a simple
>XForms conditional to check
>whether the attribute is true or false, so I can enclose the outputs in
>a xhtml:div tag.
>
>Is it possible to put a condition on a xforms tag that I could use like
>that?
>
><xforms:condition value="my condition>
>  <div style="color: #0099CC">
>    <xforms:output ref="post:person/post:name"/>
>    (<xforms:output ref="post:person/post:email"/>)
>  </div>
></xforms:condition>
>
>
>I thought I had a solution with binds with the relevant property:
>
><head>
><xforms:model>
>   ...
>   ...
>      <xforms:instance id="control-instance">
>        <control xmlns="">
>          <poster-status>
>            <registered/>
>            <unregistered/>
>          </poster-status>
>        </control>
>      </xforms:instance>
>
>      <xforms:bind nodeset="instance('control-instance')/poster-status">
>        <xforms:bind nodeset="registered"
>
>relevant="instance('posts-
>instance')/post:comments/*/post:person/@registered
>= 'true'"/>
>        <xforms:bind nodeset="unregistered"
>
>relevant="instance('posts-
>instance')/post:comments/*/post:person/@registered
>= 'false'"/>
>      </xforms:bind>
></xforms:model>
></head>
>
><body>
><xforms:repeat nodeset="post:comments/post:comment">
>  <xforms:group ref="instance('control-instance')/poster-
>status/registered">
>    <div style="color: #0099CC">
>      <xforms:output ref="post:person/post:name"/>
>      (<xforms:output ref="post:person/post:email"/>)
>    </div>
>  </xforms:group>
>  <xforms:group
>ref="instance('control-instance')/poster-status/unregistered">
>      <xforms:output ref="post:person/post:name"/>
>      (<xforms:output ref="post:person/post:email"/>)
>  </xforms:group>
></xforms:repeat>
></body>
>
>It doesn't work though as first I can't reference element of the loop
>inside a different group. Second
>it doesn't seem the relevant condition in the xform binds apply for each
>individual element in the loop.
>If I put
>instance('posts-instance')/post:comments/comment[1]/post:person/@registered
>then it works
>but.. yeah that is not what I need.
>
>Anyone know how to make it work? If there is a simpler solution?
>
>I'll attach a simplified file with the mentioned code.
>
>Jimmy Royer
>
>




--
You receive this message as a subscriber of the [hidden email] mailing list.
To unsubscribe: mailto:[hidden email]
For general help: mailto:[hidden email]?subject=help
ObjectWeb mailing lists service home page: http://www.objectweb.org/wws
Reply | Threaded
Open this post in threaded view
|

Re: Iteration and conditional in XForms

Jimmy Royer
Thanks Ryan,

I knew a simpler solution was possible. Unfortunately it doesn't work
for me. As if the XPath
condition could not access the xforms:repeat element. I tried too with

if(post:person/post:name != '') then 'color: #0099CC' else 'color: #FF0000'

which should return the blue color but it shows the red one. I'm
attaching the modified xhtml in attachment.
I ran it in the XForms sandbox but it does not even return anything.

Jimmy Royer

Ryan Puddephatt wrote:

> Jimmy
>
> Try
>
> <div style="{if(post:person/@registered = true()) then 'color: #0099CC' else
> ''}">
>
> That should work
>
> Ryan Puddephatt
> Software Engineer
> TFX Group - IT UK
> 1 Michaelson Square
> Livingston
> West Lothian
> Scotand
> EH54 7DP
>  
> * [hidden email]
> ( 01506 407 110
> 7  01506 407 108
>  
>
>  
>> -----Original Message-----
>> From: Jimmy Royer [mailto:[hidden email]]
>> Sent: 12 April 2006 17:14
>> To: [hidden email]
>> Subject: [ops-users] Iteration and conditional in XForms
>>
>> Hi everyone, apprentice here and I have an easy question.
>>
>> I need to iterate through a list from my main instance. At first I was
>> doing so with XSLT tags <choose> and
>> <when>, but then I decided to do it via XForms tag <repeat> so I could
>> easily manipulate elements after
>> the page loading.
>>
>> <xforms:repeat nodeset="post:comments/post:comment">
>>  <xforms:output ref="post:person/post:name"/>
>>  (<xforms:output ref="post:person/post:email"/>)
>> </xforms:repeat>
>>
>> It works quite well. My problem now is that I need to change the color
>> of the police when
>> the post:person/@registered attribute is true or false. I need a simple
>> XForms conditional to check
>> whether the attribute is true or false, so I can enclose the outputs in
>> a xhtml:div tag.
>>
>> Is it possible to put a condition on a xforms tag that I could use like
>> that?
>>
>> <xforms:condition value="my condition>
>>  <div style="color: #0099CC">
>>    <xforms:output ref="post:person/post:name"/>
>>    (<xforms:output ref="post:person/post:email"/>)
>>  </div>
>> </xforms:condition>
>>
>>
>> I thought I had a solution with binds with the relevant property:
>>
>> <head>
>> <xforms:model>
>>   ...
>>   ...
>>      <xforms:instance id="control-instance">
>>        <control xmlns="">
>>          <poster-status>
>>            <registered/>
>>            <unregistered/>
>>          </poster-status>
>>        </control>
>>      </xforms:instance>
>>
>>      <xforms:bind nodeset="instance('control-instance')/poster-status">
>>        <xforms:bind nodeset="registered"
>>
>> relevant="instance('posts-
>> instance')/post:comments/*/post:person/@registered
>> = 'true'"/>
>>        <xforms:bind nodeset="unregistered"
>>
>> relevant="instance('posts-
>> instance')/post:comments/*/post:person/@registered
>> = 'false'"/>
>>      </xforms:bind>
>> </xforms:model>
>> </head>
>>
>> <body>
>> <xforms:repeat nodeset="post:comments/post:comment">
>>  <xforms:group ref="instance('control-instance')/poster-
>> status/registered">
>>    <div style="color: #0099CC">
>>      <xforms:output ref="post:person/post:name"/>
>>      (<xforms:output ref="post:person/post:email"/>)
>>    </div>
>>  </xforms:group>
>>  <xforms:group
>> ref="instance('control-instance')/poster-status/unregistered">
>>      <xforms:output ref="post:person/post:name"/>
>>      (<xforms:output ref="post:person/post:email"/>)
>>  </xforms:group>
>> </xforms:repeat>
>> </body>
>>
>> It doesn't work though as first I can't reference element of the loop
>> inside a different group. Second
>> it doesn't seem the relevant condition in the xform binds apply for each
>> individual element in the loop.
>> If I put
>> instance('posts-instance')/post:comments/comment[1]/post:person/@registered
>> then it works
>> but.. yeah that is not what I need.
>>
>> Anyone know how to make it work? If there is a simpler solution?
>>
>> I'll attach a simplified file with the mentioned code.
>>
>> Jimmy Royer
>>
>>
>>    


--
You receive this message as a subscriber of the [hidden email] mailing list.
To unsubscribe: mailto:[hidden email]
For general help: mailto:[hidden email]?subject=help
ObjectWeb mailing lists service home page: http://www.objectweb.org/wws

post-view-xpath.xhtml (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Iteration and conditional in XForms

Alessandro  Vernet
Administrator
On 4/12/06, Jimmy Royer <[hidden email]> wrote:
> if(post:person/post:name != '') then 'color: #0099CC' else 'color: #FF0000'

There is no really good solution to this right now in XForms, because
you can't dynamically generate the value of an attribute the way you
would in XSLT. Your code does not work because your expression between
{} is evaluated by XSLT and does not have the right context. (And in
the XForms sandbox it won't even be evaluated because your file does
not go through XSLT.)

Here is what I suggest:

<xforms:group ref="if (post:person[@registered = 'true']) then . else ()">
    <div style="color: #0099CC">
        <xforms:output ref="post:person/post:name"/>
        (<xforms:output ref="post:person/post:email"/>)
    </div>
</xforms:group>
<xforms:group ref="if (post:person[@registered = 'false']) then . else ()">
    <div style="color: #FF0000">
        <xforms:output ref="post:person/post:name"/>
        (<xforms:output ref="post:person/post:email"/>)
    </div>
</xforms:group>

I have also attached the whole file. Essentially for each row, only
one of the two groups will show. It will show when the ref="..."
expression returns a non-empty sequence. The downside is that you have
to duplicate the content of the <div> in your code. You can avoid code
duplication by putting the content in an XSLT variable and copying
this variable in each <div>.

Alex
--
Blog (XML, Web apps, Open Source):
http://www.orbeon.com/blog/


--
You receive this message as a subscriber of the [hidden email] mailing list.
To unsubscribe: mailto:[hidden email]
For general help: mailto:[hidden email]?subject=help
ObjectWeb mailing lists service home page: http://www.objectweb.org/wws

post-view-xpath.xhtml (4K) Download Attachment
--
Follow Orbeon on Twitter: @orbeon
Follow me on Twitter: @avernet
Reply | Threaded
Open this post in threaded view
|

Re: Iteration and conditional in XForms

Jimmy Royer
It works! Thank you for your insights Alex, and also for your valuable time.

Jimmy

Alessandro Vernet wrote:

> On 4/12/06, Jimmy Royer <[hidden email]> wrote:
>  
>> if(post:person/post:name != '') then 'color: #0099CC' else 'color: #FF0000'
>>    
>
> There is no really good solution to this right now in XForms, because
> you can't dynamically generate the value of an attribute the way you
> would in XSLT. Your code does not work because your expression between
> {} is evaluated by XSLT and does not have the right context. (And in
> the XForms sandbox it won't even be evaluated because your file does
> not go through XSLT.)
>
> Here is what I suggest:
>
> <xforms:group ref="if (post:person[@registered = 'true']) then . else ()">
>     <div style="color: #0099CC">
>         <xforms:output ref="post:person/post:name"/>
>         (<xforms:output ref="post:person/post:email"/>)
>     </div>
> </xforms:group>
> <xforms:group ref="if (post:person[@registered = 'false']) then . else ()">
>     <div style="color: #FF0000">
>         <xforms:output ref="post:person/post:name"/>
>         (<xforms:output ref="post:person/post:email"/>)
>     </div>
> </xforms:group>
>
> I have also attached the whole file. Essentially for each row, only
> one of the two groups will show. It will show when the ref="..."
> expression returns a non-empty sequence. The downside is that you have
> to duplicate the content of the <div> in your code. You can avoid code
> duplication by putting the content in an XSLT variable and copying
> this variable in each <div>.
>
> Alex
> --
> Blog (XML, Web apps, Open Source):
> http://www.orbeon.com/blog/
>  



--
You receive this message as a subscriber of the [hidden email] mailing list.
To unsubscribe: mailto:[hidden email]
For general help: mailto:[hidden email]?subject=help
ObjectWeb mailing lists service home page: http://www.objectweb.org/wws