views:

15551

answers:

4

I am trying to make work the Validation plugin. It works fine for individual field but when I try to include the demo code for the error container that contain all errors I have an issue. The problem is that it show the container with all error when I am in all fields BUT I would like to display the error container only when the user press Submit (but still show inline error beside the control when losing focus).

The problem now once mixed up with some answer below:

The problem is the message in the container, when I took off the code as mentionned in the answer below for the container, the container output is just a plain text displaying the number of error. What is the trick to get a list of detailled error message?

What I would like is to display "ERROR" next of the control in error when the user press TAB and to have a summary of everything at the end when he press Submit... is that possible?

Code with all input from here:

    $().ready(function() {
        var container = $('div.containererreurtotal');



        // validate signup form on keyup and submit
  $("#frmEnregistrer").bind("invalid-form.validate", function(e, validator) {
    var err = validator.numberOfInvalids();
    if (err) {
      container.html("THERE ARE "+ err + " ERRORS IN THE FORM")
      container.show();
    } else {
      container.hide();
    }
  }).validate({
                    rules: {
                            nickname_in: {
                                 required: true,
            minLength: 4
                            },
                            prenom_in: {
                                 required: true,
            minLength: 4
                            },
                            nom_in: {
                                 required: true,
            minLength: 4
                            },
                            password_in: {
                                 required: true,
            minLength: 4
                            },
                            courriel_in: {
                                    required: true,
                                    email: true
                            },
                            userdigit: {
                                    required: true
                            }
                    },
                    messages: {
                            nickname_in: "ERROR",
                            prenom_in: "ERROR",
                            nom_in: "ERROR",
                            password_in: "ERROR",
                            courriel_in: "ERROR",
                            userdigit: "ERROR"
                    }

                    ,errorPlacement: function(error, element){
                            container.append(error.clone());
                            error.insertAfter(element);
                    }

            });
    });
A: 

I don't know if the validation plugin provides an option for this, but you can probably use standard jQuery to achieve what you want. Make sure you're container is initially hidden, by setting the display style to none:

<div id="container" style="display:none;"></div>

Then you can hookup an onsubmit event to the form which will make the container visible as soon as an attempt is made to submit the form:

jQuery('#formId').onsubmit(function() {
    // This will be called before the form is submitted
    jQuery('#container').show();
});

Hopefully combining that with your existing code should do the trick.

Doesnt't work, thx for trying
Daok
+1  A: 

I would remove the errorContainer and then intercept the validation on postback and in there add a container-error manually like this:

$("#frmEnregistrer").bind("invalid-form.validate", function(e, validator) {
  var err = validator.numberOfInvalids();
  if (err) {
    container.html("THERE ARE "+ err + " ERRORS IN THE FORM")
    container.show();
  } else {
    container.hide();
  }
}).validate({ ... })
Ok this is the effect I want for the container, still one problem is the container display because if I want the ERROR next to the control, I have to use "Serhii" code and it remove the formating inside the container...
Daok
+4  A: 

You will find the documentation for the meta option in http://docs.jquery.com/Plugins/Validation/validate#toptions

If you want to display the errors beside the inputs AND in a separate error container you will need to override the errorPlacement callback.

From your example:

...
                    courriel_in: "ERROR",
                    userdigit: "ERROR"
            }
            ,errorContainer: container

            ,errorPlacement: function(error, element){
                var errorClone = error.clone();
          container.append(errorClone);
    error.insertAfter(element)    
            }

            // We don't need this options
            //,errorLabelContainer: $("ol", container)
            //,wrapper: 'li'
            //,meta: "validate"
    });
 ...

The error parameter is a jQuery object containing a <label> tag. The element parameter is the input that has failed validation.

Update to comments

With the above code the error container will not clear errors because it contains a cloned copy. It's easy to solve this if jQuery gives a "hide" event, but it doesn't exist. Let's add a hide event!

  1. First we need the AOP plugin
  2. We add an advice for the hide method:

       jQuery.aop.before({target: jQuery.fn, method: "hide"},
        function(){
         this.trigger("hide");
        });
    
  3. We bind the hide event to hide the cloned error:

            ...
            ,errorPlacement: function(error, element){
                var errorClone = error.clone();
       container.append(errorClone);
       error.insertAfter(element).bind("hide", function(){
        errorClone.hide();
       });
      }
            ...
    

Give it a try

Serhii
Doesn't work because when the error is removed the error in the container still stay there. But you gave me some good input... +1
Daok
+5  A: 

First your container should be using an ID instead of a class.. (I'm going to assume that ID is 'containererreurtotal')

Then Try this..

    $().ready(function() {

        $('div#containererreurtotal').hide();

        // validate signup form on keyup and submit
        $("#frmEnregistrer").validate({
            errorLabelContainer: "#containererreurtotal",
            wrapper: "p",
            errorClass: "error",
            rules: {
                nickname_in: { required: true, minLength: 4 },
                prenom_in: { required: true, minLength: 4 },
                nom_in: { required: true, minLength: 4 },
                password_in: { required: true, minLength: 4 },
                courriel_in: { required: true,  email: true },
                userdigit: { required: true }
            },
            messages: { 
                nickname_in: { required: "Nickname required!", minLength: "Nickname too short!" },
                prenom_in: { required: "Prenom required!", minLength: "Prenom too short!" },
                nom_in: { required: "Nom required!", minLength: "Nom too short!" },
                password_in: { required: "Password required!", minLength: "Password too short!" },
                courriel_in: { required: "Courriel required!", email: "Courriel must be an Email" },
                userdigit: { required: "UserDigit required!" }
            },
            invalidHandler: function(form, validator) {
                $("#containererreurtotal").show();
            },
            unhighlight: function(element, errorClass) {
                if (this.numberOfInvalids() == 0) {
                    $("#containererreurtotal").hide();
                }
                $(element).removeClass(errorClass);
            }    

        });
    });

I am assuming here that you want a <p> tag around each of the individual errors. Typically I use a <ul> container for the actual container (instead of the div you used called 'containererreurtotal') and a <li> for each error (this element is specified in the "wrapper" line)

If you specify #containererreurtotal as display: none; in your CSS, then you dont need the first line in the ready function ( $('div#containererreurtotal').hide(); )

FerrousOxide
Thanks FerrousOxide,your answer helped me too. :)
Gaurav Sharma
thx FerrousOxide you make me solve a huge problem :)
frabiacca