ICEfaces
  1. ICEfaces
  2. ICE-7702

Use of the f:ajax tag in h:selectMany[Checkbox, Listbox] within 2+ naming containers throws an exception

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Invalid
    • Affects Version/s: 3.0
    • Fix Version/s: 3.1
    • Component/s: Framework, ICE-Components
    • Labels:
      None
    • Environment:
      ICEfaces 3 ACE portal portlet Mojarra
    • Assignee Priority:
      P2
    • Affects:
      Documentation (User Guide, Ref. Guide, etc.), Compatibility/Configuration
    • Workaround Exists:
      Yes
    • Workaround Description:
      Hide
      Do not use f:ajax tag with Mojarra, or use MyFaces

      Instead of using f:ajax, manually add an onclick handler and make it call the submit function yourself

      After this jira's commits, use the ace:ajax tag instead of f:ajax
      Show
      Do not use f:ajax tag with Mojarra, or use MyFaces Instead of using f:ajax, manually add an onclick handler and make it call the submit function yourself After this jira's commits, use the ace:ajax tag instead of f:ajax

      Description

      When trying to add the plain ace:tabset example as a portlet to a portal page, the following exception is thrown:

      javax.faces.FacesException: <f:ajax> contains an unknown id 'A4076:j_idt449:_t451' - cannot locate it in the context of the component _t451
      at com.sun.faces.renderkit.html_basic.AjaxBehaviorRenderer.getResolvedId(AjaxBehaviorRenderer.java:285)
      at com.sun.faces.renderkit.html_basic.AjaxBehaviorRenderer.appendIds(AjaxBehaviorRenderer.java:272)
      at com.sun.faces.renderkit.html_basic.AjaxBehaviorRenderer.buildAjaxCommand(AjaxBehaviorRenderer.java:212)
      at com.sun.faces.renderkit.html_basic.AjaxBehaviorRenderer.getScript(AjaxBehaviorRenderer.java:86)
      at javax.faces.component.behavior.ClientBehaviorBase.getScript(ClientBehaviorBase.java:103)
      at com.sun.faces.renderkit.RenderKitUtils.getSingleBehaviorHandler(RenderKitUtils.java:1610)
      at com.sun.faces.renderkit.RenderKitUtils.renderHandler(RenderKitUtils.java:1703)
      at com.sun.faces.renderkit.RenderKitUtils.renderSelectOnclick(RenderKitUtils.java:421)
      at com.sun.faces.renderkit.html_basic.SelectManyCheckboxListRenderer.renderOption(SelectManyCheckboxListRenderer.java:361)
      at com.sun.faces.renderkit.html_basic.SelectManyCheckboxListRenderer.encodeEnd(SelectManyCheckboxListRenderer.java:180)
      at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
      at org.icefaces.ace.util.Utils.renderChild(Utils.java:61)
      at org.icefaces.ace.util.Utils.renderChildren(Utils.java:43)
      at org.icefaces.ace.util.Utils.renderChild(Utils.java:59)
      at org.icefaces.ace.component.tabset.TabSetRenderer.renderTabBody(TabSetRenderer.java:431)
      at org.icefaces.ace.component.tabset.TabSetRenderer.doTab(TabSetRenderer.java:512)
      at org.icefaces.ace.component.tabset.TabSetRenderer.doTabs(TabSetRenderer.java:452)
      at org.icefaces.ace.component.tabset.TabSetRenderer.recursivelyRenderSafe(TabSetRenderer.java:323)
      at org.icefaces.ace.component.tabset.TabSetRenderer.encodeEnd(TabSetRenderer.java:261)
      at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
      at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1764)
      at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
      at org.icefaces.impl.renderkit.RendererWrapper.encodeChildren(RendererWrapper.java:49)
      at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
      at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:304)
      at com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:105)
      at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
      at org.icefaces.ace.renderkit.CoreRenderer.renderChild(CoreRenderer.java:72)
      at org.icefaces.ace.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:60)
      at org.icefaces.ace.component.panel.PanelRenderer.encodeContent(PanelRenderer.java:208)
      at org.icefaces.ace.component.panel.PanelRenderer.encodeMarkup(PanelRenderer.java:131)
      at org.icefaces.ace.component.panel.PanelRenderer.encodeEnd(PanelRenderer.java:71)
      at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
      at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1764)
      at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1760)
      at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1760)
      at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:401)
      at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
      at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
      at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
      at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
      at org.portletfaces.bridge.BridgeImpl.doFacesRequest(BridgeImpl.java:433)


      Remove the f:ajax tag from the following markup allows the tabset to work normally so the issue is not the tabset component itself but the use of the f:ajax tag in the body of the tab pane:

                  <ace:tabSet id="sampleTabSet" clientSide="false">
                      <ace:tabPane label="To Do List">
                          <h:selectManyCheckbox layout="pageDirection" selectedClass="selectedCheckBox">
                                      <f:selectItems value="#{tabSet.toDoList}"
                                                          var="listItem"
                                                          itemValue="#{listItem.value}"
                                                          itemLabel="#{listItem.key}"/>
       //Remove -> <f:ajax execute="@this" render="sampleTabSet"/>
                          </h:selectManyCheckbox>
                      </ace:tabPane>

        Issue Links

          Activity

          Deryk Sinotte created issue -
          Deryk Sinotte made changes -
          Field Original Value New Value
          Salesforce Case []
          Assignee Priority P1
          Assignee Deryk Sinotte [ deryk.sinotte ]
          Hide
          Deryk Sinotte added a comment -

          In the ace:accordionPanel example, we use a different technique - adding an onchange handler instead - and this doesn't have a problem:

          <ace:accordion collapsible="true">
          <ace:accordionPane title="My To Do List">
          <h:selectManyCheckbox layout="pageDirection" selectedClass="selectedCheckBox" onchange="submit();">
          <f:selectItems value="#

          {accordionPanelBean.toDoList}

          "
          var="listItem"
          itemValue="#

          {listItem.value}

          "
          itemLabel="#

          {listItem.key}

          "/>
          </h:selectManyCheckbox>
          </ace:accordionPane>

          Using the same technique (and removing the f:ajax tag) in ace:tabSet also works.

          Show
          Deryk Sinotte added a comment - In the ace:accordionPanel example, we use a different technique - adding an onchange handler instead - and this doesn't have a problem: <ace:accordion collapsible="true"> <ace:accordionPane title="My To Do List"> <h:selectManyCheckbox layout="pageDirection" selectedClass="selectedCheckBox" onchange="submit();"> <f:selectItems value="# {accordionPanelBean.toDoList} " var="listItem" itemValue="# {listItem.value} " itemLabel="# {listItem.key} "/> </h:selectManyCheckbox> </ace:accordionPane> Using the same technique (and removing the f:ajax tag) in ace:tabSet also works.
          Hide
          Deryk Sinotte added a comment -

          To narrow it down further, this is only a problem with Mojarra. With MyFaces, the use of f:ajax works fine. I've updated the environment information and the workaround to reflect this.

          At this point, I can only speculate that there is a difference in the findComponent algorithm that accounts for this difference.

          Show
          Deryk Sinotte added a comment - To narrow it down further, this is only a problem with Mojarra. With MyFaces, the use of f:ajax works fine. I've updated the environment information and the workaround to reflect this. At this point, I can only speculate that there is a difference in the findComponent algorithm that accounts for this difference.
          Deryk Sinotte made changes -
          Workaround Description Do not use f:ajax tag Do not use f:ajax tag with Mojarra or use MyFaces
          Environment ICEfaces 3 ACE portal portlet ICEfaces 3 ACE portal portlet Mojarra
          Salesforce Case []
          Affects [Documentation (User Guide, Ref. Guide, etc.), Compatibility/Configuration]
          Ken Fyten made changes -
          Salesforce Case []
          Fix Version/s EE-3.0.0.GA [ 10262 ]
          Fix Version/s 3.0 [ 10241 ]
          Assignee Priority P1 P2
          Repository Revision Date User Message
          ICEsoft Public SVN Repository #27503 Mon Jan 30 12:33:37 MST 2012 deryk.sinotte ICE-7702: temporarily remove f:ajax usage to work with portlets
          Files Changed
          Commit graph MODIFY /icefaces3/trunk/icefaces/samples/showcase/showcase/src/main/webapp/resources/examples/ace/tab/tabset.xhtml
          Ken Fyten made changes -
          Salesforce Case []
          Fix Version/s 3.0 [ 10241 ]
          Fix Version/s EE-3.0.0.GA [ 10262 ]
          Assignee Priority P2 P1
          Repository Revision Date User Message
          ICEsoft Public SVN Repository #27521 Mon Jan 30 15:35:35 MST 2012 ken.fyten ICE-7702: temporarily remove f:ajax usage to work with portlets
          Files Changed
          Commit graph MODIFY /icefaces3/tags/icefaces-3.0.0/icefaces/samples/showcase/showcase/src/main/webapp/resources/examples/ace/tab/tabset.xhtml
          Repository Revision Date User Message
          ICEsoft Public SVN Repository #27534 Mon Jan 30 17:22:46 MST 2012 deryk.sinotte ICE-7702: remove use of f:ajax for now
          Files Changed
          Commit graph MODIFY /icefaces3/trunk/icefaces/samples/showcase/showcase/src/main/webapp/resources/examples/ace/tab/tabset.xhtml
          Repository Revision Date User Message
          ICEsoft Public SVN Repository #27535 Mon Jan 30 17:26:15 MST 2012 ken.fyten ICE-7702: remove use of f:ajax for now
          Files Changed
          Commit graph MODIFY /icefaces3/tags/icefaces-3.0.0/icefaces/samples/showcase/showcase/src/main/webapp/resources/examples/ace/tab/tabset.xhtml
          Hide
          Deryk Sinotte added a comment -

          I've removed the f:ajax from the tabset.xhtml file and added the onchange="submit();" mechanism that we using in the accordion panel for the time being so that specific showcase demo works when running under Mojarra on Liferay.

          Show
          Deryk Sinotte added a comment - I've removed the f:ajax from the tabset.xhtml file and added the onchange="submit();" mechanism that we using in the accordion panel for the time being so that specific showcase demo works when running under Mojarra on Liferay.
          Deryk Sinotte made changes -
          Salesforce Case []
          Assignee Deryk Sinotte [ deryk.sinotte ] Ken Fyten [ ken.fyten ]
          Ken Fyten made changes -
          Salesforce Case []
          Fix Version/s 3.0.1 [ 10282 ]
          Fix Version/s 3.0 [ 10241 ]
          Assignee Priority P1 P2
          Assignee Ken Fyten [ ken.fyten ] Mark Collette [ mark.collette ]
          Hide
          Ted Goddard added a comment -

          It's possible that MyFaces is sending "@this" to the client to be resolved at submit time while mojarra is attempting to resolve "@this" server-side. It should be possible to determine if these are the strategies by looking at the network traffic.

          Show
          Ted Goddard added a comment - It's possible that MyFaces is sending "@this" to the client to be resolved at submit time while mojarra is attempting to resolve "@this" server-side. It should be possible to determine if these are the strategies by looking at the network traffic.
          Hide
          Mark Collette added a comment -

          From the code at the top of the stack, and the exception message, the problem is that some code has already converted @this to a clientId, and the clientId doesn't start with a colon, so it's being used as a relative findComponent String from the selectManyCheckbox, and so is failing the search.

          Show
          Mark Collette added a comment - From the code at the top of the stack, and the exception message, the problem is that some code has already converted @this to a clientId, and the clientId doesn't start with a colon, so it's being used as a relative findComponent String from the selectManyCheckbox, and so is failing the search.
          Hide
          Mark Collette added a comment -

          From Mojarra's AjaxBehaviorRenderer:

          StringBuilder ajaxCommand = new StringBuilder(256);
          Collection<String> execute = ajaxBehavior.getExecute();
          Collection<String> render = ajaxBehavior.getRender();
          String onevent = ajaxBehavior.getOnevent();
          String onerror = ajaxBehavior.getOnerror();
          String sourceId = behaviorContext.getSourceId();
          Collection<ClientBehaviorContext.Parameter> params = behaviorContext.getParameters();

          // Needed workaround for SelectManyCheckbox - if execute doesn't have sourceId,
          // we need to add it - otherwise, we use the default, which is sourceId:child, which
          // won't work.
          ClientBehaviorContext.Parameter foundparam = null;
          for (ClientBehaviorContext.Parameter param : params) {
          if (param.getName().equals("incExec") && (Boolean)param.getValue())

          { foundparam = param; }

          }
          if (foundparam != null && !execute.contains(sourceId))

          { execute = new LinkedList<String>(execute); execute.add(component.getClientId()); <<< This is what breaks it }
          Show
          Mark Collette added a comment - From Mojarra's AjaxBehaviorRenderer: StringBuilder ajaxCommand = new StringBuilder(256); Collection<String> execute = ajaxBehavior.getExecute(); Collection<String> render = ajaxBehavior.getRender(); String onevent = ajaxBehavior.getOnevent(); String onerror = ajaxBehavior.getOnerror(); String sourceId = behaviorContext.getSourceId(); Collection<ClientBehaviorContext.Parameter> params = behaviorContext.getParameters(); // Needed workaround for SelectManyCheckbox - if execute doesn't have sourceId, // we need to add it - otherwise, we use the default, which is sourceId:child, which // won't work. ClientBehaviorContext.Parameter foundparam = null; for (ClientBehaviorContext.Parameter param : params) { if (param.getName().equals("incExec") && (Boolean)param.getValue()) { foundparam = param; } } if (foundparam != null && !execute.contains(sourceId)) { execute = new LinkedList<String>(execute); execute.add(component.getClientId()); <<< This is what breaks it }
          Hide
          Mark Collette added a comment -

          com.sun.faces.renderkit.html_basic.SelectManyCheckboxListRenderer.renderOption(
          FacesContext context,
          UIComponent component,
          Converter converter,
          SelectItem curItem,
          Object currentSelections,
          Object[] submittedValues,
          boolean alignVertical,
          int itemNumber,
          OptionComponentInfo optionInfo)
          at line 361 calls: RenderKitUtils.renderSelectOnclick(context, component, true); which adds the specific param that AjaxBehaviorRenderer is looking for.

          So it looks like it comes down to if sourceId is specified, and is in the execute list. At this point, execute should consist of "@this".

          Show
          Mark Collette added a comment - com.sun.faces.renderkit.html_basic.SelectManyCheckboxListRenderer.renderOption( FacesContext context, UIComponent component, Converter converter, SelectItem curItem, Object currentSelections, Object[] submittedValues, boolean alignVertical, int itemNumber, OptionComponentInfo optionInfo) at line 361 calls: RenderKitUtils.renderSelectOnclick(context, component, true); which adds the specific param that AjaxBehaviorRenderer is looking for. So it looks like it comes down to if sourceId is specified, and is in the execute list. At this point, execute should consist of "@this".
          Ken Fyten made changes -
          Salesforce Case []
          Assignee Priority P2 P1
          Hide
          Mark Collette added a comment -

          The Mojarra jira for the issue:

          http://java.net/jira/browse/JAVASERVERFACES-1579

          Show
          Mark Collette added a comment - The Mojarra jira for the issue: http://java.net/jira/browse/JAVASERVERFACES-1579
          Repository Revision Date User Message
          ICEsoft Public SVN Repository #28310 Tue Mar 13 23:06:52 MDT 2012 mark.collette ICE-7702 : Use of the f:ajax tag in h:selectMany[Checkbox, Listbox] within 2+ naming containers throws an exception
          Files Changed
          Commit graph MODIFY /icefaces3/trunk/icefaces/ace/component/src/org/icefaces/ace/component/ajax/AjaxBehaviorRenderer.java
          Hide
          Mark Collette added a comment -

          Only h:selectManyCheckbox and h:selectManyListbox exhibit this problem, where if they are within 2+ levels of naming containers, and have an f:ajax tag, and are using Mojarra, that it will throw an excdption. It doesn't require portlets, but portlets will always fail since the portlet UIViewRoot is a naming container, and the selectMany* component need to be in a form, so you're already two levels deep. But you could just as well have a form and a dataTable or f:subview.

          It doesn't matter what you specify to execute, because the mojarra code will add a bogus entry to the execute list.

          Show
          Mark Collette added a comment - Only h:selectManyCheckbox and h:selectManyListbox exhibit this problem, where if they are within 2+ levels of naming containers, and have an f:ajax tag, and are using Mojarra, that it will throw an excdption. It doesn't require portlets, but portlets will always fail since the portlet UIViewRoot is a naming container, and the selectMany* component need to be in a form, so you're already two levels deep. But you could just as well have a form and a dataTable or f:subview. It doesn't matter what you specify to execute, because the mojarra code will add a bogus entry to the execute list.
          Mark Collette made changes -
          Summary Use of the f:ajax tag in the ace:tabset example throws an exception in portlet Use of the f:ajax tag in h:selectMany[Checkbox, Listbox] within 2+ naming containers throws an exception
          Workaround Description Do not use f:ajax tag with Mojarra or use MyFaces Do not use f:ajax tag with Mojarra, or use MyFaces

          Instead of using f:ajax, manually add an onclick handler and make it call the submit function yourself

          After this jira's commits, use the ace:ajax tag instead of f:ajax
          Salesforce Case []
          Hide
          Mark Collette added a comment -

          Modified the ace:ajax rendering code to handle differences between ACE components, and regular h: components, so that it can also be used with h: components. So far only verified with the h:selectManyCheckbox from the test scenario.

          This code varies noticeably between trunk and branch, so branch will require separate implementation and verification.

          <f:subview id="testSub">
          <h:form id="form">
          <ace:tabSet id="sampleTabSet" clientSide="false">
          <ace:tabPane id="toDoList" label="To Do List">
          <h:selectManyCheckbox id="list" layout="pageDirection" selectedClass="selectedCheckBox">
          <f:selectItems value="#

          {tabSet.toDoList}

          "
          var="listItem"
          itemValue="#

          {listItem.value}

          "
          itemLabel="#

          {listItem.key}

          "/>
          <ace:ajax execute="@this" render="sampleTabSet"/>
          </h:selectManyCheckbox>

          trunk
          Subversion 28310

          Show
          Mark Collette added a comment - Modified the ace:ajax rendering code to handle differences between ACE components, and regular h: components, so that it can also be used with h: components. So far only verified with the h:selectManyCheckbox from the test scenario. This code varies noticeably between trunk and branch, so branch will require separate implementation and verification. <f:subview id="testSub"> <h:form id="form"> <ace:tabSet id="sampleTabSet" clientSide="false"> <ace:tabPane id="toDoList" label="To Do List"> <h:selectManyCheckbox id="list" layout="pageDirection" selectedClass="selectedCheckBox"> <f:selectItems value="# {tabSet.toDoList} " var="listItem" itemValue="# {listItem.value} " itemLabel="# {listItem.key} "/> <ace:ajax execute="@this" render="sampleTabSet"/> </h:selectManyCheckbox> trunk Subversion 28310
          Ken Fyten made changes -
          Summary Use of the f:ajax tag in h:selectMany[Checkbox, Listbox] within 2+ naming containers throws an exception Use of the f:ajax tag in h:selectMany[Checkbox, Listbox] within 2+ naming containers throws an exception
          Salesforce Case []
          Fix Version/s 3.1 [ 10312 ]
          Fix Version/s 3.0.1 [ 10282 ]
          Assignee Priority P1 P2
          Hide
          Mark Collette added a comment -

          Since there's no real fix for this issue, aside from Mojarra fixing it, or using work-arounds, then we'll link to ICE-7909, which is a jira for making ace:ajax work with h: components, so that it can be used instead of f:ajax.

          Show
          Mark Collette added a comment - Since there's no real fix for this issue, aside from Mojarra fixing it, or using work-arounds, then we'll link to ICE-7909 , which is a jira for making ace:ajax work with h: components, so that it can be used instead of f:ajax.
          Mark Collette made changes -
          Link This issue depends on ICE-7909 [ ICE-7909 ]
          Mark Collette made changes -
          Status Open [ 1 ] Closed [ 6 ]
          Resolution Invalid [ 6 ]
          Hide
          Mark Collette added a comment -

          Subversion 28310 should have been made under ICE-7909.

          Show
          Mark Collette added a comment - Subversion 28310 should have been made under ICE-7909 .

            People

            • Assignee:
              Mark Collette
              Reporter:
              Deryk Sinotte
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: