How to use XPages Java code to set valid method of input control inside a custom control?

▼魔方 西西 提交于 2019-12-19 08:54:01

问题


Ok, this is a weird one.

In XPages my dataSource is a Java Object. A Managed bean or PageController. I'm using bootstrap via the Ext. Library.

What I'd like to do is keep all my validation code inside my Java Object rather then attaching anything to the control on the XPage. Inside the java object I can add any error messages via: FacesContext.getCurrentInstance().addMessage

So any errors can by showed via an control.

BUT what I don't know how to do is to target an individual control if I wanted to send a message to a specific (singular) control.

Realistically what I'd love to be able to is use this example for a bootstrap field custom control : http://www.bootstrap4xpages.com/bs4xp/demos.nsf/reusableFields.xsp

and from my Java class set the isValid method so the bootstrap field is rendered red via the has-error style.

Any advice on how to get to the the isValid for an input control inside a custom control or even an alternative method to let me validate via java but control the field styling would be appreciated.

Thanks


回答1:


What I do is using a custom validator for the component. For instance,

<xp:this.validators>
    <xp:customValidator validate="#{javascript:controller.validateDuration(this)}"></xp:customValidator>
</xp:this.validators>

In my controller class:

public void validateDuration(UIComponent source) {
    // Do my checks...
    // If fails,
    BeanUtils.setControlInvalid(source, "Format Error at date time!");
}

BeanUtils methods to invalidate a specific component and generate a validation error message:

public static void setControlInvalid(UIComponent editableComponent, String message) {
    if(StringUtil.isEmpty(message) || editableComponent==null) return;

    if(editableComponent instanceof EditableValueHolder) {
        ((EditableValueHolder) editableComponent).setValid(false);
        postFacesMessage(editableComponent, FacesMessage.SEVERITY_ERROR, message);
    }

}

public static void postFacesMessage(UIComponent component, Severity severity, String msg) {
    if(StringUtil.isEmpty(msg) || component==null) return;

    FacesContext fc=FacesContext.getCurrentInstance();

    FacesMessage message=new FacesMessage(severity, msg, msg);
    fc.addMessage(component.getClientId(fc), message);
}



回答2:


Any UIComponent has a setValid(boolean) method. All controls also have a binding property, which can be used to bind that component to a Java object, e.g. a property in your bean.

However, if your custom control is used multiple times, you can't use that, because all instances would be trying to bind to the same bean property.

But, with a bit of cunning thought, it's possible to take advantage of the same concept. If your bean has a Map<String, Component> myCunningBindings, you could add a collection of bindings dynamically using this code in the loaded property:

<this.loaded><![CDATA[${javascript:myBean.getMyCunningBindings().put(compositeData.fieldMapping, this);
return "";}]]>
</xp:this.loaded>

So the first line of the code gets the map and adds an element. That element has a value (the component itself) and a label. For the label, we get the field mapping that you're also likely to be passing in via compositeData. Finally, we return true.

Your bean that does the validation should know where it's saving it to, so you should be able to calculate the field mapping that was passed into compositeData, which will be the key you need to look for in the Map. And from there, you have the component to call setValid(false) on.



来源:https://stackoverflow.com/questions/29847441/how-to-use-xpages-java-code-to-set-valid-method-of-input-control-inside-a-custom

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!