xforms:deleteAdded by IBM on October 10, 2012 | Version 1 (Original)
|Deletes a row of elements from a table. The elements are first deleted from the XForms model, then the table's repeat deletes the visible items that were linked to those data elements.
Table 1. delete parameters
<xforms:delete event nodeset="nodeset binding" at="at "context="context"/>
<xforms:delete nodeset="nodeset binding" at="index" context="parent"/>
|event||string||The XForms event that triggers the action. |
|nodeset binding||special||Defines the set of child nodes to be deleted.|
|at||string||An index number that determines which row to delete. Indexing is one-based, meaning the first row is row 1, the second row is row 2, and so on.|
|context||XPath||Not required. Added only to allow symmetry of syntax with xfoms:insert.|
Example This example assumes you are working with a purchase order form that includes the following data instance:
This data instance includes multiple <row> elements that represent the rows in a table. The last row is a "template" row. Template rows are not visible to the user. It simply contains the basic information for a table row, so that when the user wants to add a row to the table, the information needed to create that row is available. All other rows are visible to the user and contain data that the user has entered.
The xforms:repeat that creates this table must also exclude the template row, as shown:
In this case, the nodeset includes all rows that are not in the last position in the table (which would be the template row). This ensures that the template row is never included in the table itself, and is never shown to the user.
To delete a row from this table, you need to create a control (such as a button) that the user can click to trigger an xforms:delete action. You also need to add some other actions to this control to account for special cases. The following button illustrates this:
<xforms:repeat nodeset="order/row [position()!=last()]"
In this button, the first action is the xforms:delete. This delete identifies the nodeset for the row. It uses the last function to ensure that there is more than one row left in the table (if there is more than one row, the last row will have an index greater than one). If there was only one row left, that would mean you were deleting the template row. In this case, the delete will not execute because the last row is not greater than one. The delete then uses the index function to determine which row of the repeat (called orderTable) the cursor is on, then deletes that row.
The next action is an xforms:insert. This action uses the last function to detect whether there is only one row left (in which case the last row is row 1). If there is only one row left, then the table is effectively empty, since the last row is always the invisible template row. In this case, the insert function adds a new, blank row to the table. This prevents the user from deleting all rows in the table, and thereby making the table disappear.
Finally, we use the xforms:setfocus action to reset the focus to the table. This is necessary because when the user clicks the "Delete Row" button, the focus shifts to the button, so we put it back to the table.
<xforms:delete nodeset="order/row [last()>1]"
<xforms:insert nodeset="order/row [last()=1]" at="1"
- When deleting a row, the index for the xforms:repeat does not change. Once the row is deleted, the rows following are all renumbered (their index is reduced by one). This effectively places the focus on the row that followed the deleted row.
- When processing the data model on the back end, make sure that you also exclude the template row. Otherwise, you will include a row of blank data in your results.
- If you are creating tables with template rows, you must ensure that the form's focus never moves to the invisible template row, because to the user this seems as though the focus has disappeared. There are two ways to avoid this. The first is to have the table automatically insert a new row if the only table row is the template row (as shown in the example above). Alternatively, you can use xforms:setindex in combination with xforms:setfocus to deliberately place the focus elsewhere. The following example shows how xforms:setindex uses an if statement to ensure that if the last row is deleted, the current index moves to the second last row or, if a row other than the last row is deleted, the index moves to the last row. xforms:setfocus is then used to move the focus to the row that has the current index.
<xforms:setindex index="index('orderTable')- if(index('orderTable')
= count(order/row),1,0)" repeat="orderTable"></xforms:setindex>