You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by "Joe Rossi (JIRA)" <de...@myfaces.apache.org> on 2007/10/19 20:00:50 UTC

[jira] Created: (TRINIDAD-779) PPR not triggered when deleting last row from table

PPR not triggered when deleting last row from table
---------------------------------------------------

                 Key: TRINIDAD-779
                 URL: https://issues.apache.org/jira/browse/TRINIDAD-779
             Project: MyFaces Trinidad
          Issue Type: Bug
    Affects Versions: 1.2.1-core
         Environment: Trinidad 1.2.1, facelets and JSF 1.2 (Sun RI)
            Reporter: Joe Rossi


I'm hitting a problem with auto-refreshing of tables using Trinidad 1.2.1, facelets and JSF 1.2 (Sun RI). I've condensed the scenario down to a small test case shown below. The summary is:

- I have a page which displays a table containing a collection of objects
- Each row of the table contains two command links - one to edit the row and another to delete the row
- Both links pop-up a dialog with details of the row. Hitting the "save" button on the dialog will either save the edit changes (if invoked from the edit link) or delete the row (if invoked from the delete link).
- The table has a partialTriggers attribute which attempts to refresh the table contents whenever a row is edited or deleted (i.e. partialTriggers contains the ids of the edit and delete links)
- Everything appears to work fine apart from deletion of the last row in the table whereby the table does not automatically refresh.
- Moving the table inside a panelGroupLayout and adding the triggers to that does not work
- Programatically calling addPartialTarget also does not work, (though I may be using this incorrectly?) i.e. The 'Delete' button is on a dialog (i.e. a separate page to the one containing the table). If I add an action listener to the delete button, programatically calling addPartialTarget on the table fails as the table is not on the "current page". 
- Same bug occurs when deleting the last row of a branch of a treetable.

Here's the source code:

widgetList.xhtml (page containing the table):
=============================
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<tr:document id="testForm" title="test form"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:tr="http://myfaces.apache.org/trinidad">
  <tr:panelBorderLayout>
    <tr:form id="widgetListForm">
      <tr:panelGroupLayout layout="vertical">
        <tr:commandButton text="Create New Widget"
          action="dialog:widgetDialog"
          useWindow="true" partialSubmit="true"
          windowHeight="300" windowWidth="400"
          id="createWidgetCommand">
          <tr:setActionListener from="#{widgetListBean.newWidgetBean}"
            to="#{pageFlowScope.widgetBean}" />
          <tr:setActionListener from="#{'create'}"
            to="#{pageFlowScope.widgetBean.operation}" />
        </tr:commandButton>

        <tr:commandButton text="Refresh Page" id="refreshCommand">
        </tr:commandButton>

        <tr:table id="widgetTable" var="widgetBean"
          value="#{widgetListBean.widgetList}" rowBandingInterval="1"
          partialTriggers="refreshCommand createWidgetCommand widgetTable:editWidgetCommand widgetTable:deleteWidgetCommand">
          <tr:column>
            <f:facet name="header">
              <tr:outputText value="Widget Name" />
            </f:facet>
            <tr:outputText value="#{widgetBean.name}" />
          </tr:column>
          <tr:column>
            <f:facet name="header">
              <tr:outputText value="Actions" />
            </f:facet>
            <tr:panelGroupLayout layout="horizontal">
              <tr:commandLink action="dialog:widgetDialog"
                useWindow="true" partialSubmit="true"
                windowHeight="300" windowWidth="400"
                id="editWidgetCommand"
                shortDesc="Edit the widget.">
                <tr:image source="/skins/tn/images/ico_edit.gif" />
                <tr:setActionListener from="#{'edit'}"
                  to="#{widgetBean.operation}" />
                <tr:setActionListener from="#{widgetBean}"
                  to="#{pageFlowScope.widgetBean}" />
              </tr:commandLink>
              <tr:commandLink action="dialog:widgetDialog"
                useWindow="true" partialSubmit="true"
                windowHeight="300" windowWidth="400"
                id="deleteWidgetCommand"
                shortDesc="Delete the widget.">
                <tr:image source="/skins/tn/images/ico_delete.gif" />
                <tr:setActionListener from="#{'delete'}"
                  to="#{widgetBean.operation}" />
                <tr:setActionListener from="#{widgetBean}"
                  to="#{pageFlowScope.widgetBean}" />
              </tr:commandLink>
            </tr:panelGroupLayout>
          </tr:column>
        </tr:table>

      </tr:panelGroupLayout>
    </tr:form>

  </tr:panelBorderLayout>
</tr:document>


