Uploaded image for project: 'MyFaces Core'
  1. MyFaces Core
  2. MYFACES-4026

Composite Component cc.clientId not usable in custom tag

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Trivial
    • Resolution: Won't Fix
    • Affects Version/s: 2.1.17
    • Fix Version/s: None
    • Component/s: General
    • Labels:
      None

      Description

      If you use the cc.clientId in a custom tag, then the wrong ids are generated.

      <composite:implementation>
      	<cure:grid id="#{cc.clientId}">
      		<cure:gridRow>
      			<cure:gridCol width="12">
      				my col
      			</cure:gridCol>
      		</cure:gridRow>
      	</cure:grid>
      </composite:implementation>
      

      Here we need an id otherwise an update on this component will fail since there wouldn't be an html node on the client side which contents can be replaced by an update. There are some cases where the composite component is not allowed to define an div which holds the client id.

      <composite:implementation>
      <!-- Would break grid container specification -->
      <div id="#{cc.clientid}">
      		<cure:gridRow>
      			<cure:gridCol width="12">
      				my col
      			</cure:gridCol>
      		</cure:gridRow>
      <div>
      </composite:implementation>
      

      We think this is caused by the fact that the cc.clientId is accessed during build view time and gets cached in the UIComponentBase. At this time the cc.clientId is empty. This seems to be a common issue, because cc.clientId can never be accessed at build view time.

      "UIComponentBase#getClientId"
          @Override
          public String getClientId(FacesContext context)
          {
              if (context == null)
              {
                  throw new NullPointerException("context");
              }
      
              if (_clientId != null)
              {
                  return _clientId;
              }
      ...
      }
      
      "one of the custom tags we use"
      <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:p="http://primefaces.org/ui"
          xmlns:ui="http://java.sun.com/jsf/facelets">
          
          <c:set var="styleClass" value="#{not empty styleClass ? styleClass : ''}" />
          <c:set var="style" value="#{not empty style ? style : ''}" />
          <c:set var="rendered" value="#{not empty rendered ? rendered : true}" />
          <c:set var="isFormRow" value="#{not empty isFormRow and isFormRow}" />
      	
      	<c:if test="#{not empty id}">
      		<h:panelGroup id="#{id}" layout="block" styleClass="#{isFormRow ? 'form-row' : ''} #{styleClass} ui-grid-row" style="#{style}" rendered="#{rendered}">
      			<ui:insert/>
      		</h:panelGroup>
      	</c:if>
      	
      	<c:if test="#{empty id}">
      		<h:panelGroup layout="block" styleClass="#{isFormRow ? 'form-row' : ''} #{styleClass} ui-grid-row" style="#{style}" rendered="#{rendered}">
      			<ui:insert/>
      		</h:panelGroup>
      	</c:if>
      	
      </ui:composition>
      
      "resulting html"
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
      <html xmlns="http://www.w3.org/1999/xhtml">
         <head></head>
         <body>
            <form id="myForm1" name="myForm1" method="post" action="/jsf2-basic-portlet/index.xhtml" enctype="application/x-www-form-urlencoded">
               <div id="composite1:composite1" class=" ui-grid ui-grid-responsive">
                  <div class="  ui-grid-row">
                     <div class=" ui-grid-col-12">
                        my col
                     </div>
                  </div>
               </div>
               <input type="hidden" name="myForm1_SUBMIT" value="1" /><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="puXzCX78lsGwm5D7TAEgUKup9vm0hFpybGfw7y1R85EQt46s" />
            </form>
            <form id="myForm2" name="myForm2" method="post" action="/jsf2-basic-portlet/index.xhtml" enctype="application/x-www-form-urlencoded"><span id="myForm2:composite2:myOutputText">OutputText</span><input type="hidden" name="myForm2_SUBMIT" value="1" /><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="puXzCX78lsGwm5D7TAEgUKup9vm0hFpybGfw7y1R85EQt46s" /></form>
         </body>
      </html>
      

      I have an sample which I could provide but here is no option to upload it.

        Attachments

        1. demo.zip
          38 kB
          Thomas Herzog

          Issue Links

            Activity

              People

              • Assignee:
                lu4242 Leonardo Uribe
                Reporter:
                cchet Thomas Herzog
              • Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: