Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Make the most of XForms repeats

Managing iteration over data sets in your open-standards form

Jan J. Kratky, Advisory Software Engineer, IBM 
Jan Joseph Kratky is the lead developer for the Compound XML Document Editor and XML Forms Generator. Currently a software engineer with IBM Emerging Software Standards in Research Triangle Park, North Carolina, he holds a B.A. from Cornell University and an M.S. from Rensselaer Polytechnic Institute. A Sun Certified Java Programmer and Sun Certified Web Component Developer, Jan has worked with Java technologies since 1997, and with Eclipse technologies since 2001.
Steve K Speicher (sspeiche@us.ibm.com), Senior Software Engineer, IBM 
Steve Speicher is an IBM Senior Software Engineer working on emerging standards, both infrastructure based and industry verticals (healthcare). He is a member of the W3C Compound Document Formats Working Group, he led the development of the Compound XML Document Toolkit, and he uses Model-Driven Development (MDD) to improve the development of standards. He has previously worked on change and release management tools in the Rational division and in IBM internal tools.

Summary:  XForms provides many powerful mechanisms for working with XML data. One such mechanism is the "repeat" element, which allows you to quickly and easily implement iteration over homogeneous data sets in your XML. In addition, you can format the presentation of such sets as tables, as well as provide dynamic behavior like the insertion and deletion of specific pieces of data within the repeating set. Read on for some tips and tricks on how to make the most of your XForms repeats.

Date:  21 Nov 2006
Level:  Intermediate
Also available in:   Chinese  Japanese

Activity:  10605 views
Comments:  

What is an XForms repeat?

The repeat element allows you to map your XForms user interface (UI) elements to a homogeneous collection in your XForms document's XML data instance. A "homogenous collection" is taken to be a series of nodes of the same datatype at the same level in the document. For example, in Listing 1, below, the set of bread elements is a homogeneous collection of nodes within the XML instance.


Listing 1. A homogeneous collection of XML nodes
        
<xforms:instance id="in-stock">
    <in-stock>
        <groceries>
            <perishable>          
                <bread brand="Wonder" quantity="1"/>
              <bread brand="Merita" quantity="2"/>
              <bread brand="Arnold" quantity="4"/>             
            </perishable>
        </groceries>
    </in-stock>
</xforms:instance>

To associate a repeat element with the homogeneous set, you simply refer to it by specifying XPath in the nodeset attribute of a repeat element, as in Listing 2, below.


Listing 2. Binding a repeat to the homogeneous collection
        
<xforms:repeat id="bread-repeat" nodeset="instance('in-stock')/perishable/bread">
    ...

Notice also in Listing 2 that the repeat was given an id value, so we can refer to it later from other XForms constructs.

Now, you can place UI elements within the repeat element, and when you view the form the UI elements will be "unrolled", so that one control will appear for each member in the homogeneous set. Listing 3 shows an XForms input UI element bound to an attribute within the homogeneous set from Listing 1. Notice that the reference into the data instance from the input element is made relative to the nodeset defined for the surrounding repeat.


Listing 3. UI elements within a repeat
        
<xforms:repeat id="bread-repeat" 
               nodeset="instance('in-stock')/groceries/perishable/bread">
    <xforms:input ref="@brand">
        <xforms:label>Brand of bread: </xforms:label>
    </xforms:input>      
</xforms:repeat>

Listing 4 gives an indication of the "unrolled" version that really would be rendered. (You would never see this source when developing the form; it's just here to demonstrate a renderer's interpretation of the repeat construct.)


Listing 4. The repeat from Listing 3, unrolled
        
    <xforms:input ref="instance('in-stock')/groceries/perishable/bread[1]/@brand">
        <xforms:label>Brand of bread: </xforms:label>
    </xforms:input>
    <xforms:input ref="instance('in-stock')/groceries/perishable/bread[2]/@brand">
        <xforms:label>Brand of bread: </xforms:label>
    </xforms:input>
    <xforms:input ref="instance('in-stock')/groceries/perishable/bread[3]/@brand">
        <xforms:label>Brand of bread: </xforms:label>
    </xforms:input>

Figure 1 shows what this construct looks like when rendered in Mozilla Firefox with the XForms Extension (see Resources for information on how to get the Firefox XForms Extension).


Figure 1. The repeat, rendered
The repeat, rendered

Formatting repeats as tables

Very often, it makes sense to display data from a homogeneous set in a table format. In the XForms Extension for Firefox, formatting repeats into a display having the appearance of a table requires some work with cascading stylesheets (CSS).

First, the source in Listing 5 shows the markup in the body of the document, to which the CSS definitions will apply. Note that the table and column headers are declared with XHTML markup. However, the "body" of the table consists entirely of an XForms repeat.


Listing 5. Markup for presenting a repeat as a table

<xhtml:table>
    <xhtml:tr>
        <xhtml:thead>
            <xhtml:th>Brand Name</xhtml:th>
            <xhtml:th>Quantity</xhtml:th>
        </xhtml:thead>
    </xhtml:tr>
    <xforms:repeat id="bread-repeat" 
                   nodeset="instance('in-stock')/groceries/perishable/bread">
        <xforms:output ref="@brand">
            <xforms:label/>
        </xforms:output>
        <xforms:input ref="@quantity">
            <xforms:label/>
        </xforms:input>
    </xforms:repeat>
</xhtml:table>

Listing 6 gives the style definition we'll use for our repeat. The CSS declarations are placed within an XHTML style tag (you can also refer to CSS stored in an external file using the src attribute on the style tag).


Listing 6. CSS for styling a repeat as a table
        
<xhtml:style type="text/css">
    @namespace xforms url("http://www.w3.org/2002/xforms");
    @namespace xhtml url("http://www.w3.org/1999/xhtml");

    xhtml|th 
    { 
        width: 240px; 
    }

    xforms|repeat .xf-repeat-item 
    {
        display: table-row;
        width:   480px;
    }

    xforms|repeat xforms|output, xforms|repeat xforms|input
    {
       display:          table-cell;
       border:           thin;
       border-style:     solid;
       width:            240px;
       text-align:       center;
       background-color: lightgray;  
    }
</xhtml:style>

Listing 6 approaches the styling by declaring that each item (that is, each row) in the repeat is to be displayed as a row in a table. Then, the next declaration asserts that each XForms output and input control within a repeat will be treated as a table cell, having a solid border and a light gray background.

Figure 2 shows the result when rendered in Mozilla Firefox with the XForms Extension.


Figure 2. A repeat rendered as a table
A repeat rendered as a table

There are other stylings that could be used to get a similar effect in Firefox. Furthermore, other XForms renderers might permit different approaches altogether. One example of an alternate approach is the use of some optional attributes defined in the XForms 1.0 specification, particularly repeat-nodeset. These attributes could be placed on a non-XForms element to define a repeating structure that applies to that element's children. Listing 7 shows an example of the usage of repeat-nodeset on the XHTML table element.


Listing 7. Using the repeat-nodeset attribute
    
<xhtml:table>
    <xhtml:tr>
        <xhtml:thead>
            <xhtml:th>Brand Name</xhtml:th>
            <xhtml:th>Quantity</xhtml:th>
        </xhtml:thead>
    </xhtml:tr>
</xhtml:table>
<xhtml:table xforms:repeat-nodeset="instance('in-stock')/groceries/perishable/bread">
    <xhtml:tr>
        <xhtml:td>
            <xforms:output ref="@brand">
                <xforms:label/>
            </xforms:output>
        </xhtml:td>
        <xhtml:td>
            <xforms:input ref="@quantity">
                <xforms:label/>
            </xforms:input>          
        </xhtml:td>      
    </xhtml:tr>
</xhtml:table>

Using the repeat attributes on non-XForms elements is an elegant approach. It's supported by some XForms implementations, including the XForms Extension for Firefox.

Inserting and deleting rows

