ICEfaces
  1. ICEfaces
  2. ICE-6398

CoreComponentUtils.findComponent(UIComponent, String) is bailing out too early, not recursing through the component tree enough to find a matching clientId

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Invalid
    • Affects Version/s: 2.0-Beta2
    • Fix Version/s: None
    • Component/s: Framework
    • Labels:
      None
    • Environment:
      Found with Liferay 6.0 + PortletFaces-Bridge 2.0.0-BETA3 but it's not portlet related.

      Description

      I have a JSF 2 Facelet composite component wrapping ice:dataTable like this:

      <my-comp:dataPaginator for=":myData" />
      <ice:dataTable id="myData">
      </ice:dataTable>

      The colon in front of :myData indicates that the search should start from the root of the tree. Sadly, CoreComponentUtils.findComponent(UIComponent, String) is bailing out too early, not recursing through the component tree enough to find a matching clientId.

      Here's a patch to fix:


      ===================================================================
      --- /icefaces-src/2.0-trunk/icefaces/compat/core/src/main/java/com/icesoft/util/CoreComponentUtils.java (revision 23550)
      +++ /icefaces-src/2.0-trunk/icefaces/compat/core/src/main/java/com/icesoft/util/CoreComponentUtils.java (working copy)
      @@ -162,6 +162,12 @@
                       component = child;
                       break;
                   }
      + if (component == null) {
      + component = findComponent(child, componentId);
      + if (component != null) {
      + break;
      + }
      + }
               }
               return component;
           }

        Issue Links

          Activity

          Neil Griffin created issue -
          Hide
          Mark Collette added a comment -

          Are those components within a form? Does the form have prependId=false?

          Show
          Mark Collette added a comment - Are those components within a form? Does the form have prependId=false?
          Hide
          Neil Griffin added a comment -

          Yes they are inside an h:form – I didn't set the prependId value, so the default would be true according to the VDLDocs: http://javaserverfaces.java.net/nonav/docs/2.0/pdldocs/facelets/h/form.html

          I would like to have prependId=true so that the child elements are namespaced well, in case I have multiple forms.

          Show
          Neil Griffin added a comment - Yes they are inside an h:form – I didn't set the prependId value, so the default would be true according to the VDLDocs: http://javaserverfaces.java.net/nonav/docs/2.0/pdldocs/facelets/h/form.html I would like to have prependId=true so that the child elements are namespaced well, in case I have multiple forms.
          Hide
          Mark Collette added a comment -

          So what you'd have is:

          <h:form id="something">
          <my-comp:dataPaginator for=":myData" />
          <ice:dataTable id="myData">

          The appropriate for values would either be:
          :something:myData
          or
          myData

          Show
          Mark Collette added a comment - So what you'd have is: <h:form id="something"> <my-comp:dataPaginator for=":myData" /> <ice:dataTable id="myData"> The appropriate for values would either be: :something:myData or myData
          Mark Collette made changes -
          Field Original Value New Value
          Comment [ Can you please provide the whole .xhtml page, so we can see the parents of these components, to see what the NamingContainers in the parentage are. ]
          Hide
          Neil Griffin added a comment -

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
          <ui:composition xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
          xmlns:aui="http://portletfaces.org/alloyfaces/aui" xmlns:aui-cc="http://portletfaces.org/alloyfaces/aui-cc"
          xmlns:liferay-ui="http://portletfaces.org/liferayfaces/liferay-ui" xmlns:ice="http://www.icesoft.com/icefaces/component"
          xmlns:ui="http://java.sun.com/jsf/facelets"
          xmlns:icecore="http://www.icefaces.org/icefaces/core">
          <icecore:config render="true" />
          <ice:form id="f2" styleClass="aui-form dlp">
          <aui-cc:messages globalOnly="true" layout="table" />
          <ice:panelGroup rendered="#

          {usersViewBean.formRendered}

          ">
          <aui:layout>
          <aui:button-row>
          <aui-cc:button type="submit">
          <f:actionListener for="click" binding="#

          {usersBackingBean.saveUserActionListener}

          " />
          </aui-cc:button>
          <aui-cc:button immediate="true" type="cancel">
          <f:actionListener for="click" binding="#

          {usersBackingBean.cancelUserActionListener}

          " />
          </aui-cc:button>
          </aui:button-row>
          <hr />
          </aui:layout>
          </ice:panelGroup>
          <ice:panelGroup rendered="#

          {!usersViewBean.formRendered}

          ">
          <aui:layout>
          <aui:column styleClass="aui-w100">
          <aui:fieldset>
          <aui-cc:select inlineMessage="true" label="#

          {i18n['status']}

          " required="true" value="#

          {usersModelBean.searchCriteria.active}

          ">
          <f:selectItem itemLabel="#

          {i18n['active']}

          " itemValue="true" />
          <f:selectItem itemLabel="#

          {i18n['inactive']}

          " itemValue="false" />
          </aui-cc:select>
          <aui:button-row>
          <aui-cc:button type="submit" label="#

          {i18n['search']}

          ">
          <f:actionListener for="click" binding="#

          {usersBackingBean.searchActionListener}

          " />
          </aui-cc:button>
          </aui:button-row>
          </aui:fieldset>
          <liferay-ui:ice-page-iterator for=":users" />
          <ice:dataTable id="users" rows="2" value="#

          {usersModelBean.userDataModel}

          " var="user">
          <ice:column>
          <liferay-ui:icon image="edit" listItemStyle="list-style-type: none;">
          <f:param name="userId" value="#

          {user.userId}

          " />
          <f:actionListener for="click" binding="#

          {usersBackingBean.selectUserActionListener}

          " />
          </liferay-ui:icon>
          </ice:column>
          <ice:column>
          <f:facet name="header">
          <h:outputText value="#

          {i18n['last-name']}

          " />
          </f:facet>
          <h:outputText value="#

          {user.lastName}

          " />
          </ice:column>
          <ice:column>
          <f:facet name="header">
          <h:outputText value="#

          {i18n['first-name']}

          " />
          </f:facet>
          <h:outputText value="#

          {user.firstName}

          " />
          </ice:column>
          <ice:column>
          <f:facet name="header">
          <h:outputText value="#

          {i18n['email-address']}

          " />
          </f:facet>
          <h:outputText value="#

          {user.emailAddress}

          " />
          </ice:column>
          </ice:dataTable>
          <liferay-ui:info message="there-are-no-results" rendered="#

          {usersModelBean.userDataModel.rowCount == 0}

          " />
          </aui:column>
          </aui:layout>
          </ice:panelGroup>
          </ice:form>
          </ui:composition>

          Show
          Neil Griffin added a comment - <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <ui:composition xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:aui="http://portletfaces.org/alloyfaces/aui" xmlns:aui-cc="http://portletfaces.org/alloyfaces/aui-cc" xmlns:liferay-ui="http://portletfaces.org/liferayfaces/liferay-ui" xmlns:ice="http://www.icesoft.com/icefaces/component" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:icecore="http://www.icefaces.org/icefaces/core"> <icecore:config render="true" /> <ice:form id="f2" styleClass="aui-form dlp"> <aui-cc:messages globalOnly="true" layout="table" /> <ice:panelGroup rendered="# {usersViewBean.formRendered} "> <aui:layout> <aui:button-row> <aui-cc:button type="submit"> <f:actionListener for="click" binding="# {usersBackingBean.saveUserActionListener} " /> </aui-cc:button> <aui-cc:button immediate="true" type="cancel"> <f:actionListener for="click" binding="# {usersBackingBean.cancelUserActionListener} " /> </aui-cc:button> </aui:button-row> <hr /> </aui:layout> </ice:panelGroup> <ice:panelGroup rendered="# {!usersViewBean.formRendered} "> <aui:layout> <aui:column styleClass="aui-w100"> <aui:fieldset> <aui-cc:select inlineMessage="true" label="# {i18n['status']} " required="true" value="# {usersModelBean.searchCriteria.active} "> <f:selectItem itemLabel="# {i18n['active']} " itemValue="true" /> <f:selectItem itemLabel="# {i18n['inactive']} " itemValue="false" /> </aui-cc:select> <aui:button-row> <aui-cc:button type="submit" label="# {i18n['search']} "> <f:actionListener for="click" binding="# {usersBackingBean.searchActionListener} " /> </aui-cc:button> </aui:button-row> </aui:fieldset> <liferay-ui:ice-page-iterator for=":users" /> <ice:dataTable id="users" rows="2" value="# {usersModelBean.userDataModel} " var="user"> <ice:column> <liferay-ui:icon image="edit" listItemStyle="list-style-type: none;"> <f:param name="userId" value="# {user.userId} " /> <f:actionListener for="click" binding="# {usersBackingBean.selectUserActionListener} " /> </liferay-ui:icon> </ice:column> <ice:column> <f:facet name="header"> <h:outputText value="# {i18n['last-name']} " /> </f:facet> <h:outputText value="# {user.lastName} " /> </ice:column> <ice:column> <f:facet name="header"> <h:outputText value="# {i18n['first-name']} " /> </f:facet> <h:outputText value="# {user.firstName} " /> </ice:column> <ice:column> <f:facet name="header"> <h:outputText value="# {i18n['email-address']} " /> </f:facet> <h:outputText value="# {user.emailAddress} " /> </ice:column> </ice:dataTable> <liferay-ui:info message="there-are-no-results" rendered="# {usersModelBean.userDataModel.rowCount == 0} " /> </aui:column> </aui:layout> </ice:panelGroup> </ice:form> </ui:composition>
          Hide
          Neil Griffin added a comment -

          Note that I have ":users" as the value of the "for" attribute. I never used to have to put the colon with JSF 1.2 and Facelets. But now with JSF 2.0 Facelets, the liferay-ui:ice-page-iterator composite component is actually a NamingContainer. So I think one problem here is that CoreComponentUtils tries to recurse up until it hits a NamingContainer and doesn't expect it – it bumps into the UIComponent (the component represented by "cc") which is actually a NamingContainer, and it stops. The other problem (described in the title of this issue) is that if you start at the root, by putting a colon character as the first character in the "for" attribute, then it doesn't recurse all the way down through all the children.

          Show
          Neil Griffin added a comment - Note that I have ":users" as the value of the "for" attribute. I never used to have to put the colon with JSF 1.2 and Facelets. But now with JSF 2.0 Facelets, the liferay-ui:ice-page-iterator composite component is actually a NamingContainer. So I think one problem here is that CoreComponentUtils tries to recurse up until it hits a NamingContainer and doesn't expect it – it bumps into the UIComponent (the component represented by "cc") which is actually a NamingContainer, and it stops. The other problem (described in the title of this issue) is that if you start at the root, by putting a colon character as the first character in the "for" attribute, then it doesn't recurse all the way down through all the children.
          Hide
          Neil Griffin added a comment -

          Forgot to mention that there is an ice:dataPaginator inside the liferay-ui:ice-page-iterator composite component. The datapaginator can't find the component associated with the clientId in the "for" attribute now with JSF 2.0 Facelets.

          Show
          Neil Griffin added a comment - Forgot to mention that there is an ice:dataPaginator inside the liferay-ui:ice-page-iterator composite component. The datapaginator can't find the component associated with the clientId in the "for" attribute now with JSF 2.0 Facelets.
          Ken Fyten made changes -
          Salesforce Case []
          Fix Version/s 2.0.1 [ 10255 ]
          Assignee Mark Collette [ mark.collette ]
          Neil Griffin made changes -
          Link This issue duplicates ICE-6226 [ ICE-6226 ]
          Hide
          Travis De Silva added a comment -

          Using the colon I was able to get it to work. So you need to give the proper DOM hierarchy and it works. But would be good if it works as suggested by Neil.

          Show
          Travis De Silva added a comment - Using the colon I was able to get it to work. So you need to give the proper DOM hierarchy and it works. But would be good if it works as suggested by Neil.
          Arran Mccullough made changes -
          Salesforce Case [5007000000FZuRM]
          Hide
          Ken Fyten added a comment -

          This will be dealt with by the resolution to ICE-5721.

          Show
          Ken Fyten added a comment - This will be dealt with by the resolution to ICE-5721.
          Ken Fyten made changes -
          Link This issue depends on ICE-5721 [ ICE-5721 ]
          Ken Fyten made changes -
          Fix Version/s 2.1 [ 10241 ]
          Fix Version/s 2.0.1 [ 10255 ]
          Mark Collette made changes -
          Link This issue depends on ICE-6667 [ ICE-6667 ]
          Hide
          Deryk Sinotte added a comment -

          It's likely that the rationale and fix provided for ICE-6659 will fix this problem as well but we'll need the original reporter to test and verify.

          Assigning to Neil for verification.

          Show
          Deryk Sinotte added a comment - It's likely that the rationale and fix provided for ICE-6659 will fix this problem as well but we'll need the original reporter to test and verify. Assigning to Neil for verification.
          Deryk Sinotte made changes -
          Assignee Mark Collette [ mark.collette ] Neil Griffin [ ngriffin7a ]
          Hide
          Deryk Sinotte added a comment -

          I did test against an inputText nested in a panelSeries in a portlet and, with the id provided by the PortletFaces UIViewRoot implementation, the findComponent algorithm did work and the "required" validation operated as expected.

          Show
          Deryk Sinotte added a comment - I did test against an inputText nested in a panelSeries in a portlet and, with the id provided by the PortletFaces UIViewRoot implementation, the findComponent algorithm did work and the "required" validation operated as expected.
          Hide
          Deryk Sinotte added a comment -

          The main research and documenation on the fix for this issue is in ICE-6659 so I'm linking to that case.

          Show
          Deryk Sinotte added a comment - The main research and documenation on the fix for this issue is in ICE-6659 so I'm linking to that case.
          Deryk Sinotte made changes -
          Link This issue depends on ICE-6659 [ ICE-6659 ]
          Hide
          Neil Griffin added a comment -

          I tested the pf-directory-portlet (uses LiferayFaces, which in turn tests this bug) and the ICEfaces trunk revision 24185 (today). Unfortunately it still doesn't work. Assigning back to Deryk.

          Show
          Neil Griffin added a comment - I tested the pf-directory-portlet (uses LiferayFaces, which in turn tests this bug) and the ICEfaces trunk revision 24185 (today). Unfortunately it still doesn't work. Assigning back to Deryk.
          Neil Griffin made changes -
          Assignee Neil Griffin [ ngriffin7a ] Deryk Sinotte [ deryk.sinotte ]
          Ken Fyten made changes -
          Assignee Deryk Sinotte [ deryk.sinotte ] Ken Fyten [ ken.fyten ]
          Hide
          Ted Goddard added a comment -

          Investigate whether a bean method can plug in an alternate findComponent strategy:

          <ice:label for="#

          {bean.find('comp27')}

          " />

          or perhaps a custom EL resolver.

          Show
          Ted Goddard added a comment - Investigate whether a bean method can plug in an alternate findComponent strategy: <ice:label for="# {bean.find('comp27')} " /> or perhaps a custom EL resolver.
          Ken Fyten made changes -
          Fix Version/s 3.1 [ 10312 ]
          Fix Version/s 3.0 [ 10241 ]
          Ken Fyten made changes -
          Fix Version/s 3.2 [ 10338 ]
          Fix Version/s 3.1 [ 10312 ]
          Migration made changes -
          Fix Version/s 3.3 [ 10370 ]
          Fix Version/s 3.2 [ 10338 ]
          Ken Fyten made changes -
          Fix Version/s 3.3 [ 10370 ]
          Ken Fyten made changes -
          Assignee Ken Fyten [ ken.fyten ]
          Hide
          Ken Fyten added a comment -

          Marking as Closed / Invalid as part of legacy ICEfaces 1.x, 2.x JIRA cleanup.

          Note: This issue may be resolved in a newer ICEfaces release, available here: http://www.icesoft.org/java/downloads/icefaces-downloads.jsf

          If the issue persists with the current ICEfaces release, please create a new JIRA for it.

          Show
          Ken Fyten added a comment - Marking as Closed / Invalid as part of legacy ICEfaces 1.x, 2.x JIRA cleanup. Note: This issue may be resolved in a newer ICEfaces release, available here: http://www.icesoft.org/java/downloads/icefaces-downloads.jsf If the issue persists with the current ICEfaces release, please create a new JIRA for it.
          Ken Fyten made changes -
          Status Open [ 1 ] Closed [ 6 ]
          Resolution Invalid [ 6 ]

            People

            • Assignee:
              Unassigned
              Reporter:
              Neil Griffin
            • Votes:
              3 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: