Hi Tony,

Assume you have a page with 3 tabs (and one collection per tab): A, B, and C. Since the user could make a few changes in one tab then switch to another and do more, Tapestry has to collect the changes from all of the tabs. This collection happens during the rewind.

For sake of argument, assume each tab has 10 elements. Let's say the user deletes the first 2 items in tabs A and B (elements 1, 2, 11, and 12.) Roughly speaking, as the user clicks delete on each element, Tapestry adds another set of parameters to the URL to be sent.

After submit, tapestry needs to match up the values in the query parameters (1, 2, 11, and 12) with the corresponding collection elements. That's where rewinding comes in -- Tapestry walks through the page as if it were drawing the whole thing again, without actually generating HTML, and matches up the query parameters to the resulting HTML fields (and the objects that correspond with them.) For a tabbed list, Tapestry will draw each tab in turn, which is why you're always getting the last tab.

OK, so how do you fix this? The best way I can think of is at the page level: use a ListEditMap, which you'll populate with _all_ of your collections up front (collection A + collection B + collection C.) Then, in your form handler, walk through the ListEditMap (which will have one "delete" flag per item, for example) and do the actual deletions.

Here's a rough example (CAUTION: Not syntax checked)

public abstract class CollectionEditPage extends BasePage implements PageRenderListener {

  public abstract ListEditMap getMap();
  public abstract void setMap(ListEditMap map);

public abstract List getCollections(); // I'm going to assume each collection can be iterated like a list

  // Builds the master list
  public void pageBeginRender(PageEvent event) {
        super.pageBeginRender(event);
        ListEditMap map = new ListEditMap();
        List collections = getCollections();
        int counter = 0;
        for (Iterator iter = collections.iterator(); iter.hasNext();) {
            Collection collection = (Collection) iter.next();
for (Iterator itemIter = collection.iterator(); itemIter.hasNext();) { ItemWrapper wrapper = new ItemWrapper(collection, itemIter.next()); map.add(new Integer(counter++), wrapper); // key by a sequential count
        }
        setMap(map);
    }

    public void synchronize(IRequestCycle cycle) {
        ItemWrapper info = (ItemWrapper) getMap().getValue();
setWorkingModule(info); // You should handle the case where info == null; often by throwing an exception
    }

    public void doFormSubmission(IRequestCycle cycle) {
for (Iterator iter = map.getAllValues().iterator(); iter.hasNext();) {
            ItemWrapper wrapper = (ItemWrapper) iter.next();
            if (wrapper.isToBeDeleted())
                wrapper.getCollection().remove(wrapper.getItem());
        }
    }
}

public class ItemWrapper {
  private Collection collection;
  private Object item;
  private boolean toBeDeleted;

  public ItemWrapper(Collection c, Object i) {
    collection = c;
    item = i;
    toBeDeleted = false;
  }

  public Collection getCollection() { return collection; }
  public Object getItem() { return item; }
  public boolean isToBeDeleted() { return toBeDeleted; }
  public void setToBeDeleted(boolean delete) { toBeDeleted = delete; }
}



Hope this helps :)

 ...Richard



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to