So far, we've looked at presenting repeating structures as they exist in the XML data instance. However, XForms allows users to do much, much more with that data. In particular, it's very common to want to add a new row to a table, or delete an existing row. Listing 8 shows the markup for permitting the user to trigger deletion and insertion of rows in your repeating set.


Listing 8. Enabling insert and delete of rows

<xforms:trigger>
    <xforms:label>Insert Row</xforms:label>
    <xforms:insert ev:event="DOMActivate"
                   at="index('bread-repeat')" position="after"
                   nodeset="instance('in-stock')/groceries/perishable/bread"/>
</xforms:trigger>
<xforms:trigger>
    <xforms:label>Delete Row</xforms:label>
    <xforms:delete ev:event="DOMActivate"
                   at="index('bread-repeat')"
                   nodeset="instance('in-stock')/groceries/perishable/bread"/>
</xforms:trigger>

Listing 8 introduces the concept of a repeat "index". Notice the use of the index() function within the at attribute of the insert and delete actions. The value given in the value of the at attribute represents the 1-based index into the repeat's data set at which the insert or delete will occur. By using the index() function within the value of this attribute, we are specifying that the insert or delete will occur at the currently selected row in the repeat. In the case of the delete action, this means that the currently selected row will be deleted. For the insert action, this means that the new row will be inserted either directly before or after the row at the selected index. Whether the new row is inserted before or after the currently selected row depends on the value given in the insert element's position attribute.

When an insert action is triggered, the last row of the repeat is cloned, and it is that clone of the repeat that is inserted. This generally means that the values for the elements and attributes of that row are brought along as well. As this may not be the desired behavior, you may want to follow an insert with a setvalue action to reset the value, as in Listing 9. The index() function is again used to specify the currently-selected row of the repeat as the one on which the setvalue action will occur. This suits the intended purpose -- to target the just-inserted row -- since the insert action resets the repeat's index to be that of the just-inserted row.


Listing 9. Resetting the inserted value

<xforms:trigger>
    <xforms:label>Insert Row</xforms:label>
    <xforms:action ev:event="DOMActivate">
        <xforms:insert at="index('bread-repeat')"
                       position="after" 
                       nodeset="instance('in-stock')/groceries/perishable/bread"/>
        <xforms:setvalue 
                    ref="instance('in-stock')/
                         groceries/perishable/bread[index('bread-repeat')]/@quantity"
                    value="0"/>
    </xforms:action>
</xforms:trigger>

Implementing triggers for inserting and deleting rows in a repeat is a very common pattern. In fact, automated XForms-generation tools, specifically the IBM® XML Forms Generator (see Resources) will automatically generate triggers for addition and deletion with every repeat.

Preventing deletion of the last row

In the previous section, we established that an insert action clones the last row in the repeat. This is very bad news when the repeat no longer has any rows, possibly because the user has triggered delete actions on all of them. The net result is that, in the earlier examples, if all rows are deleted, the insert action will no longer do anything.

Therefore, you may wish to prevent deletion of the last row. Listing 10 shows one approach, which is to bind the "Delete" trigger to a node in the data model, and then to make that node non-relevant when the count of nodes in the set reaches 1.


Listing 10. Preventing deletion of the last row

<xforms:instance id="trigger-controller">
    <trigger-sets>
        <trigger-set>
            <insert-trigger/>
            <delete-trigger/>
        </trigger-set>
    </trigger-sets>
</xforms:instance>
<xforms:bind nodeset="instance('trigger-controller')/trigger-set/delete-trigger"
             relevant="count(instance('in-stock')/groceries/perishable/bread) > 1"/>
		                 
        ...
        
<xforms:trigger ref="instance('trigger-controller')/trigger-set/insert-trigger">
    <xforms:label>Insert Row</xforms:label>
    <xforms:insert ev:event="DOMActivate" at="index('bread-repeat')"
                   position="after" 
                   nodeset="instance('in-stock')/groceries/perishable/bread"/>