widgetDialog.xhtml (the dialog that gets popped up when edit or delete is clicked):
==========================================================
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<tr:document id="testDialog" title="Dialog"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:tr="http://myfaces.apache.org/trinidad">
  <tr:form id="widgetDialogForm">

    <tr:panelFormLayout id="widgetDialogForm" inlineStyle="width:20%">
      <tr:inputText label="Widget Code"
        value="#{pageFlowScope.widgetBean.name}"
        id="nameField" required="true" showRequired="true"
        requiredMessageDetail="Widget name must be entered."
        maximumLength="10"/>

      <f:facet name="footer">
        <tr:panelButtonBar>
          <tr:commandButton id="saveCommand"
            text="#{pageFlowScope.widgetBean.operation}"
            action="#{pageFlowScope.widgetBean.commitAction}" />
          <tr:commandButton id="cancelCommand" text="Cancel"
            action="#{pageFlowScope.widgetBean.cancelAction}"
            immediate="true" />
        </tr:panelButtonBar>
      </f:facet>
    </tr:panelFormLayout>
  </tr:form>
</tr:document>


WidgetList.java (backing bean for the main page - manages the collection of widgets)
==========================================================
public class WidgetList
{


  public WidgetList()
  {
    _createInitialTestValues();
  }
 
  public List<Widget> getWidgetList()
  {
    return _widgetBeans;
  }
 
  public Widget getNewWidgetBean()
  {
    Widget widget = new Widget(this, "");
    widget.setOperation("create");
    return widget;
  }
 
  private void _createInitialTestValues()
  {
    _widgetBeans.add(new Widget(this, "w1"));
    _widgetBeans.add(new Widget(this, "w2"));
    _widgetBeans.add(new Widget(this, "w3"));
  }

  private List<Widget> _widgetBeans = new ArrayList<Widget>();
}


Widget.java (backing bean for the individual rows)
=================================


/**
 * Widget is a test bean
 */
public class Widget
{
  public Widget(WidgetList widgetList, String name)
  {
    _widgetList = widgetList;
    _name = name;
  }
 
  public String getName()
  {
    return _name;
  }
  public void setName(String name)
  {
    _name = name;
  }
  public String getOperation()
  {
    return _operation;
  }
  public void setOperation(String operation)
  {
    assert(operation.equals("edit") || operation.equals("create") || operation.equals("delete"));
    _operation = operation;
  }

  public String commitAction()
  {
    if (_operation.equals("create"))
    {
      _widgetList.getWidgetList().add(this);
    }
    if (_operation.equals("delete"))
    {
      _widgetList.getWidgetList().remove(this);
    }
    if (_operation.equals("edit"))
    {
      // no change to owning collection
    }
    TrinidadFacesUtils.endDialog(_widgetList);

    return null;
  }
 
  public String cancelAction()
  {
    TrinidadFacesUtils.endDialog(this);
   
    return null;
  }
 
  @Override
  public boolean equals(Object obj)
  {
    if (obj instanceof Widget)
    {
      Widget w = (Widget) obj;
      return _name.equals(w._name);
    }
    return false;
  }

  @Override
  public int hashCode()
  {
    return _name.hashCode();
  }

  @Override
  public String toString()
  {
    return _name;
  }

  private String _name;
  private String _operation = "edit";
  private WidgetList _widgetList;
}


-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (TRINIDAD-779) PPR not triggered when deleting last row from table

Posted by "Andrew Robinson (JIRA)" <de...@myfaces.apache.org>.
    [ https://issues.apache.org/jira/browse/TRINIDAD-779?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12701356#action_12701356 ] 

Andrew Robinson commented on TRINIDAD-779:
------------------------------------------

Okay I did some debugging and I found the problem, but I do not know the right solution besides a work-around

The problem is that the return action event is queued on the firing component. In this case, it is the delete link in the table. When the last item is removed from the collection, that stamp is no longer in the table, so when the return action fires, the table is unable to set the current index in the table model to the last row. Therefore, the return event is never broadcast for the delete link and the partial trigger is never invoked.

The work-around solution is to delete the object from the collection during the return event, not in the dialog. 

So per the documentation at:
http://myfaces.apache.org/trinidad/trinidad-1_2/devguide/dialogs.html

setup a returnListener on the commandLink in the table that removes the item from the collection. Using the events return value.

I'll upload the fixed test project

> PPR not triggered when deleting last row from table
> ---------------------------------------------------
>
>                 Key: TRINIDAD-779
>                 URL: https://issues.apache.org/jira/browse/TRINIDAD-779
>             Project: MyFaces Trinidad
>          Issue Type: Bug
>    Affects Versions: 1.2.1-core
>         Environment: Trinidad 1.2.1, facelets and JSF 1.2 (Sun RI)
>            Reporter: Joe Rossi
>         Attachments: testcase.zip
>
>
> I'm hitting a problem with auto-refreshing of tables using Trinidad 1.2.1, facelets and JSF 1.2 (Sun RI). I've condensed the scenario down to a small test case shown below. The summary is:
> - I have a page which displays a table containing a collection of objects
> - Each row of the table contains two command links - one to edit the row and another to delete the row
> - Both links pop-up a dialog with details of the row. Hitting the "save" button on the dialog will either save the edit changes (if invoked from the edit link) or delete the row (if invoked from the delete link).
> - The table has a partialTriggers attribute which attempts to refresh the table contents whenever a row is edited or deleted (i.e. partialTriggers contains the ids of the edit and delete links)
> - Everything appears to work fine apart from deletion of the last row in the table whereby the table does not automatically refresh.
> - Moving the table inside a panelGroupLayout and adding the triggers to that does not work
> - Programatically calling addPartialTarget also does not work, (though I may be using this incorrectly?) i.e. The 'Delete' button is on a dialog (i.e. a separate page to the one containing the table). If I add an action listener to the delete button, programatically calling addPartialTarget on the table fails as the table is not on the "current page". 
> - Same bug occurs when deleting the last row of a branch of a treetable.
> Here's the source code:
> widgetList.xhtml (page containing the table):
> =============================
> <!DOCTYPE html
> PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
> <tr:document id="testForm" title="test form"
>   xmlns:h="http://java.sun.com/jsf/html"
>   xmlns:f="http://java.sun.com/jsf/core"
>   xmlns:ui="http://java.sun.com/jsf/facelets"
>   xmlns:tr="http://myfaces.apache.org/trinidad">
>   <tr:panelBorderLayout>
>     <tr:form id="widgetListForm">
>       <tr:panelGroupLayout layout="vertical">
>         <tr:commandButton text="Create New Widget"
>           action="dialog:widgetDialog"
>           useWindow="true" partialSubmit="true"
>           windowHeight="300" windowWidth="400"
>           id="createWidgetCommand">
>           <tr:setActionListener from="#{widgetListBean.newWidgetBean}"
>             to="#{pageFlowScope.widgetBean}" />
>           <tr:setActionListener from="#{'create'}"
>             to="#{pageFlowScope.widgetBean.operation}" />
>         </tr:commandButton>
>         <tr:commandButton text="Refresh Page" id="refreshCommand">
>         </tr:commandButton>
>         <tr:table id="widgetTable" var="widgetBean"
>           value="#{widgetListBean.widgetList}" rowBandingInterval="1"
>           partialTriggers="refreshCommand createWidgetCommand widgetTable:editWidgetCommand widgetTable:deleteWidgetCommand">
>           <tr:column>
>             <f:facet name="header">
>               <tr:outputText value="Widget Name" />
>             </f:facet>
>             <tr:outputText value="#{widgetBean.name}" />
>           </tr:column>
>           <tr:column>
>             <f:facet name="header">
>               <tr:outputText value="Actions" />
>             </f:facet>
>             <tr:panelGroupLayout layout="horizontal">
>               <tr:commandLink action="dialog:widgetDialog"
>                 useWindow="true" partialSubmit="true"
>                 windowHeight="300" windowWidth="400"
>                 id="editWidgetCommand"
>                 shortDesc="Edit the widget.">
>                 <tr:image source="/skins/tn/images/ico_edit.gif" />
>                 <tr:setActionListener from="#{'edit'}"
>                   to="#{widgetBean.operation}" />
>                 <tr:setActionListener from="#{widgetBean}"
>                   to="#{pageFlowScope.widgetBean}" />
>               </tr:commandLink>
>               <tr:commandLink action="dialog:widgetDialog"
>                 useWindow="true" partialSubmit="true"
>                 windowHeight="300" windowWidth="400"
>                 id="deleteWidgetCommand"
>                 shortDesc="Delete the widget.">
>                 <tr:image source="/skins/tn/images/ico_delete.gif" />
>                 <tr:setActionListener from="#{'delete'}"
>                   to="#{widgetBean.operation}" />
>                 <tr:setActionListener from="#{widgetBean}"
>                   to="#{pageFlowScope.widgetBean}" />
>               </tr:commandLink>
>             </tr:panelGroupLayout>
>           </tr:column>
>         </tr:table>
>       </tr:panelGroupLayout>
>     </tr:form>
>   </tr:panelBorderLayout>
> </tr:document>
> widgetDialog.xhtml (the dialog that gets popped up when edit or delete is clicked):
> ==========================================================
> <!DOCTYPE html
> PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
> <tr:document id="testDialog" title="Dialog"
>   xmlns:h="http://java.sun.com/jsf/html"
>   xmlns:f="http://java.sun.com/jsf/core"
>   xmlns:ui="http://java.sun.com/jsf/facelets"
>   xmlns:tr="http://myfaces.apache.org/trinidad">
>   <tr:form id="widgetDialogForm">
>     <tr:panelFormLayout id="widgetDialogForm" inlineStyle="width:20%">
>       <tr:inputText label="Widget Code"
>         value="#{pageFlowScope.widgetBean.name}"
>         id="nameField" required="true" showRequired="true"
>         requiredMessageDetail="Widget name must be entered."
>         maximumLength="10"/>
>       <f:facet name="footer">
>         <tr:panelButtonBar>
>           <tr:commandButton id="saveCommand"
>             text="#{pageFlowScope.widgetBean.operation}"
>             action="#{pageFlowScope.widgetBean.commitAction}" />
>           <tr:commandButton id="cancelCommand" text="Cancel"
>             action="#{pageFlowScope.widgetBean.cancelAction}"
>             immediate="true" />
>         </tr:panelButtonBar>
>       </f:facet>
>     </tr:panelFormLayout>
>   </tr:form>
> </tr:document>
> WidgetList.java (backing bean for the main page - manages the collection of widgets)
> ==========================================================
> public class WidgetList
> {
>   public WidgetList()
>   {
>     _createInitialTestValues();
>   }
>  
>   public List<Widget> getWidgetList()
>   {
>     return _widgetBeans;
>   }
>  
>   public Widget getNewWidgetBean()
>   {
>     Widget widget = new Widget(this, "");
>     widget.setOperation("create");
>     return widget;
>   }
>  
>   private void _createInitialTestValues()
>   {
>     _widgetBeans.add(new Widget(this, "w1"));
>     _widgetBeans.add(new Widget(this, "w2"));
>     _widgetBeans.add(new Widget(this, "w3"));
>   }
>   private List<Widget> _widgetBeans = new ArrayList<Widget>();
> }
> Widget.java (backing bean for the individual rows)
> =================================
> /**
>  * Widget is a test bean
>  */
> public class Widget
> {
>   public Widget(WidgetList widgetList, String name)
>   {
>     _widgetList = widgetList;
>     _name = name;
>   }
>  
>   public String getName()
>   {
>     return _name;
>   }
>   public void setName(String name)
>   {
>     _name = name;
>   }
>   public String getOperation()
>   {
>     return _operation;
>   }
>   public void setOperation(String operation)
>   {
>     assert(operation.equals("edit") || operation.equals("create") || operation.equals("delete"));
>     _operation = operation;
>   }
>   public String commitAction()
>   {
>     if (_operation.equals("create"))
>     {
>       _widgetList.getWidgetList().add(this);
>     }
>     if (_operation.equals("delete"))
>     {
>       _widgetList.getWidgetList().remove(this);
>     }
>     if (_operation.equals("edit"))
>     {
>       // no change to owning collection
>     }
>     TrinidadFacesUtils.endDialog(_widgetList);
>     return null;
>   }
>  
>   public String cancelAction()
>   {
>     TrinidadFacesUtils.endDialog(this);
>    
>     return null;
>   }
>  
>   @Override
>   public boolean equals(Object obj)
>   {
>     if (obj instanceof Widget)
>     {
>       Widget w = (Widget) obj;
>       return _name.equals(w._name);
>     }
>     return false;
>   }
>   @Override
>   public int hashCode()
>   {
>     return _name.hashCode();
>   }
>   @Override
>   public String toString()
>   {
>     return _name;
>   }
>   private String _name;
>   private String _operation = "edit";
>   private WidgetList _widgetList;
> }

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Resolved: (TRINIDAD-779) PPR not triggered when deleting last row from table

Posted by "Andrew Robinson (JIRA)" <de...@myfaces.apache.org>.
     [ https://issues.apache.org/jira/browse/TRINIDAD-779?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Andrew Robinson resolved TRINIDAD-779.
--------------------------------------

       Resolution: Invalid
    Fix Version/s:  1.2.12-core

The fix is to remove the item during the return event.

> PPR not triggered when deleting last row from table
> ---------------------------------------------------
>
>                 Key: TRINIDAD-779
>                 URL: https://issues.apache.org/jira/browse/TRINIDAD-779
>             Project: MyFaces Trinidad
>          Issue Type: Bug
>    Affects Versions: 1.2.1-core
>         Environment: Trinidad 1.2.1, facelets and JSF 1.2 (Sun RI)
>            Reporter: Joe Rossi
>             Fix For:  1.2.12-core
>
>         Attachments: testcase.zip, testcase.zip
>
>
> I'm hitting a problem with auto-refreshing of tables using Trinidad 1.2.1, facelets and JSF 1.2 (Sun RI). I've condensed the scenario down to a small test case shown below. The summary is:
> - I have a page which displays a table containing a collection of objects
> - Each row of the table contains two command links - one to edit the row and another to delete the row
> - Both links pop-up a dialog with details of the row. Hitting the "save" button on the dialog will either save the edit changes (if invoked from the edit link) or delete the row (if invoked from the delete link).
> - The table has a partialTriggers attribute which attempts to refresh the table contents whenever a row is edited or deleted (i.e. partialTriggers contains the ids of the edit and delete links)
> - Everything appears to work fine apart from deletion of the last row in the table whereby the table does not automatically refresh.
> - Moving the table inside a panelGroupLayout and adding the triggers to that does not work
> - Programatically calling addPartialTarget also does not work, (though I may be using this incorrectly?) i.e. The 'Delete' button is on a dialog (i.e. a separate page to the one containing the table). If I add an action listener to the delete button, programatically calling addPartialTarget on the table fails as the table is not on the "current page". 
> - Same bug occurs when deleting the last row of a branch of a treetable.
> Here's the source code:
> widgetList.xhtml (page containing the table):
> =============================
> <!DOCTYPE html
> PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
> <tr:document id="testForm" title="test form"
>   xmlns:h="http://java.sun.com/jsf/html"
>   xmlns:f="http://java.sun.com/jsf/core"
>   xmlns:ui="http://java.sun.com/jsf/facelets"
>   xmlns:tr="http://myfaces.apache.org/trinidad">
>   <tr:panelBorderLayout>
>     <tr:form id="widgetListForm">
>       <tr:panelGroupLayout layout="vertical">
>         <tr:commandButton text="Create New Widget"
>           action="dialog:widgetDialog"
>           useWindow="true" partialSubmit="true"
>           windowHeight="300" windowWidth="400"
>           id="createWidgetCommand">
>           <tr:setActionListener from="#{widgetListBean.newWidgetBean}"
>             to="#{pageFlowScope.widgetBean}" />
>           <tr:setActionListener from="#{'create'}"
>             to="#{pageFlowScope.widgetBean.operation}" />
>         </tr:commandButton>
>         <tr:commandButton text="Refresh Page" id="refreshCommand">
>         </tr:commandButton>
>         <tr:table id="widgetTable" var="widgetBean"
>           value="#{widgetListBean.widgetList}" rowBandingInterval="1"
>           partialTriggers="refreshCommand createWidgetCommand widgetTable:editWidgetCommand widgetTable:deleteWidgetCommand">
>           <tr:column>
>             <f:facet name="header">
>               <tr:outputText value="Widget Name" />
>             </f:facet>
>             <tr:outputText value="#{widgetBean.name}" />
>           </tr:column>
>           <tr:column>
>             <f:facet name="header">
>               <tr:outputText value="Actions" />
>             </f:facet>
>             <tr:panelGroupLayout layout="horizontal">
>               <tr:commandLink action="dialog:widgetDialog"
>                 useWindow="true" partialSubmit="true"
>                 windowHeight="300" windowWidth="400"
>                 id="editWidgetCommand"
>                 shortDesc="Edit the widget.">
>                 <tr:image source="/skins/tn/images/ico_edit.gif" />
>                 <tr:setActionListener from="#{'edit'}"
>                   to="#{widgetBean.operation}" />
>                 <tr:setActionListener from="#{widgetBean}"
>                   to="#{pageFlowScope.widgetBean}" />
>               </tr:commandLink>
>               <tr:commandLink action="dialog:widgetDialog"
>                 useWindow="true" partialSubmit="true"
>                 windowHeight="300" windowWidth="400"
>                 id="deleteWidgetCommand"
>                 shortDesc="Delete the widget.">
>                 <tr:image source="/skins/tn/images/ico_delete.gif" />
>                 <tr:setActionListener from="#{'delete'}"
>                   to="#{widgetBean.operation}" />
>                 <tr:setActionListener from="#{widgetBean}"
>                   to="#{pageFlowScope.widgetBean}" />
>               </tr:commandLink>
>             </tr:panelGroupLayout>
>           </tr:column>
>         </tr:table>
>       </tr:panelGroupLayout>
>     </tr:form>
>   </tr:panelBorderLayout>
> </tr:document>
> widgetDialog.xhtml (the dialog that gets popped up when edit or delete is clicked):
> ==========================================================
> <!DOCTYPE html
> PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
> <tr:document id="testDialog" title="Dialog"
>   xmlns:h="http://java.sun.com/jsf/html"
>   xmlns:f="http://java.sun.com/jsf/core"
>   xmlns:ui="http://java.sun.com/jsf/facelets"
>   xmlns:tr="http://myfaces.apache.org/trinidad">
>   <tr:form id="widgetDialogForm">
>     <tr:panelFormLayout id="widgetDialogForm" inlineStyle="width:20%">
>       <tr:inputText label="Widget Code"
>         value="#{pageFlowScope.widgetBean.name}"
>         id="nameField" required="true" showRequired="true"
>         requiredMessageDetail="Widget name must be entered."
>         maximumLength="10"/>
>       <f:facet name="footer">
>         <tr:panelButtonBar>
>           <tr:commandButton id="saveCommand"
>             text="#{pageFlowScope.widgetBean.operation}"
>             action="#{pageFlowScope.widgetBean.commitAction}" />
>           <tr:commandButton id="cancelCommand" text="Cancel"
>             action="#{pageFlowScope.widgetBean.cancelAction}"
>             immediate="true" />
>         </tr:panelButtonBar>
>       </f:facet>
>     </tr:panelFormLayout>
>   </tr:form>
> </tr:document>
> WidgetList.java (backing bean for the main page - manages the collection of widgets)
> ==========================================================
> public class WidgetList
> {
>   public WidgetList()
>   {
>     _createInitialTestValues();
>   }
>  
>   public List<Widget> getWidgetList()
>   {
>     return _widgetBeans;
>   }
>  
>   public Widget getNewWidgetBean()
>   {
>     Widget widget = new Widget(this, "");
>     widget.setOperation("create");
>     return widget;
>   }
>  
>   private void _createInitialTestValues()
>   {
>     _widgetBeans.add(new Widget(this, "w1"));
>     _widgetBeans.add(new Widget(this, "w2"));
>     _widgetBeans.add(new Widget(this, "w3"));
>   }
>   private List<Widget> _widgetBeans = new ArrayList<Widget>();
> }
> Widget.java (backing bean for the individual rows)
> =================================
> /**
>  * Widget is a test bean
>  */
> public class Widget
> {
>   public Widget(WidgetList widgetList, String name)
>   {
>     _widgetList = widgetList;
>     _name = name;
>   }
>  
>   public String getName()
>   {
>     return _name;
>   }
>   public void setName(String name)
>   {
>     _name = name;
>   }
>   public String getOperation()
>   {
>     return _operation;
>   }
>   public void setOperation(String operation)
>   {
>     assert(operation.equals("edit") || operation.equals("create") || operation.equals("delete"));
>     _operation = operation;
>   }
>   public String commitAction()
>   {
>     if (_operation.equals("create"))
>     {
>       _widgetList.getWidgetList().add(this);
>     }
>     if (_operation.equals("delete"))
>     {
>       _widgetList.getWidgetList().remove(this);
>     }
>     if (_operation.equals("edit"))
>     {
>       // no change to owning collection
>     }
>     TrinidadFacesUtils.endDialog(_widgetList);
>     return null;
>   }
>  
>   public String cancelAction()
>   {
>     TrinidadFacesUtils.endDialog(this);
>    
>     return null;
>   }
>  
>   @Override
>   public boolean equals(Object obj)
>   {
>     if (obj instanceof Widget)
>     {
>       Widget w = (Widget) obj;
>       return _name.equals(w._name);
>     }
>     return false;
>   }
>   @Override
>   public int hashCode()
>   {
>     return _name.hashCode();
>   }
>   @Override
>   public String toString()
>   {
>     return _name;
>   }
>   private String _name;
>   private String _operation = "edit";
>   private WidgetList _widgetList;
> }

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (TRINIDAD-779) PPR not triggered when deleting last row from table

Posted by "Paul Freeman (JIRA)" <de...@myfaces.apache.org>.
    [ https://issues.apache.org/jira/browse/TRINIDAD-779?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12701264#action_12701264 ] 

Paul Freeman commented on TRINIDAD-779:
---------------------------------------

Added a simple maven-based test case. To reproduce:

- unzip testcase.zip
- cd testcase
- mvn jetty:run
- go to: http://localhost:8080/widgetList.jsf
- click Delete link on any row but the last one and then click on the 'delete' button on the dialog. Row disappears from the table as expected
- click Delete link on the last row and then click on the 'delete' button on the dialog. When the dialog returns the table is not refreshed. as expected. (Clicking the 'Refresh Page' button will force a refresh of the table, showing that the last row was in fact deleted.)

> PPR not triggered when deleting last row from table
> ---------------------------------------------------
>
>                 Key: TRINIDAD-779
>                 URL: https://issues.apache.org/jira/browse/TRINIDAD-779
>             Project: MyFaces Trinidad
>          Issue Type: Bug
>    Affects Versions: 1.2.1-core
>         Environment: Trinidad 1.2.1, facelets and JSF 1.2 (Sun RI)
>            Reporter: Joe Rossi
>         Attachments: testcase.zip
>
>
> I'm hitting a problem with auto-refreshing of tables using Trinidad 1.2.1, facelets and JSF 1.2 (Sun RI). I've condensed the scenario down to a small test case shown below. The summary is:
> - I have a page which displays a table containing a collection of objects
> - Each row of the table contains two command links - one to edit the row and another to delete the row
> - Both links pop-up a dialog with details of the row. Hitting the "save" button on the dialog will either save the edit changes (if invoked from the edit link) or delete the row (if invoked from the delete link).
> - The table has a partialTriggers attribute which attempts to refresh the table contents whenever a row is edited or deleted (i.e. partialTriggers contains the ids of the edit and delete links)
> - Everything appears to work fine apart from deletion of the last row in the table whereby the table does not automatically refresh.
> - Moving the table inside a panelGroupLayout and adding the triggers to that does not work
> - Programatically calling addPartialTarget also does not work, (though I may be using this incorrectly?) i.e. The 'Delete' button is on a dialog (i.e. a separate page to the one containing the table). If I add an action listener to the delete button, programatically calling addPartialTarget on the table fails as the table is not on the "current page". 
> - Same bug occurs when deleting the last row of a branch of a treetable.
> Here's the source code:
> widgetList.xhtml (page containing the table):
> =============================
> <!DOCTYPE html
> PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
> <tr:document id="testForm" title="test form"
>   xmlns:h="http://java.sun.com/jsf/html"
>   xmlns:f="http://java.sun.com/jsf/core"
>   xmlns:ui="http://java.sun.com/jsf/facelets"
>   xmlns:tr="http://myfaces.apache.org/trinidad">
>   <tr:panelBorderLayout>
>     <tr:form id="widgetListForm">
>       <tr:panelGroupLayout layout="vertical">
>         <tr:commandButton text="Create New Widget"
>           action="dialog:widgetDialog"
>           useWindow="true" partialSubmit="true"
>           windowHeight="300" windowWidth="400"
>           id="createWidgetCommand">
>           <tr:setActionListener from="#{widgetListBean.newWidgetBean}"
>             to="#{pageFlowScope.widgetBean}" />
>           <tr:setActionListener from="#{'create'}"
>             to="#{pageFlowScope.widgetBean.operation}" />
>         </tr:commandButton>
>         <tr:commandButton text="Refresh Page" id="refreshCommand">
>         </tr:commandButton>
>         <tr:table id="widgetTable" var="widgetBean"
>           value="#{widgetListBean.widgetList}" rowBandingInterval="1"
>           partialTriggers="refreshCommand createWidgetCommand widgetTable:editWidgetCommand widgetTable:deleteWidgetCommand">
>           <tr:column>
>             <f:facet name="header">
>               <tr:outputText value="Widget Name" />
>             </f:facet>
>             <tr:outputText value="#{widgetBean.name}" />
>           </tr:column>
>           <tr:column>
>             <f:facet name="header">
>               <tr:outputText value="Actions" />
>             </f:facet>
>             <tr:panelGroupLayout layout="horizontal">
>               <tr:commandLink action="dialog:widgetDialog"
>                 useWindow="true" partialSubmit="true"
>                 windowHeight="300" windowWidth="400"
>                 id="editWidgetCommand"
>                 shortDesc="Edit the widget.">
>                 <tr:image source="/skins/tn/images/ico_edit.gif" />
>                 <tr:setActionListener from="#{'edit'}"
>                   to="#{widgetBean.operation}" />
>                 <tr:setActionListener from="#{widgetBean}"
>                   to="#{pageFlowScope.widgetBean}" />
>               </tr:commandLink>
>               <tr:commandLink action="dialog:widgetDialog"
>                 useWindow="true" partialSubmit="true"
>                 windowHeight="300" windowWidth="400"
>                 id="deleteWidgetCommand"
>                 shortDesc="Delete the widget.">
>                 <tr:image source="/skins/tn/images/ico_delete.gif" />
>                 <tr:setActionListener from="#{'delete'}"
>                   to="#{widgetBean.operation}" />
>                 <tr:setActionListener from="#{widgetBean}"
>                   to="#{pageFlowScope.widgetBean}" />
>               </tr:commandLink>
>             </tr:panelGroupLayout>
>           </tr:column>
>         </tr:table>
>       </tr:panelGroupLayout>
>     </tr:form>
>   </tr:panelBorderLayout>
> </tr:document>
> widgetDialog.xhtml (the dialog that gets popped up when edit or delete is clicked):
> ==========================================================
> <!DOCTYPE html
> PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
> <tr:document id="testDialog" title="Dialog"
>   xmlns:h="http://java.sun.com/jsf/html"
>   xmlns:f="http://java.sun.com/jsf/core"
>   xmlns:ui="http://java.sun.com/jsf/facelets"
>   xmlns:tr="http://myfaces.apache.org/trinidad">
>   <tr:form id="widgetDialogForm">
>     <tr:panelFormLayout id="widgetDialogForm" inlineStyle="width:20%">
>       <tr:inputText label="Widget Code"
>         value="#{pageFlowScope.widgetBean.name}"
>         id="nameField" required="true" showRequired="true"
>         requiredMessageDetail="Widget name must be entered."
>         maximumLength="10"/>
>       <f:facet name="footer">
>         <tr:panelButtonBar>
>           <tr:commandButton id="saveCommand"
>             text="#{pageFlowScope.widgetBean.operation}"
>             action="#{pageFlowScope.widgetBean.commitAction}" />
>           <tr:commandButton id="cancelCommand" text="Cancel"
>             action="#{pageFlowScope.widgetBean.cancelAction}"
>             immediate="true" />
>         </tr:panelButtonBar>
>       </f:facet>
>     </tr:panelFormLayout>
>   </tr:form>
> </tr:document>
> WidgetList.java (backing bean for the main page - manages the collection of widgets)
> ==========================================================
> public class WidgetList
> {
>   public WidgetList()
>   {
>     _createInitialTestValues();
>   }
>  
>   public List<Widget> getWidgetList()
>   {
>     return _widgetBeans;
>   }
>  
>   public Widget getNewWidgetBean()
>   {
>     Widget widget = new Widget(this, "");
>     widget.setOperation("create");
>     return widget;
>   }
>  
>   private void _createInitialTestValues()
>   {
>     _widgetBeans.add(new Widget(this, "w1"));
>     _widgetBeans.add(new Widget(this, "w2"));
>     _widgetBeans.add(new Widget(this, "w3"));
>   }
>   private List<Widget> _widgetBeans = new ArrayList<Widget>();
> }
> Widget.java (backing bean for the individual rows)
> =================================
> /**
>  * Widget is a test bean
>  */
> public class Widget
> {
>   public Widget(WidgetList widgetList, String name)
>   {
>     _widgetList = widgetList;
>     _name = name;
>   }
>  
>   public String getName()
>   {
>     return _name;
>   }
>   public void setName(String name)
>   {
>     _name = name;
>   }
>   public String getOperation()
>   {
>     return _operation;
>   }
>   public void setOperation(String operation)
>   {
>     assert(operation.equals("edit") || operation.equals("create") || operation.equals("delete"));
>     _operation = operation;
>   }
>   public String commitAction()
>   {
>     if (_operation.equals("create"))
>     {
>       _widgetList.getWidgetList().add(this);
>     }
>     if (_operation.equals("delete"))
>     {
>       _widgetList.getWidgetList().remove(this);
>     }
>     if (_operation.equals("edit"))
>     {
>       // no change to owning collection
>     }
>     TrinidadFacesUtils.endDialog(_widgetList);
>     return null;
>   }
>  
>   public String cancelAction()
>   {
>     TrinidadFacesUtils.endDialog(this);
>    
>     return null;
>   }
>  
>   @Override
>   public boolean equals(Object obj)
>   {
>     if (obj instanceof Widget)
>     {
>       Widget w = (Widget) obj;
>       return _name.equals(w._name);
>     }
>     return false;
>   }
>   @Override
>   public int hashCode()
>   {
>     return _name.hashCode();
>   }
>   @Override
>   public String toString()
>   {
>     return _name;
>   }
>   private String _name;
>   private String _operation = "edit";
>   private WidgetList _widgetList;
> }

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.