10 Replies Latest reply on May 24, 2010 4:13 PM by lee3star.lee3star.gmail.com

    How to bypass <s:validateAll>?

    namisandr

      How to bypass JSF validation phase (but apply model updates) on any ajax-enabled action except of form submit actions?


      E.g. if we have Add product form, we want to add product variants or product categories ajaxly without validating all Add product form, but validations must be processed when executing Save product action.

        • 1. Re: How to bypass <s:validateAll>?

          Join the club!.Best bet is to do it all on the client (with help from jQuery) and the submit it all in a single post in to the server for validation.

          • 2. Re: How to bypass <s:validateAll>?
            brandonsimpson

            I had the same problem and ended up writing my own validation and not using the built-in JSF/Hibernate validations. It's ugly, but I couldn't figure out a way to do what I wanted to do due to the inflexibility of the architecture. I hope the powers the be realize this in a future version because the current validation system does not work well with interactive pages. Furthermore, I don't even know if the whole concept of only updating model values and keeping a separate set of values in components is really needed. It also doesn't appear to work right with table values and neither does validation. So my solution wasn't as elegant, but at least it gets the job done. I only validate in my Save method and I also don't lose FacesMessages, etc. when interacting with the page. The validation checks only take place when I want them to and don't interfere with the normal page interactions. Best of luck to you, and if you find a better solution, please let me know.

            • 3. Re: How to bypass <s:validateAll>?
              abraao
              immediate="true"?
              • 4. Re: How to bypass <s:validateAll>?

                Abraao Isvi Oliveira Souza do Carmo wrote on May 11, 2009 19:52:


                immediate="true"?




                No... AFAIK immediate="true" will not do the trick, because the original request is:


                Lex Siman wrote:

                How to bypass JSF validation phase (but apply model updates) on any ajax-enabled action except of form submit actions?


                and AFAIK immediate="true" does not apply model updates.







                • 5. Re: How to bypass <s:validateAll>?
                  namisandr

                  You are right. immediate="true" is not the solution.


                  There is interesting article about JSF Lifecycle. And as we can see on Lifecycle diagram, immediate="true" skips Update model values phase. But even if we would have an ability to skip validation phase but apply Update models phase, there is also the problem about conversion of input values to models:



                  If the data cannot be converted to the types specified by the bean properties, the life cycle advances directly to the render response phase so that the page is re-rendered with errors displayed.

                  ...which means that action invocation will be skipped.


                  So the root of the skip validation problem is in JSF Lifecycle, which we cannot change (or can?). I cannot find any elegant way to make changes into JSF Lifecycle. And if we have such kind of problems, why do we need this JSF? Maybe to use Struts2 or any other action-based web framework?

                  • 6. Re: How to bypass <s:validateAll>?

                    Lex Siman wrote on May 12, 2009 16:19:


                    You are right. immediate="true" is not the solution.



                    I know



                    There is interesting article about JSF Lifecycle. And as we can see on Lifecycle diagram, immediate="true" skips Update model values phase. But even if we would have an ability to skip validation phase but apply Update models phase, there is also the problem about conversion of input values to models:

                    If the data cannot be converted to the types specified by the bean properties, the life cycle advances directly to the render response phase so that the page is re-rendered with errors displayed.



                    Correct.




                    ...which means that action invocation will be skipped.

                    So the root of the skip validation problem is in JSF Lifecycle, which we cannot change (or can?).




                    AFAIK we can not... but maybe?




                    I cannot find any elegant way to make changes into JSF Lifecycle. And if we have such kind of problems, why do we need this JSF? Maybe to use Struts2 or any other action-based web framework?



                    Same limitation there (in all serverside frameworks, action-based or not, unless you tell me they have a way of storing the string Jhon Smith in a variable of type Integer). I think the problem with Seam is that it mixes up unavoidable validation (like the impossiblity to store Strings in Integer variables) with the avoidable one (like writing an email without an @, it is certainly invalid, but it can be stored for a while in a String variable, until we decide to validate it at the end of the transaction.




                    One solution I have found is to use jQuery to do the unavoidable type violation kind of validation client-side, so that the server-side does not complain, and then do the avoidable validation programmatically server-side, at the end of the transaction.





                    Another solution is to remember that Seam is perfectly capable of binding you controls to a java.util.Map (DTOs are returing from the death as Maps). And then (manually) transfer that data into you @Entities, that way you skip unavoidable validation, because a String can store anything, and validate later, when transferring the data to your @Entities





                    • 7. Re: How to bypass <s:validateAll>?
                      namisandr

                      I don't understand your 1-st solution with jQuery. How do you bind JavaScript-generated inputs to JSF UI components and server models (backing beans)? Don't they lost after form submit? It would be nice if you provide us some source code about you jQuery solution.


                      The 2-nd solution is appropriate but very tricky.

                      • 8. Re: How to bypass <s:validateAll>?

                        Lex Siman wrote on May 12, 2009 22:33:


                        I don't understand your 1-st solution with jQuery. How do you bind JavaScript-generated inputs to JSF UI components and server models (backing beans)?



                        I let JSF do it the way it currently does, the only difference is that jQuery prevents the user from even typing John Smith in the field Number of cars you own:, because that field has the class integer and therefore jQuery blocks the keyboard from writing anything but a number. That means that JSF validation will always be successful, and so it will never issue a validation error (jQuery will prevent any invalid data from being written in the first place).



                        Of course, jQuery can not validate everything, I only use it to trick basic unavoidable JSF so that it is always happy (after all there is no way to save a non numeric string in to an Integer field). For more complex many fields or a query is required to know validations, I write my own custom code an call it before calling entityManager.persist.



                        Don't they lost after form submit? It would be nice if you provide us some source code about you jQuery solution.

                        The 2-nd solution is appropriate but very tricky.


                        • 9. Re: How to bypass <s:validateAll>?
                          swd847

                          You can play with the lifecycle a bit. It is possible to change the phase that commandbutton events are invoked in, so you can run an event before the validation failures kick in for instance.


                          using a4j:region you can also limit the components that are processed, sort of like a validation group. If you group all you 'Add Product' components into a a4j:region then this should do what you are after.

                          • 10. Re: How to bypass <s:validateAll>?
                            lee3star.lee3star.gmail.com

                            Thanks Stuart, that works!