david-l david-l - 4 months ago 83
Javascript Question

jQuery .validate() submitHandler not firing

I'm loading a dialog box with a form that's built on-the-fly using Bootbox.js and I'm validating user input with a jQuery validate plugin.

Validation works just fine, but the

submitHandler
is ignored when the form is filled in successfully.

What's going wrong?

submitHandler: function(form) {
alert("Submitted!");
var $form = $(form);
$form.submit();
}


See the full example below. I've looked at other posts where a similar issue has been raised. Unfortunately they seem to have the form rendered on the page whereas I'm rendering my via jQuery.



$(document).on("click", "[data-toggle=\"contactAdmin\"]", function() {
bootbox.dialog({
title: "Contact admin",
buttons: {
close: {
label: 'Close',
className: "btn btn-sm btn-danger",
callback: function() {}
},
success: {
label: "Submit",
className: "btn btn-sm btn-primary",
callback: function() {
$("#webteamContactForm").validate({
rules: {
requestType: {
required: true
}
},
messages: {
requestType: {
required: "Please specify what your request is for",
}
},
highlight: function(a) {
$(a).closest(".form-group").addClass("has-error");
},
unhighlight: function(a) {
$(a).closest(".form-group").removeClass("has-error");
},
errorElement: "span",
errorClass: "help-blocks",
errorPlacement: function(error, element) {
if (element.is(":radio")) {
error.appendTo(element.parents('.requestTypeGroup'));
} else { // This is the default behavior
error.insertAfter(element);
}
},
submitHandler: function(form) {
alert("Submitted!");
var $form = $(form);
$form.submit();
}
}).form();
return false;
}
}
},
message: '<div class="row"> ' +
'<div class="col-md-12"> ' +
'<form id="webteamContactForm" class="form-horizontal" method="post"> ' +
'<p>Please get in touch if you wish to delete this content</p>' +
'<div class="form-group"> ' +
'<div class="col-md-12"> ' +
'<textarea id="message" name="message" class="form-control input-md" rows="3" cols="50">This email is to notify you the creator is putting a request for the following item\n\n' +
this.attributes.getNamedItem("data-url").value + '\n\n' + '</textarea> ' +
'<span class="help-block">Feel free to change the message and add more information. Please ensure you always provide the link.</span> </div> ' +
'</div> ' +
'<div class="form-group requestTypeGroup"> ' +
'<label class="col-md-4 control-label" for="requestType">This request is for:</label> ' +
'<div class="col-md-4"> <div class="radio"> <label for="Edit"> ' +
'<input type="radio" name="requestType" id="requestType-0" value="Edit"> ' +
'Editing </label> ' +
'</div><div class="radio"> <label for="Delete"> ' +
'<input type="radio" name="requestType" id="requestType-1" value="Delete"> Deletion</label> ' +
'</div> ' +
'</div> </div>' +
'</form> </div> </div>'
});
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/jquery.validate.js"></script>

<a data-toggle="contactAdmin" data-title="help" data-url="http:/www.mydomain.com/some-url" href="#">Contact Web team</a>





View on jsFiddle

Answer

Inspecting the DOM of the jsFiddle and two problems become apparent.

  1. Your "submit" <button> is a type="button".

  2. Your "submit" button is outside of the <form></form> container.

If you want the jQuery Validate plugin to automatically capture the click event of the "submit" button...

  • the button must be a type="submit"
  • The button must be within the <form></form> container.

These two conditions must be met if you want the plugin to operate as intended.


You've also incorrectly placed the .validate() method within the success callback of your modal dialog box "submit" button.

The .validate() method is only used for initializing the plugin and should be called once after the form is created.


EDIT:

After playing around with this, it becomes apparent that the Bootbox modal plugin may have some critical limitations that interfere with the submission of the form.

  1. I am initializing the Validate plugin after the dialog is opened.

  2. I am using the .valid() method within the "submit" to trigger the validation test.

I can get validation initialized and working as it should, but the dialog is dismissed before the actual form submission takes place. Perhaps there is a solution, but after reviewing the documentation for Bootbox, it's not readily apparent.

https://jsfiddle.net/vyaw3ucd/2/


EDIT 2:

As per the OP's solution...

bootbox.dialog({
    // other options,
    buttons: {
        success: {
            label: "Submit",
            className: "btn btn-sm btn-primary",
            callback: function () {
                if ($("#webteamContactForm").valid()) {
                    var form = $("#webteamContactForm");
                    form.submit();  // form submits and dialog closes
                } else {
                    return false;  // keeps dialog open
                }
            }
        }
    }
});

However, by simply using the supplied form argument directly, you do not have any errors when using the submitHandler option of the jQuery Validate plugin.

submitHandler: function (form) {
    console.log("Submitted!");
    form.submit();
}

DEMO: https://jsfiddle.net/vyaw3ucd/5/