13

Imagine a JSF page with several components such as <h:selectOneMenu>, <h:dataTable>, <h:panelGrid>, etc. Each component has an ID. Is there any method or technique by which I can get the components programmatically when the constructor of the bean is invoked?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Basit
  • 8,426
  • 46
  • 116
  • 196
  • 4
    "pragmatic" has a completely different meaning than "programmatic". Please consult a dictionary if you aren't sure about the spelling :) – BalusC Dec 14 '11 at 18:21

4 Answers4

37

You can get the component tree by FacesContext#getViewRoot() and find a particular component by ID by UIComponentBase#findComponent():

UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
UIComponent component = viewRoot.findComponent("someId");
// ...

However, the view root is not directly available in the bean's constructor per se. It might return null on GET requests to a view wherein the bean is not referenced in a view build time tag or attribute. It's however guaranteed to be available during the pre render view event.

<f:event type="preRenderView" listener="#{bean.init}" />

with

public void init() {
    // ...
}

Unrelated to the concrete problem, it's not clear why you need to do this, but I can tell that this is more than often a code smell. I suggest to investigate if this is really the right solution for the concrete functional requirement you've had in mind. For clues and hints, see also How does the 'binding' attribute work in JSF? When and how should it be used? and How to use component binding in JSF right ? (request-scoped component in session scoped bean).

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
3

I tried your solution and it worked :). Here i just posting my answer that how i did it. Actually someone just asked me this question that can we get all the components inside a constructor when our page invoke, i.e., why i asked on this forum:). Here is my code

/** Creates a new instance of ExporterProfileUpdateRequestGrid */
public ExporterProfileUpdateRequestGrid() {

    session = ConnectionUtil.getCurrentSession();
    exporterProfileUpdateRequestList = new ArrayList<ExporterProfileUpdateRequest>();

    int test = selectedRadioButton;
    System.out.println();
    //getExporterProfileUpdateRequestGrid();

} //end of constructor

@PostConstruct
public void init() {

    UIViewRoot viewRoot =  FacesContext.getCurrentInstance().getViewRoot();
    UIComponent component1 = viewRoot.findComponent("exporterProfileUpdateRequestGrid");  //form id
    HtmlForm form = (HtmlForm)component1;

    List<UIComponent> componentList = form.getChildren();

    for(int i=0; i<componentList.size(); i++) {

        UIComponent component = componentList.get(i);

        if (component instanceof Panel) {

            Panel myPanel = (Panel)component;

            List<UIComponent> panelComponentList = myPanel.getChildren();

            for(int j=0; j<panelComponentList.size(); j++) {

                UIComponent panelComponent = panelComponentList.get(j);

                System.out.println();


            }

             System.out.println();

        }

        System.out.println();

    } //end of for()

    UIComponent component2 = viewRoot.findComponent("panel1");   //null
    UIComponent component3 = viewRoot.findComponent("myTable");  // null

} //end of init

I want to ask that i got form(HtmlForm) here, but panel1 and myTable null, why? Although i get panel and table by inspecting HtmlForm children, but why i can't get them directly.

Thanks

Basit
  • 8,426
  • 46
  • 116
  • 196
2

see this http://horrikhalid.com/2011/01/27/how-to-find-uicomponent-in-jsf/

public UIComponent findComponent(String id) {

UIComponent result = null;
UIComponent root = FacesContext.getCurrentInstance().getViewRoot();
if (root != null) {
result = findComponent(root, id);
}
return result;

}

private UIComponent findComponent(UIComponent root, String id) {

UIComponent result = null;
if (root.getId().equals(id))
return root;

for (UIComponent child : root.getChildren()) {
if (child.getId().equals(id)) {
result = child;
break;
}
result = findComponent(child, id);
if (result != null)
break;
}
return result;
}
Marin
  • 1,010
  • 1
  • 10
  • 37
0

If the panel and the table are in form, try the following:

UIComponent component2 = viewRoot.findComponent("exporterProfileUpdateRequestGrid").findComponent("panel1");
Elmo
  • 6,409
  • 16
  • 72
  • 140
angela
  • 1