Find component by type in JSF

前端 未结 1 1145
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-31 18:39

My question is related to this one Get all hidden input fields in JSF dynamically but it\'s not the same as I want to work with JSF and not plain HTML, and assuming that I h

1条回答
  •  没有蜡笔的小新
    2020-12-31 19:03

    You also need to iterate over children of children, and their children, etcetera. You see, it's a component tree.

    Here's a kickoff snippet of an utility method which does exactly that using tail recursion:

    public static  void findChildrenByType(UIComponent parent, List found, Class type) {
        for (UIComponent child : parent.getChildren()) {
            if (type.isAssignableFrom(child.getClass())) {
                found.add(type.cast(child));
            }
    
            findChildrenByType(child, found, type);
        }
    }
    

    Here's how you could use it:

    UIForm form = (UIForm) FacesContext.getCurrentInstance().getViewRoot().findComponent("formId");
    List hiddenComponents = new ArrayList<>();
    findChildrenByType(form, hiddenComponents, HtmlInputHidden.class);
    
    for (HtmlInputHidden hidden : hiddenComponents) {
        System.out.println(hidden.getValue());
    }
    

    Or, better, use UIComponent#visitTree() which uses the visitor pattern. The major difference is that it also iterates over iterating components such as and and restores the child state for every iteration. Otherwise you would end up getting no value when you have an enclosed in such component.

    FacesContext context = FacesContext.getCurrentInstance();
    List hiddenComponentValues = new ArrayList<>();
    context.getViewRoot().findComponent("formId").visitTree(VisitContext.createVisitContext(context), new VisitCallback() {
        @Override
        public VisitResult visit(VisitContext visitContext, UIComponent component) {
            if (component instanceof HtmlInputHidden) {
                hiddenComponentValues.add(((HtmlInputHidden) component).getValue());
                return VisitResult.COMPLETE;
            } else {
                return VisitResult.ACCEPT;
            }
        }
    });
    
    for (Object hiddenComponentValue : hiddenComponentValues) {
        System.out.println(hiddenComponentValue);
    }
    
    
    

    See also:

    • How to collect values of an UIInput component inside an UIData component in bean's action method?
    • How do I attach a FacesMessage from the backing bean to a specific field in a ui:repeat?
    • Accessing dynamic UIComponents in JSF Managed Bean
    • JSF 2 -- Save All Valid Component Values

    After all, it's probably easiest to just bind them to a bean property the usual way, if necessary inside an :

    
    
    

    0 讨论(0)
    提交回复
    热议问题