Patrick Kwinten
Patrick Kwinten

Reputation: 2048

Possible to set the styleClass of a xp:control from validator class?

For a form I have set up a validaor for an Edit Box e.g.:

<xp:inputText
    id="inpRiskFactors" 
    styleClass="inputEscalation"
    value="#{matterBean.matter.escRiskFactors}" 
    validator="#{matterValidators.valEscRiskFactors}"...

Here is a snippet from my validating method:

public void valEscRiskFactors(FacesContext facesContext, UIComponent component, Object value) {        
        utils.printToConsole(this.getClass().getSimpleName().toString() + " - valEscRiskFactors(...), value = " + value.toString());
        String msg = null;
        if (value.toString().replaceAll("\\s+","").equals("")){
            msg = matterProp.getProperty("msg_valid_esc_risk_factors");
            FacesMessage message = new FacesMessage(msg);
            throw new ValidatorException(message);
        }       
    }

I was wondering if I could change/set the styleclass property of the calling component (UIComponent component) from this method?

For the user it would be nice to apply some CSS on the xp:controls that are required and do not pass the validation.

Anyone have a clue how to achieve this?

Upvotes: 0

Views: 104

Answers (2)

Stanislaw Guzik
Stanislaw Guzik

Reputation: 244

The explicit call to setStyleClass method of UIComponent casted to XspInputText works for me

((XspInputText)component).setStyleClass("my-class");

If you don't want to cast but want to apply the styleClass to any component that supports such property, java reflection can help:

try {
    Method setStyleClass = component.getClass().getMethod("setStyleClass", String.class);
    if (setStyleClass != null) {
        setStyleClass.invoke(component, "my-class");
    }
} catch (SecurityException e) {} 
catch (NoSuchMethodException e) {}
catch (IllegalArgumentException e) {}
catch (IllegalAccessException e) {}
catch (InvocationTargetException e) {}

You may want to append the styleClass instead of replace

try {
    String styleClass = null;
    Method getStyleClass = component.getClass().getMethod("getStyleClass");
    if (getStyleClass != null) {
        styleClass = (String)getStyleClass.invoke(component, (Object[])null);
    }
    Method setStyleClass = component.getClass().getMethod("setStyleClass", String.class);
    if (setStyleClass != null) {
        String newStyleClass = StringUtil.isNotEmpty(styleClass) ? styleClass.concat(" my-class") : "my-class";
        setStyleClass.invoke(component, newStyleClass);
    }
} catch (SecurityException e) {} 
catch (NoSuchMethodException e) {}
catch (IllegalArgumentException e) {}
catch (IllegalAccessException e) {}
catch (InvocationTargetException e) {}

Upvotes: 1

Per Henrik Lausten
Per Henrik Lausten

Reputation: 21709

Most (all?) standard XPages controls uses the WAI-ARIA standard for validation and therefore automatically gets the aria-invalid property set to "true" when the control is invalid.

This means that you can use CSS to style the input control. You can for instance style the background-color and border differently when the control is invalid:

[aria-invalid=true] {
    background-color: #fee;
    border-color: red;
} 

Upvotes: 5

Related Questions