Thursday, 3 December 2009

JSF - Automatic mandatory indicator

In JSF 1.2, there is no built-in support for mandatory indicator and it seems that we have to do it manually :-(. Fortunately, there is another automatic way to do it with the help from attribute "for" in HtmlOutputLabel and FaceletViewHandler:

  • Extending FaceletViewHandler with your own handler and override method buildView() to add a post-decorator to the GUI components after the view is built (don't forget to configure this as your view handler in the faces configuration)
  • @Override    protected void buildView(FacesContext context, UIViewRoot viewToRender) throws IOException,            FacesException {        super.buildView(context, viewToRender);        decorateGUIComponents();    }
  • In your post-decorator, check for all componenents which are instances of HtmlOutputLabel. If the "for" attribute in an HtmlOutputLabel points to a UIInput with "required=true", then apply the desired indicator
    private void buildIdToComponentMap(UIComponent c, Map<String, UIComponent> comps) {        comps.put(c.getId(), c);        Iterator<UIComponent> kids = c.getFacetsAndChildren();        while (kids.hasNext()) {            UIComponent kid = kids.next();            buildIdToComponentMap(kid, comps);        }    }private void decorateGUIComponents() {        Map<String, UIComponent> comps = new HashMap<String, UIComponent>();        buildIdToComponentMap(FacesUtils.getFacesContext().getViewRoot(), comps);        addMandatoryIndicators(comps);    }private void addMandatoryIndicators(Map<String, UIComponent> comps) {                final List<String> inputFieldsToBeEnabled = (List<String>) FacesUtils                .removeSessionMapValue(WebConstants.SESSION_INPUT_FIELDS_TO_BE_ENABLED);                String oldValue = null;        for (String key : comps.keySet()) {            UIComponent sourceComp = comps.get(key);            if (sourceComp instanceof HtmlOutputLabel) {                HtmlOutputLabel label = (HtmlOutputLabel) sourceComp;                if (label.getFor() != null) {                    UIComponent targetComp = comps.get(label.getFor());                    if (targetComp instanceof UIInput) {                        if (((UIInput) targetComp).isRequired()) {                            oldValue = (String) label.getValue();                            if (!StringUtils.endsWith(oldValue, "*")) {                                label.setValue(oldValue + "*");                            }                        }                    }                }            }        }    }

No comments:

Post a Comment