W3C home > Mailing lists > Public > www-forms@w3.org > September 2006

RE: Nested repeat and xf:delete question ...

From: Klotz, Leigh <Leigh.Klotz@xerox.com>
Date: Mon, 18 Sep 2006 11:32:33 -0700
Message-ID: <E254B0A7E0268949ABFE5EA97B7D0CF40238C790@usa7061ms01.na.xerox.net>
To: Sébastien CRAMATTE <contact@zeninteractif.com>, "Xforms W3C Mailing list" <www-forms@w3.org>
Cc: "John Boyer" <boyerj@ca.ibm.com>
Sebastien,
If you choose John's trigger-inside-repeat pattern, you can additionally use CSS to suppress the insert and delete buttons on every row except the current one.
1. Put the buttons inside a group, and style it by class as "display:none".
2. Override that style when inside ::repeat-index with "display:inline"
3. When the user clicks inside one of the input lines on the row, it will become the selected repeat row, and the buttons will "move".
 
Here's some partially-written code for doing this, extracted from a working example.
 
Your CSS styles may vary; these are CSS3.
In Mozilla you need .xf-repeat-index and .xf-value instead of ::repeat-index and ::value.
In Chiba you need .value and .repeat-index.
 
<html xmlns="http://www.w3.org/1999/xhtml <http://www.w3.org/1999/xhtml> "
      xmlns:xf="http://www.w3.org/2002/xforms <http://www.w3.org/2002/xforms> " xmlns:ev="http://www.w3.org/2001/xml-events <http://www.w3.org/2001/xml-events> ">
  <head>
    <xf:model>
      <xf:instance>
        <data xmlns="">
          <items>
            <item name="a">123</item>
            <item name="b">456</item>
          </items>
        </data>
      </xf:instance>
    </xf:model>
    <style type="text/css">
      .MyName::value { width: 5em; }
      .MyItemValue::value { width: 35em; }
      .MyItemsRowButtons { display: none; }
      ::repeat-index .MyItemsRowButtons { display: inline; }
    </style>
  </head>
  <body>
    <xf:repeat id='myRepeat' nodeset="items/item">
      <xf:input class="MyName" ref="@name"><xf:label>Name</xf:label></xf:input>
      <xf:input class="MyItemValue" ref="."><xf:label>Value</xf:label></xf:input>
      <xf:group class="MyItemsRowButtons">
        <xf:trigger appearance="minimal">
          <xf:label><img src='/images/add.png' alt='+' /></xf:label>
          <xf:hint>Add an item here</xf:hint>
          <xf:action ev:event="DOMActivate">
            <xf:insert nodeset="../item" at="index('myRepeat')" position="after"  />
            <xf:setvalue ref="../item[index('myRepeat')]">New Value</xf:setvalue>
            <xf:setvalue ref="../item[index('myRepeat')]/@name">New Name</xf:setvalue>
          </xf:action>
        </xf:trigger>
        <xf:trigger appearance="minimal">
          <xf:label><img src='/images/delete.png' alt='X' /></xf:label>
          <xf:hint>Delete this item</xf:hint>
          <xf:delete nodeset="../item" at="index('myRepeat')" ev:event="DOMActivate" />
        </xf:trigger>
      </xf:group>
    </xf:repeat>
  </body>
</html>

Leigh.

________________________________

From: www-forms-request@w3.org [mailto:www-forms-request@w3.org] On Behalf Of John Boyer
Sent: Monday, September 18, 2006 11:09 AM
To: Sébastien CRAMATTE
Cc: Xforms W3C Mailing list; www-forms-request@w3.org
Subject: Re: Nested repeat and xf:delete question ...



Hi Sebastien, 

There are basically two patterns you would use for a "delete button" (by which I mean a trigger with a delete action attached to the DOMActivate event). 

The first is to have the trigger inside the repeat and the other is to have it outside the repeat. 

When a deletion trigger appears outside of a repeat, the delete action typically has a nodeset attribute with the same nodeset expression as the repeat, and the at attribute uses the index() function to cause deletion of the node of data corresponding to the current row of the repeat. 

