5

I have a form in a modal, the user has to complete the form (otherwise validation will display the required fields error messages), then click the submit input type, it does nothing, then they click it again, then it will post via ajax, and return a "thank you" message.

I have looked around Stackoverflow and applied answers to the problem I am having but I still can't get it to work. I did remove the event.preventDefault(); from it, as well as $("#review-form").submit(function(event) { and the form submits like it should after clicking the submit input once, but it doesn't post to the database.

Below is the jQuery for #review-form

$("#review-form").validate({
    submitHandler: function () {
        $("#review-form").submit(function (event) {
            var rating = $(this).find('input[name=rating]');
            // var rating = $(this).find('input[name=rating]').val();
            var review = $(this).find('textarea[name=review]');
            var form_settings = $(this).find('input[name=form_settings]');
            var xid = $(this).find('input[name=XID]');
            var entry_id = $(this).find('input[name=entry_id]');
            var entry_type = $(this).find('input[name=entry_type]');
            var site_id = $(this).find('input[name=site_id]');
            var first_name = $(this).find('input[name=first_name]');
            var middle_initial = $(this).find('input[name=middle_initial]');

            $.ajax({
                url: $("#review-form").attr("action"), //your server side script
                data: $(this).serialize(),
                type: 'POST',
                success: function (data) {
                    //$('#response').append('<li>' + data + '</li>');
                    $('#review-form').hide();
                    $('#review-form-response').html("<h3 style='text-align:center;'>Thank you, your review was submitted!</h3>");
                },
                error: function (jxhr, msg, err) {
                    $('#response').append('<li style="color:red">' + msg + '</li>');
                }
            });
            event.preventDefault();
        });
    }
});

UPDATE: I removed the $("#review-form").submit(function (event) { }); and I changed the $(this).find ... and retrieved by specifying the form's id of #form-review, then past thru the data parameter. I commented out all the individual variables and just passing $(this).serialize() into the data parameter and that did not work.

The below code works in chrome and firefox, but in firefox, it closes the modal and redirects to the domain's homepage, it should keep the modal open with a thank you msg, like it does in chrome:

$("#review-form").validate({
    submitHandler: function() {

         $.ajax({
             url: $("#review-form").attr("action"), //your server side script
             data: $("#review-form").serialize(),                
             type: 'POST',
             success: function (data) {
                 $('#review-form').hide();
                 $('#review-form-response').html("<h3 style='text-align:center;'>Thank you, your review was submitted!</h3>");
             },
             error: function (jxhr, msg, err) {
                 $('#response').append('<li style="color:red">' + msg + '</li>');
             }
         });

        event.preventDefault(); 
    }
});

Final working product:

$("#review-form").validate({
    submitHandler: function() {

         $.ajax({
             url: $("#review-form").attr("action"),
             data: $("#review-form").serialize(),
             type: 'POST',
             success: function (data) {
                 $('#review-form').hide();
                 $('#review-form-response').html("<h3 style='text-align:center;'>Thank you, your review was submitted!</h3>");
             },
             error: function (jxhr, msg, err) {
                 $('#response').append('<li style="color:red">' + msg + '</li>');
             }
         });
    }
});
Sparky
  • 98,165
  • 25
  • 199
  • 285
Brad
  • 12,054
  • 44
  • 118
  • 187
  • 2
    You definitely want to remove the `$("#review-form").submit` call as that is binding the submit handler on the first click, which is why you are getting the dead click. Are you getting any errors from your `$.ajax` call? – Evan Davis Dec 10 '13 at 14:22

3 Answers3

9

You are binding a new submit event handler, within submitHandler callback of the plugin. This handler won't fire right away because a submit event is already in progress.

You don't need it. The submitHandler callback will already preventDefault internally within plugin code

Remove this

$("#review-form").submit(function(event) { })

and keep all the code it contains directly within submitHandler

Since you are using serialize() for the data.... you don't need all the individual field variables you create either

charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • 1
    Important general knowledge note: not necessarily applicable here, but serialize() doesn't cover file inputs. – Ben Barden Dec 10 '13 at 14:35
  • I tried passing the serialized data like this: data: $(this).serialize(), and that did not work, updated my code explaining that. – Brad Dec 10 '13 at 14:52
  • 1
    add `form` as argmuent to submitHandler `submitHandler: function(form) {`...then can use `$(form).serailize()` – charlietfl Dec 10 '13 at 14:55
  • @charlietfl thanks, I added data: $("#review-form").serialize(), – Brad Dec 10 '13 at 15:07
  • @charlietfl updated code, posts data in firefox and chrome, but modal disappears in ff and redirects me to main index.php page of domain (ex: domain.com/index.php) – Brad Dec 10 '13 at 15:08
  • 1
    likely throwing javascript errors...you left in `evemt.preventDefault()` but `event` is undefined – charlietfl Dec 10 '13 at 15:26
2

I had the same issue and resolved it by adding the following to my validate:

$("#myform").validate({
  onfocusout: false
});

onfocusout will remove the focus from your form fields and submit button will work on the first click.

See more at https://jqueryvalidation.org/validate/

6dev6il6
  • 767
  • 2
  • 15
  • 34
1

This is how I deal with remote validation.

    if (form.find('[data-val-remote]').length > 0) {
        form.find('[type="submit"]').on("click enter", function (evt) {
            var interval = setInterval(function () {
                // keep check if there are any remote pending then prevent submit button from click
                if (Object.keys($('form').validate().pending).length) { 
                    evt.preventDefault();
                } else {
                 // if all remote responded then check form valid or not
                    if (!form.valid()) {
                 // if isvalid then stop interval
                        clearInterval(interval);
                    }
                 // if form valid then submit and stop interval
                    form.submit();
                    clearInterval(interval);
                }
            // loop 100ms
            }, 100);
            return false;
        });
    }