Howto validate an entity shared over multiple tabs

I am having an entity with many attributes which should be displayed in multiple tabs in a p:tabView. It might look like the following.

I have one h:form which surrounds the p:tabView. In the tabs I have a single p:message for every input element.

<p:column>
    <p:outputLabel value="Name" for="name_input" />
</p:column>
<p:column>
    <p:message for="name_input" display="icon" />
</p:column>
<p:column>
    <p:inputText id="name_input" value="#{bean.person.name}">
        <p:ajax /> <!-- put value into backingbean on tabchange -->
        <f:validateRequired />
    </p:inputText>
</p:column>

I have made the following observations.

1) Problem: validation is only executed in tabs which have been activated

  • If I switch to edit mode and the current tab has no validation errors and I do not change the tab, then my entity gets saved and validation error on other tabs are ignored.

  • If I switch to edit mode and navigate to a tab which has validation error and then navigate to the first tab with no validation error, then a vaidation error is displayed (but only from those tab, that I visited).

  • (I hope this is understandable, at least a little bit) It does not make a difference if I set dynamic=true/false and cache=false in the p:tabView.

2) Problem: no message icon on tab change

  • If I switch to edit mode and click on every tab so that every validation error are recognized (like in scenario b) I get a proper validation message (icon) and the p:inputText is displayed with a red border. So everything seems to be fine. But if I navigate to another tab with validation errors there is no message icon displayed, only the red border is around the particular p:inputText. As far as I would guess, the JSF lifecycle is executed on tab change but no validation takes place so for this lifecycle roundtrip everything is OK and the message icon disappears (on the other hand it is a mystery to me why the red border does not disappear...).

3) Problem: no visual hint in the tab

  • For the user experience I would very much like to have a visual hint (i. e. a red background on a tab-title) so that a user knows where the problems occur.

I have read Validating one form with multiple tabs, how to switch tabs without losing validation errors? Using Myfaces and Trinidad but neither the wizard (it is not a "wizardy" task it is just an edit of a big entity) nor the do-it-yourself-with-javascrip-and-css (main problem is the corporated identity I am using pretty often tabViews in other situations) is a good option for me.

Does anyone have a solution/hint for any of my problems?

I am using JSF 2.2, Primefaces 5.3.

Answers


OK, a colleague of mine came up with the answer.

First of all, my first two problems vanished into thin air. With the attributes dynamic="false" and cache="false" in the <p:tabView /> this works as desired (I do not know what I tested back then).

And the visual hint in the tab. There is a <f:facet name="title" /> which can be used to display the tab title and additional messages. The <p:message /> components are doubled, firstly inside the column at the input component and secondly in the title-facet. With a little CSS one can adjust the icons in the title at will.

<p:tabView dynamic="false" cache="false">
    <f:facet name="title">
        Address
        <p:message for="name_input" display="icon" />
    </f:facet>
    ...
    <p:panelGrid>
        <p:row>
            <p:column>
                <p:outputLabel value="Name" for="name_input" />
            </p:column>
            <p:column>
                <p:message for="name_input" display="icon" />
            </p:column>
            <p:column>
                <p:inputText id="name_input" value="#{bean.person.name}">
                    <p:ajax />
                    <f:validateRequired />
                </p:inputText>
            </p:column>
        </p:row>
        ....
    </p:panelGrid>
</p:tabView>

Need Your Help

How should I encrypt data to send in URL

c# encryption

I need to encrypt a string which I am sending in a URL and later I need to decrypt it ...

DateTime Comparison Precision

c# datetime comparison

I'm doing DateTime comparison but I don't want to do comparison at second, millisecond and ticks level. What's the most elegant way?