When a deletion trigger appears inside of a repeat, it is duplicated on every row of the repeat, so the deletion trigger and hence the delete action already have an in-scope evaluation context equal to the very node you would like to delete.  So, instead of setting the nodeset attribute equal to the same thing as the repeat, you have to recognize that the repeat itself is already giving the correct context to the delete action.  So, you only have to say <delete nodeset="." at="1"/> and you're done. 

I think the confusion you were having about the 'at' attribute is because you were trying to set up the deletion trigger as if it were not inside the repeat.  It turns out that you can do this too.  And, the whole delete action looks almost identical when it is inside versus when it is outside of the repeat.  So, you should also be able to write your delete below as follows:   

<form:delete ev:event="DOMActivate" nodeset="../concentre:feature" at="index('repeat-features')" /> 

This version of the at attribute works because when the user activates the delete trigger, the very first thing an XForms implementation does is set the index of the repeat so that the row containing the input focus is regarded as the "current" row of the repeat. 

As you correctly deduced, the nodeset attribute required the leading ../ because the repeat sets the in-scope evaluation context to be a particular concentre:feature, which differs on each row, so you back up to the parent of the homogeneous collection of concentre:feature elements, then select them all.  The 'at' attribute then chooses the one corresponding to the row containing the trigger you just activated. 

Best regards, 
John M. Boyer, Ph.D.
Senior Product Architect/Research Scientist
Co-Chair, W3C XForms Working Group
Workplace, Portal and Collaboration Software
IBM Victoria Software Lab
E-Mail: boyerj@ca.ibm.com  http://www.ibm.com/software/

Blog: http://www.ibm.com/developerworks/blogs/page/JohnBoyer





Sébastien CRAMATTE <contact@zeninteractif.com> 
Sent by: www-forms-request@w3.org 

09/18/2006 08:50 AM 

To
Xforms W3C Mailing list <www-forms@w3.org> 
cc
Subject
Nested repeat  and xf:delete  question ...

	





Hello list,

I've made this forms. It use nested repeat and works quite well.
My only problem is that I want to put delete trigger  in  nested-repeat
to delete a specific line
but I don't know which value I should put in @at  attribute .... Look at
button  "Delete this feature"

I hope that someone have got the answer or any tips
Regards


           <form:repeat nodeset="concentre:release" id="repeat-release">
               <form:group>
                   <form:label>Release</form:label>
                  
             <form:input ref="concentre:label" >
                      <form:label>Label:</form:label>
                  </form:input>
                  
                   <form:group ref="concentre:features"
appearance="minimal">
                   <form:repeat nodeset="concentre:feature"
id="repeat-features">
                       <form:group>
                           <form:label>Feature</form:label>

                     <form:input ref="concentre:label" >
                       <form:label>Name:</form:label>
                     </form:input>
                     <form:select1 ref="concentre:status"
appearance="minimal">
                       <form:label>Status:</form:label>
                       <form:item><form:label>Todo</form:label> 
<form:value>todo</form:value>  </form:item>
                       <form:item><form:label>Done</form:label>
<form:value>done</form:value> </form:item>
                       <form:item><form:label>Working on</form:label>
<form:value>workingon</form:value> </form:item>
                       <form:item><form:label>Discarded</form:label>
<form:value>discarded</form:value> </form:item>
                     </form:select1>
                    
                     <form:trigger>
                       <form:label>Delete this feature</form:label>
                       <form:delete ev:event="DOMActivate"
nodeset="../concentre:feature" at="1" />
                     </form:trigger>
                 </form:group>
                    </form:repeat>
                   
                   <form:trigger>
               <form:label>Add a feature</form:label>
               <form:insert ev:event="DOMActivate"
nodeset="concentre:feature" at="last()" position="after"/>
                 </form:trigger>

             </form:group>
           </form:group>
           </form:repeat>
                   <form:trigger>
               <form:label>Add release</form:label>
               <form:insert ev:event="DOMActivate"
nodeset="concentre:release" at="last()" position="after"/>
                 </form:trigger>
Received on Monday, 18 September 2006 18:33:12 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Saturday, 10 March 2012 06:22:06 GMT