</xforms:trigger>
<xforms:trigger ref="instance('trigger-controller')/trigger-set/delete-trigger">
    <xforms:label>Delete Row</xforms:label>
    <xforms:delete ev:event="DOMActivate" at="index('bread-repeat')"
                   nodeset="instance('in-stock')/groceries/perishable/bread"/>
</xforms:trigger>

When the node referenced by the trigger becomes non-relevant, the trigger becomes "unavailable". In Firefox, the default behavior is for the button to disappear from the page, as shown in Figure 3, which shows the form before and after the next-to-last row is deleted.


Figure 3. Preventing deletion of the last row
Preventing deletion of the last row

You may wish to experiment with other approaches using the "relevant" property; for example, always making the last row of the repeat non-relevant. That way, the last row can never be selected, and therefore can never be deleted when you are depending on the repeat index to determine the delete location.

Listing 11 shows how you might add a "prototype" entry to your data instance, and then add binds to make that last entry always non-relevant. To ensure that the last row is never displayed, a new CSS entry is made, keying on the ".disabled" CSS cue. The repeat element and its contents require no change at all for this approach.


Listing 11. Data with two-deep nesting

<xforms:model>
    <xforms:instance id="in-stock">
        <in-stock>
            <groceries>
                <perishable>
                    <bread brand="Wonder" quantity="1" />
                    <bread brand="Merita" quantity="2" />
                    <bread brand="Arnold" quantity="4" />
                    <bread brand="Not sure yet" quantity="0" />
                </perishable>
            </groceries>
        </in-stock>
    </xforms:instance>
    <xforms:bind nodeset="instance('in-stock')/groceries/perishable/bread
                          [count(instance('in-stock')/groceries/perishable/bread)]/
                          @brand"
		 relevant="false()"/>
    <xforms:bind nodeset="instance('in-stock')/groceries/perishable/bread
                          [count(instance('in-stock')/groceries/perishable/bread)]/
                          @quantity"
		 relevant="false()"/>
</xforms:model>
<xhtml:style type="text/css">
    @namespace xforms url("http://www.w3.org/2002/xforms");
    xforms|*:disabled { display: none; }
</xhtml:style>

For now, using a technique like this is necessary to prevent deletion of your insert prototype. However, there is help on the horizon. The XForms 1.1 specification will address this and other shortcomings with the insert and delete actions, making workarounds like the ones shown here no longer necessary.

Nesting repeats

The power of XForms really shows itself when you have data that contains homogeneous data sets at different levels, with one nested within the other. For example, Listing 12 shows a data instance in which a top-level homogeneous set of elements consists of the three item elements. Then, each item element contains a set of its own info elements.


Listing 12. Data with two-deep nesting

<xforms:instance id="in-stock">
    <in-stock>
        <groceries>
            <perishable>
                <item type="bread">
                    <info brand="Wonder" quantity="1"/>
                    <info brand="Merita" quantity="2"/>
                    <info brand="Arnold" quantity="4"/>	                    
                </item>
                <item type="peanut butter"">
                    <info brand="Skippy" quantity="2"/>		                
                    <info brand="Jif" quantity="1"/>
                </item>
                <item type="jelly">
                    <info brand="Smuckers" quantity="1"/>
                    <info brand="Welch's" quantity="3"/>	                    
                </item>
            </perishable>
        </groceries>
    </in-stock>
</xforms:instance>

XForms makes it easy to iterate over nested sets like this through the nesting of the corresponding repeats. Listing 13 shows how to do it.


Listing 13. Defining nested repeats

<xforms:repeat id="bread-repeat" nodeset="instance('in-stock')/groceries/perishable/item">
    <xforms:output ref="@type">
        <xforms:label>Item type: </xforms:label>
    </xforms:output>
    <xforms:repeat id="bread-repeat" nodeset="info">
        <xforms:output ref="@brand">
            <xforms:label>Brand: </xforms:label>
        </xforms:output>
        <xforms:input ref="@quantity">
            <xforms:label>Quantity: </xforms:label>
        </xforms:input>
    </xforms:repeat>
    <xhtml:hr/>
