Search code examples
jsfeventsinheritanceprimefacescomposite-component

JSF Composite pass all events


I want to create my custom composite component in JSF (with primefaces) that shows a label in front of an input an adds a message at the end.

In order to do that here is my source code:

The composite:

<?xml version="1.0" encoding="UTF-8"?>
<!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:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:composite="http://java.sun.com/jsf/composite">
    <composite:interface componentType="customInput">
        <composite:attribute name="label" />
        <composite:attribute name="value" />
    </composite:interface>

    <composite:implementation>
        <h:panelGrid columns="3">
            <h:outputText value="#{cc.attrs.label}:" />
            <p:inputText id="abcde" value="#{cc.attrs.value}" />
            <p:message for="abcde" />
        </h:panelGrid>
    </composite:implementation>
</html>

The backing bean:

@FacesComponent(value = "customInput")
public class CustomInput extends InputText implements NamingContainer {
    @Override
    public String getFamily() {
        return UINamingContainer.COMPONENT_FAMILY;
    }
}

So far, so good. Now I want to use the events inherited by the p:inputText component. Like for example:

<pch2:PchInputText2 label="Name" id="test2" value="#{testBean.test}">
    <p:ajax event="blur" listener="#{chantierFormBean.updateMap()}" />
    <p:ajax event="change" listener="#{chantierFormBean.updateMap()}" />
</pch2:PchInputText2>

I know that I could pass these events by adding

<composite:clientBehavior name="change" event="change" targets="abcde" />

to the composite:interface part, but then I have to add one client behavior for every event (in the future). Isn't there a method to pass all events inherited by the primefaces inputtext?

Thanks in advance


Solution

  • That's not possible.

    A composite is in first place not the right tool for this job. It's not primarily intented to DRY out and refactor repeated XHTML code. It's intented to create a whole new (input) component tied to a single model value. For example, a <p:fileUpload> and <p:imageCropper> togeher which is tied to a single com.example.Image property. Or three <p:selectOneMenu> together which is tied to a single java.time.LocalDate property.

    Use a tagfile instead.

    <ui:composition ...>
        <h:outputLabel for="#{id}" value="#{label}:" />
        <p:inputText id="#{id}" value="#{value}">
            <ui:insert />
        </p:inputText>
        <p:message for="#{id}" />
    </ui:composition>
    

    See also: