Search code examples
primefacesjsf-2.2omnifaces

Using Omnifaces validateAllOrNone component into ui:repeat


I have the following problem:

I try to use o:validateAllOrNone component into ui:repeat and it's work nice. But it doesn't work with my composite component.

My composite component it's really the simple p:inputText for comfortable input phone number. There I have used javascript which provides work with different phone numbers (inputPhoneNumber).

<p:inputText id="#{cc.attrs.id}" type="tel" label="Номер телефона" value="#{cc.attrs.value}" required="#{cc.attrs.required}"
             styleClass="#{cc.attrs.styleClass} m-pad-left50" style="#{cc.attrs.style}">
</p:inputText>

<script>
    $("#{cc.fullId}").intlTelInput(
        {
            utilsScript: "intl-tel-input/js/utils.js",
            autoHideDialCode: false,
            nationalMode: false,
            preferredCountries: [#{cc.preferredCountries}],
            onlyCountries: [#{cc.countries}],
            dropdownContainer: 'body'
        }
    );
</script>

Also I have the form to create contacts such as phone number, email, skype and et. The form allows to create list of contacts. And there I have used my composite component if category of contact is phone number else simple input text:

<ui:repeat value="#{bean.contacts}" var="contact">
    <p:selectOneMenu id="contact_type" value="#{contact.type}">
       ...
    </p:selectOneMenu>

    <p:outputPanel rendered="#{contact.category.equals(category.PHONE)}">
        <mycomponent:inputPhoneNumber id="contact_phone_value" value="#{contact.value}" preferred="ru">
        <o:validateAllOrNone components="contact_type contact_phone_value"/>
    </p:outputPanel>

    <p:outputPanel rendered="#{ne contact.category.equals(category.PHONE)}">
        <p:inputText id="contact_other_value" value="#{contact.value}"/>
        <o:validateAllOrNone components="contact_type contact_other_value"/>
    </p:outputPanel>
</ui:repeat>

I have used o:validateAllOrNone to check that contact type and his value not empty. It works for p:inputText but when I have tried to used this component for mycomponent:inputPhoneNumber I have caught the following exception:

Exception message: ValidateAllOrNone attribute 'components' must refer existing client IDs. Client ID 'contact_type' cannot be found.

I have found the question the question where I have known how to get full into ui:repeat. After that I have rewritten my code:

<ui:repeat id="contact_list" value="#{bean.contacts}" var="contact" varStatus="status">
    <p:selectOneMenu id="contact_type" value="#{contact.type}">
       ...
    </p:selectOneMenu>

    <p:outputPanel rendered="#{contact.category.equals(category.PHONE)}">
        <mycomponent:inputPhoneNumber id="contact_phone_value" value="#{contact.value}" preferred="ru">
        <o:validateAllOrNone components="contact_creation_form-contact_list-#{status.index}-contact_type contact_phone_value"/>
    </p:outputPanel>

    <p:outputPanel rendered="#{ne contact.category.equals(category.PHONE)}">
        <p:inputText id="contact_other_value" value="#{contact.value}"/>
        <o:validateAllOrNone components="contact_type contact_other_value"/>
    </p:outputPanel>
</ui:repeat>

Now I have put the correct id for contact type, but I caught the same exception:

Exception message: ValidateAllOrNone attribute 'components' must refer existing client IDs. Client ID 'contact_creation_form-list-2-contact_type' cannot be found.

How can I fix this proglem?


Solution

  • I should went from other side. It's easy to get the full id for the composite component and use it at o:validateAllOrNone. It fixed the problem. The correct id for composite component in this case it is contact_phone_value-contact_phone_value. After that code lookes like:

    <ui:repeat value="#{bean.contacts}" var="contact">
        <p:selectOneMenu id="contact_type" value="#{contact.type}">
           ...
        </p:selectOneMenu>
    
        <p:outputPanel rendered="#{contact.category.equals(category.PHONE)}">
            <mycomponent:inputPhoneNumber id="contact_phone_value" value="#{contact.value}" preferred="ru">
            <o:validateAllOrNone components="contact_type contact_phone_value-contact_phone_value"/>
        </p:outputPanel>
    
        <p:outputPanel rendered="#{ne contact.category.equals(category.PHONE)}">
            <p:inputText id="contact_other_value" value="#{contact.value}"/>
            <o:validateAllOrNone components="contact_type contact_other_value"/>
        </p:outputPanel>
    </ui:repeat>
    

    Also you should know that I use '-' instead ':' for id delimeter.