</xforms:repeat>

Listing 13 defines an output within the outermost repeat, for which each item type is displayed. Then, an inner repeat iterates over the info elements within each item. Notice that the XPath in the inner repat's nodeset attribute is defined relative to the nodeset of its containing repeat. Figure 4 shows how these nested repeats would look in Firefox.


Figure 4. The nested repeat, rendered
The nested repeat, rendered

The power of XForms shows itself once again with the fact that there are no limits to the depth with which you can nest repeats. The only constraints are renderer performance and the desire to maintain a clean, easy-to-navigate interface for the end-user.

Managing a repeat's index

During our discussion of the insert and delete actions, we touched on the concept of the repeat's index -- that is, the one-based index of the currently selected "row".

The user may make the selection, or you can force a selection programmatically in one of two ways.

Firstly, you can specify the index of the repeat at the time the form is first rendered by specifying an integer value for the attribute of repeat called startindex. Unlike some of the other XForms facilities for dealing with indices, you cannot specify an XPath expression here; according to the XForms 1.0 specification, only a positive integer value will do.

Secondly, you may also set the index of a repeat with the setindex action in response to the user activating a trigger, or perhaps as part of some other action (for example, resetting the index to a desired value after an insert or delete). Listing 14 gives some markup which initially sets the index to 2, and then allows the user to enter a value for the index and set it to that value by activating the trigger labeled "Select".


Listing 14. Using setindex

    <xforms:instance id="target-index">
        <target-index>
            <value>1</value>
        </target-index>
    </xforms:instance>
		    
    ...
		    
    <xhtml:table>
        <xhtml:tr>
            <xhtml:thead>
                <xhtml:th>Brand Name</xhtml:th>
                <xhtml:th>Quantity</xhtml:th>
            </xhtml:thead>
        </xhtml:tr>
        <xforms:repeat id="bread-repeat" 
                       nodeset="instance('in-stock')/groceries/perishable/bread" 
                       startindex="2">		      
            <xforms:output ref="@brand">
                <xforms:label/>
            </xforms:output>
            <xforms:input ref="@quantity">
                <xforms:label/>
            </xforms:input>
        </xforms:repeat>
    </xhtml:table>
	    
    <xforms:input ref="instance('target-index')/value">
        <xforms:label>Target Index: </xforms:label>
    </xforms:input>
    <xforms:trigger>
        <xforms:label>Select</xforms:label>
        <xforms:setindex ev:event="DOMActivate"
                        repeat="bread-repeat" 
                        index="instance('target-index')/value"/>
    </xforms:trigger>		    

In Listing 14, a data instance has been added to hold the desired value of the repeat index. The input control is bound to this data, so whenever a user enters a new value, that value gets placed in the value element. Finally, the setvalue action tied to the trigger references that same value element in its index attribute, which can take an XPath expression. Figure 5 shows the resulting form in Firefox.


Figure 5. Allowing the user to input the repeat index
Allowing the user to input the repeat index

Figure 5 shows the selected row having a different appearance from the other rows. Without a visual cue like this, it's likely to be unclear to the user which row is currently selected. You can use CSS to provide the user with an indicator of the currently selected row. In Firefox, CSS such as that shown in Listing 15 targets the selected index.


Listing 15. Styling for the repeat index

xforms|repeat .xf-repeat-index > xforms|*
{
    color:            white;
    background-color: black;
    border:           none;
}

The number attribute

The number attribute on the XForms repeat element is a hint to the renderer as to the number of repeat items (or rows) to display at any one time. Support for this attribute is optional for XForms processors, so many renderers do not support it. However, some renderers, such as the FormsPlayer plug-in for Microsoft® Internet Explorer (see Resources), do support the number attribute.

Use of the number attribute can permit a cleaner presentation, particularly of repeats over very large sets of data. It may also improve performance, as not every item in the repeat will need to have its associated controls redrawn when the data changes.

Let's say that, using the data instance from Listing 1, we want only one row of data to be presented at a time. We would simply add a value of 1 to the repeat element as defined in Listing 2. The result would be as shown in Listing 16.


Listing 16. Applying the number attribute to the repeat

<xforms:repeat id="bread-repeat" 
               nodeset="instance('in-stock')/groceries/perishable/bread" 
               number="1">
...

Now, it's great that so much space is saved by showing only one repeat row at a time, but a user of this form may want to manipulate the data for a row other than the one initially shown. You can give users the opportunity to access other repeat items by allowing the user to set the current index of the repeat. Listing 17 shows how to enable this by leveraging the setindex action.


Listing 17. Allowing navigation of the repeat

<xforms:trigger>
    <xforms:label>< < Previous</xforms:label>
    <xforms:setindex ev:event="DOMActivate" repeat="bread-repeat"
                     index="index('bread-repeat') - 1"/>
</xforms:trigger>
<xforms:trigger>
    <xforms:label>Next > ></xforms:label>
    <xforms:setindex ev:event="DOMActivate" repeat="bread-repeat"
                     index="index('bread-repeat') + 1"/>
</xforms:trigger>

Listing 17 provides buttons labeled "< < Previous" and "Next > >", which when pressed will decrement and increment, respectively, the index of the repeat. This allows the form's user to scroll back and forth through the data in the repeat.

Figure 6 shows what our scrollable repeat would look like in Internet Explorer, using the FormsPlayer plug-in.


Figure 6. The scrollable repeat
The scrollable repeat

The power of XForms

XForms repeats are one of the more powerful constructs in XForms. If you have not done so already, go ahead and grab a renderer -- such as the free download of the XForms Extension for Mozilla Firefox (see Resources) -- and try these techniques out for yourself.


Resources

Learn

  • Dig into XForms at the home page of W3C XForms, which has links to the official XForms specification, as well as to a wide variety of XForms rendering options.

  • Find out more about XHTML, Cascading Style Sheets (CSS), XML, XML Events, XPath, and other related standards at the W3C site.

Get products and technologies

  • Mozilla XForms: Render your standards-compliant forms in Mozilla Firefox using this plug-in.

  • Get MozzIE, an open-source control that allows you to render XForms in Internet Explorer.

  • Try FormsPlayer, a plug-in for Internet Explorer that renders XForms.

  • XML Forms Generator: Create functional, standards-compliant forms with a click of the mouse using this Eclipse-based tool from alphaWorks.

  • Visual XForms Designer: Check out the home page, with links to installation instructions, prerequisites, and the forum.

  • Compound XML Document Toolkit: Explore other open-standard XML markups, including Scalable Vector Graphics (SVG), MathML, VoiceXML, and Synchronized Multimedia Integration Language (SMIL).

Discuss

  • Get answers to your questions about the Visual XForms Designer on its discussion forum.

About the authors

Jan Joseph Kratky is the lead developer for the Compound XML Document Editor and XML Forms Generator. Currently a software engineer with IBM Emerging Software Standards in Research Triangle Park, North Carolina, he holds a B.A. from Cornell University and an M.S. from Rensselaer Polytechnic Institute. A Sun Certified Java Programmer and Sun Certified Web Component Developer, Jan has worked with Java technologies since 1997, and with Eclipse technologies since 2001.

Steve Speicher is an IBM Senior Software Engineer working on emerging standards, both infrastructure based and industry verticals (healthcare). He is a member of the W3C Compound Document Formats Working Group, he led the development of the Compound XML Document Toolkit, and he uses Model-Driven Development (MDD) to improve the development of standards. He has previously worked on change and release management tools in the Rational division and in IBM internal tools.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=XML, Web development
ArticleID=175548
ArticleTitle=Make the most of XForms repeats
publish-date=11212006
author1-email=kratky@us.ibm.com
author1-email-cc=dwxed@us.ibm.com
author2-email=sspeiche@us.ibm.com
author2-email-cc=dwxed@us.ibm.com

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers