jsr372-experts@javaserverfaces-spec-public.java.net

[jsr372-experts] Re: [jsr372-experts mirror] Re: Concerns about validateWholeBean

From: arjan tijms <arjan.tijms_at_gmail.com>
Date: Tue, 9 Feb 2016 19:20:53 +0100

On Tue, Feb 9, 2016 at 6:31 PM, Michael Müller <
michael.mueller_at_mueller-bruehl.de> wrote:

> I don't understand you:
> If I omit the render attribute, it defaults to @this. Both fields are
> processed and validated well.
> Please explain, why you think, it wouldn't be processed.
>

I didn't read the entire conversation, but based on just this you have to
be aware that there are 2 attributes that play a role; *execute* and
*render* (note that they have slightly different names in PrimeFaces
components).

"execute" is about which (input) components get processed on the server.
With these you effectively create a sub-form post.

"render" is about which components get updated after processing and during
render response.

For instance, if you have input 1, input 2, and input 3, and (panel) group
A and B on your page view, then with an ajax request you can specify that
only input 1 and 3 are to be processed. It's as if input 2 simply didn't
exist. Then for after processing (converting, validating, calling the
model), you can say that only input 3 and group B are to be re-rendered.

The partial response in that case will only contain the updated markup for
input 3 and group B.

Confusingly, perhaps, is that due to what you may call a spec bug/oversight
in JSF 2, even when you specify that only input 1 and 3 are to be
processed, the jsf script will still send *all* inputs. E.g. the submit
(post) is still full. But then when this submit arrives at the server, the
runtime ignores input 2 from the request.

Maybe that's where the confusion comes from?

Manfred seems to be referring to the *execute* attribute of f:ajax here.

Kind regards,
Arjan Tijms







>
>
> Herzliche Grüße - Best Regards,
>
> Michael Müller
> Brühl, Germany
> blog.mueller-bruehl.de
> it-rezension.de
> @muellermi
>
>
> Read my books
> "Web Development with Java and JSF": <https://leanpub.com/jsf>
> https://leanpub.com/jsf
> "Java Lambdas und (parallel) Streams" Deutsche Ausgabe:
> <https://leanpub.com/lambdas-de>https://leanpub.com/lambdas-de
> "Java Lambdas and (parallel) Streams" English edition:
> <https://leanpub.com/lambdas>https://leanpub.com/lambdas
>
> Am 09.02.2016 um 16:30 schrieb manfred riem:
>
> Hi Michael,
>
> If you do not make sure the input field are part of the execute they won't
> get processed.
>
> Thanks!
>
> Kind regards,
> Manfred Riem
>
> On 2/8/16, 10:06 AM, Michael Müller wrote:
>
> Hi Manfred,
>
> Because I have some input fields nested in the f:ajax, every input
> triggers the partial request. Every field would be single validated. Can't
> we trigger the group validation (I prefer this to a whole bean validation)
> by the way?
>
> Or, if sombody likes to trigger the group validation independent from the
> single field trigger, then we need to define a special trigger condition.
> It shall not be triggered on submit of the form - this seems to be much too
> late. And not by hitting any button. Just when the user performed some
> input.
>
> Maybe
> <f:validationGroup group="..." trigger="...."/>
> A trigger condition might be "fieldA not empty and fieldB not empty"...
>
> To me, triggering the group validation togehter with the user input
> (ajaxified field) would fit.
>
> To my example: I just ried to wrap the whole thing into an f:ajax. Sine
> rendering tho whole div will destroy the focus, I prefer to ajaxify each
> single field:
>
> <="" h:inputtext=""> <="" h:inputtext=""> <h:message for="ageValidator"/>
> <h:inputText id="ageDays" value="#{grouper.ageDays}">
> <f:validateBean id="ageValidator"
> validationGroups="javax.validation.groups.Default,de.muellerbruehl.jsf23.Age"/>
> <f:ajax render="msgAgeDays ageValidator"
> validate="de.muellerbruehl.jsf23.Age"/>
> </h:inputText>
> <h:message id="msgAgeDays" for="ageDays"/>
>
> <h:inputText id="ageYears" value="#{grouper.ageYears}">
> <f:validateBean
> validationGroups="javax.validation.groups.Default,de.muellerbruehl.jsf23.Age"/>
> <f:ajax render="msgAgeYears ageValidator"
> validate="de.muellerbruehl.jsf23.Age"/>
> </h:inputText>
> <h:message id="msgAgeYears" for="ageYears"/>
>
> And writing down this example, I got the idea to add a validate attribute
> to the f:ajax. This way, the JSF user might trigger the multi field
> validation on his preferred place.
>
> Herzliche Grüße - Best Regards,
>
> Michael Müller
> Brühl, Germany
> blog.mueller-bruehl.de <http://blog.mueller-bruehl.de/>
> <http://blog.mueller-bruehl.de/>
> it-rezension.de <http://it-rezension.de/> <http://it-rezension.de/>
> @muellermi
>
>
> Read my books
> "Web Development with Java and JSF": https://leanpub.com/jsf
> "Java Lambdas und (parallel) Streams" Deutsche Ausgabe:
> https://leanpub.com/lambdas-de
> "Java Lambdas and (parallel) Streams" English edition:
> https://leanpub.com/lambdas
>
> Am 08.02.2016 um 16:43 schrieb manfred riem:
>
> Hi Michael,
>
> If you are using f:ajax you need to make sure you submit something. You
> cannot just have f:ajax do a re-render.
>
> Thanks!
>
> Kind regards,
> Manfred Riem
>
> On 2/7/16, 6:58 AM, Michael Müller wrote:
>
> Hi experts,
>
> In a real worl application hospitals and people of the healthcare sector
> have to report comprehensiove information to a central institute. For each
> domain the user might fullfill a form - from a handfull of input fields up
> to a tabbed page with several hundresds of fields or lists. Usuall it takes
> some time to fullfill such a form. Thus, the user may store the data at any
> time and continue after a break. Once he has finished, he "sends" the data
> to the institute.
>
> Some requirements:
> - provide the user straight feedback
> - offer or hide conditional fields depending on the previous user input
> - check the input, thus it is compatible to the database at any time
> - check the whole form whnen the user clicks onto the send button
>
> I made some tests, how to solve this with our new multi field validation.
>
> Provide straight feedback and store at any time needs to use ajax: Every
> single field is pushed into the model to store an intermediate version.
>
> And to provide straight feedback on conditional fields or interacting
> fields requires an immediate multi field validation. It seems (unless I did
> not understand it right), that we can't use validateWholeBean for this. As
> the name states, it validates the whole bean and not a single group. As a
> workarround I split the data and used multiple backing beans for a single
> form. I tried to validate just after the input using ajax. Sadly,
> validateWholeBeans became active only after clicking the submit button.
>
> Here an excerpt of the form:
>
> <div jsf:id="age">
> <f:ajax render="age">
> <h:message for="ageValidator"/>
> <h:inputText id="ageDays" value="#{grouper.ageDays}">
> <f:validateBean id="ageValidator"
> validationGroups="javax.validation.groups.Default,de.muellerbruehl.jsf23.Age"/>
> </h:inputText>
> <h:message for="ageDays"/>
>
> <h:inputText id="ageYears" value="#{grouper.ageYears}">
> <f:validateBean
> validationGroups="javax.validation.groups.Default,de.muellerbruehl.jsf23.Age"/>
> </h:inputText>
> <h:message for="ageYears"/>
> <f:validateWholeBean value="#{grouper}"
> validationGroups="de.muellerbruehl.jsf23.Age" id="ageValidator"/>
> </f:ajax>
> </div>
>
> <div jsf:id="email">
> <f:ajax render="emailValidator">
> <h:message for="ageValidator"/>
> <h:inputText value="#{emailBean.email1}">
> <f:validateBean
> validationGroups="javax.validation.groups.Default,de.muellerbruehl.jsf23.Email"/>
> </h:inputText>
>
> <h:inputText value="#{emailBean.email2}">
> <f:validateBean
> validationGroups="javax.validation.groups.Default,de.muellerbruehl.jsf23.Email"/>
> </h:inputText>
>
> <f:validateWholeBean value="#{emailBean}"
> validationGroups="de.muellerbruehl.jsf23.Email" id="emailValidator"/>
> </f:ajax>
> </div>
>
> <h:commandButton value="submit"/>
>
> No matter, whether I include the f:validateWholeBean into the f:ajax, it
> it validated on submit only.
>
> I propose to enhance the multi field validation:
>
> - let the user define a couple of multi field validation
> (f:validateWholeBean or a new tag like f:validateGroup)
> - if a single field of this group is validated, validate the whole group
> too (no matter whether the validateWholeBean is place into a f:ajax)
>
> or
> - add an attribute validateGroup="someGroup" to the f:validateBean tag,
> e.g.
> <f:validateBean
> validationGroups="javax.validation.groups.Default,de.muellerbruehl.jsf23.Email"
> validateGroup="de.muellerbruehl.jsf23.Email"/>
> - on a partial request (in case of ajax), if validateGroup is declared,
> create a temp. copy of the bean and perform a group validation for the
> declared group.
>
> What do you think about this?
>
>
> --
>
> Herzliche Grüße - Best Regards,
>
> Michael Müller
> Brühl, Germany
> blog.mueller-bruehl.de <http://blog.mueller-bruehl.de/>
> <http://blog.mueller-bruehl.de/>
> it-rezension.de <http://it-rezension.de/> <http://it-rezension.de/>
> @muellermi
>
>
> Read my books
> "Web Development with Java and JSF": https://leanpub.com/jsf
> "Java Lambdas und (parallel) Streams" Deutsche Ausgabe:
> https://leanpub.com/lambdas-de
> "Java Lambdas and (parallel) Streams" English edition:
> https://leanpub.com/lambdas
>
>
>
>
>
>