简体   繁体   中英

Validation/conversion for two component based composite in JSF

I'm developing a JSF web application where I need to use periodicities as data structure. Here there are the Java classes I work with:

public class Periodicity implements Serializable {

    private Integer value = 0;

    private PeriodicityType type;

    //Getter and setters

}

public enum PeriodicityType {
    DAY, WEEK, MONTH, YEAR
}

That way I can specify different periodicities for my tasks, which can combine values with PeriodicityType .

I also have created an input composite element called periodicityInput.xhtml , which I can use to provide that data type in different forms in a reusable way:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:composite="http://java.sun.com/jsf/composite"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets">

<h:body>
    <composite:interface>
        <composite:attribute name="value" required="true" />
        <composite:attribute name="disabled" required="false" default="false" />
    </composite:interface>

    <composite:implementation>
        <h:panelGrid columns="2" id="#{cc.id}">
            <p:spinner value="#{cc.attrs.value.value}" min="1"
                id="value_spinner" disabled="#{cc.attrs.disabled}" />
            <p:selectOneMenu value="#{cc.attrs.value.type}" style="width:200px"
                disabled="#{cc.attrs.disabled}">
                <f:selectItem noSelectionOption="true"
                    itemLabel="#{windowsMessages.NOT_ASSIGNED}" />
                <f:selectItems value="#{viewUtils.periodicityTypes}" />
            </p:selectOneMenu>
        </h:panelGrid>
    </composite:implementation>
</h:body>
</html>

Basically I have an spinner element and a selectOneMenu , in order to select a value and a type for the periodicity. There's also the chance not to select any type, in this case the input numeric value must be zero . Or, even better, if no periodicity selected the input must be converted into a null/null tuple .

As I read in some sites there's the chance to validate multiple JSF components at once accesing the id in the validation method:

UIInput confirmComponent = (UIInput) component.getAttributes().get("confirm");

Question is, how to adapt it in order to use in a composite component which doesn't have a fixed id?

One way would be to create a backing component extending UIInput and do the job in UIInput#getSubmittedValue() . The child inputs are just directly available by findComponent() .

<cc:interface componentType="inputPeriodicity">
    ...
</cc:interface>
<cc:implementation>
    ...
    <p:spinner id="value_spinner" ... />
    <p:selectOneMenu id="type_menu" ... />
    ...
</cc:implementation>

with

@FacesComponent("inputPeriodicity")
public class InputPeriodicity extends UIInput implements NamingContainer {

    @Override
    public String getFamily() {
        return UINamingContainer.COMPONENT_FAMILY;
    }

    @Override
    public Object getSubmittedValue() {
        UIInput typeMenu = (UIInput) findComponent("type_menu");
        String type = (String) typeMenu.getSubmittedValue();

        if (type == null || type.isEmpty()) {
            UIInput valueSpinner = (UIInput) findComponent("value_spinner");
            valueSpinner.setSubmittedValue("0"); // Don't use int/Integer here!
        }

        return super.getSubmittedValue();
    }

}

See also:


Unrelated to the concrete problem, the <h:panelGrid id="#{cc.id}"> really isn't right. Give it a fixed ID instead if you really need to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM