3 Replies Latest reply on Jun 15, 2009 1:24 PM by Joachim Skeie

    Finding component by ID (Not ClientID)

    Joachim Skeie Newbie

      Hello,

      I am developing a custom chart component for JSF, and I need to be able to find a component based on its ID, and not its ClientID.

      If I have a component in my JSF page like so:

      {code}
      <h:form id="myForm">

      </h:form>
      {code}

      I need to be able to find this component using the String "myID", and not the clientID which is "myForm:myID".

      Do anyone have any tips on how to archeive this without traversing the whole tag-tree manually ?

        • 1. Re: Finding component by ID (Not ClientID)
          Joachim Skeie Newbie

           

          <h:form id="myForm">
          <mycomponent id="myID"/>
          </h:form>
          


          • 2. Re: Finding component by ID (Not ClientID)
            Matthew Pickell Newbie

            Here is code that I use to do this dynamically, but it is re-traversing the whole tag tree when needed.

            If you already have a reference to the component, you can just use the second method called "getFullComponentId" to get the full id.

            /**
             * Search the JSF Tree for a component based only on its partial component ID (i.e.,
             * without the NamingContainer)
             * @author matt.pickell
             */
            public class JSFTreeComponentFinder {
            
             /**
             * Recursively search for the partial componentID in the JSF tree. If found, return its absolute ID.
             * @param partialComponentId the id that the component was created with. NOT containing the NamingContainer
             * @return the full ID, with naming container for using in finding this component in the JSF Tree.
             * Or null if no component exists with that partial ID
             */
             public static String buildAbsoluteComponentIDFromJsfTree(String partialComponentId, UIComponent root) {
             if (root.getChildCount() > 0) {
             for (Object next : root.getChildren()) {
             UIComponent current = (UIComponent) next;
             if (partialComponentId.equals(current.getId())) {
             return getFullComponentId(current);
             } else {
             if (current.getChildCount() > 0) {
             String subTreeHunt = buildAbsoluteComponentIDFromJsfTree(partialComponentId, current);
             if (subTreeHunt != null) {
             return subTreeHunt;
             }
             }
             }
             }
             }
             return null;
             }
            
             /**
             * Once a component is known in the JSF tree, this returns its absolute ID
             * @param component build absolute ID based on JSF Tree structure.
             * @return the absolute ID of the component.
             */
             public static String getFullComponentId(UIComponent component) {
             String fullId = component.getId();
            
             component = component.getParent();
             while (component != null) {
             if (component instanceof NamingContainer) {
             fullId = component.getId() + NamingContainer.SEPARATOR_CHAR + fullId;
             }
             component = component.getParent();
             }
            
             return fullId;
             }
            
            }
            


            • 3. Re: Finding component by ID (Not ClientID)
              Joachim Skeie Newbie

              Thanks mpickell!

              That code actually builds up the clientId, which might be a bit overkill for my setup.

              I currently use this code (which is cut out from http://illegalargumentexception.googlecode.com/svn/trunk/code/java/JsfClientId/src/demo/faces/ClientIdUtils.java):

              public static UIComponent findComponent(UIComponent component, String id) {
               if (id.equals(component.getId())) {
               return component;
               }
              
               Iterator<UIComponent> kids = component.getFacetsAndChildren();
               while (kids.hasNext()) {
               UIComponent kid = kids.next();
               UIComponent found = findComponent(kid, id);
               if (found != null) {
               return found;
               }
               }
              
               return null;
               }
              


              Which traverses the component tree untill the ID is found and then returns that components getClientId() value. I'd still would have liked JSF to have an efficient method to do this sort of stuff in the API though...