Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jquery validation: call ajax and close bootstrap modal form after entire form validates

I'm using Bootstrap layout and the jQuery Validation Plugin. I click on a button, a modal with the form opens. The user inputs some data and improves it until everything is correct. When he submits it, it should make ajax call and close the modal form (but if the validation fails, there should be no ajax and no modal closing). Below is my code:

ajax call

$('#outcomeFormDialog form').on( "submit", function( event ) {
    var form = $(this);
    $.ajax({
        type: form.attr('method'),
        url: "../php/client/json.php",
        data: form.serialize(),
        success: function(data, status) {
            $(this).modal('hide');
        }
    });

    event.preventDefault();
});

current validation code:

 $('#outcomeFormDialog form').validate(
 {
  rules: {
    amount: {
      money: true,
      required: true
    },
    comment: {
      required: false
    }
  },
  highlight: function(element) {
    $(element).closest('.control-group')
    .removeClass('success').addClass('error');
  },
  success: function(element) {
    element
    .addClass('valid').closest('.control-group')
    .removeClass('error').addClass('success');
  }
 });

As far as I understood, jquery validation's success corresponds to each form element rather than entire form - so checking entire form validation should be done some other way.

This is my form (mustache-driven):

<div id="outcomeFormDialog" class="modal hide fade" role="dialog">
    <form class="form-horizontal well" data-async data-target="#outcomeFormDialog" method="POST">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal">×</button>
            <h3 id="myModalLabel">Add outcome</h3>
        </div>
        <div class="modal-body">
            <fieldset>
                <input name="type" type="hidden" value="add_outcome" />
                <div class="control-group">
                    <label class="control-label" for="amount">Amount</label>
                    <div class="controls">
                        <div class="input-prepend">
                            <span class="add-on">{{ currency }}</span>
                            <input type="text" name="amount" class="input-xlarge" placeholder="00.01" />
                        </div>
                    </div>
                </div>
                <div class="control-group">
                    <label class="control-label" for="comment">Comment</label>
                    <div class="controls">
                        <input type="text" name="comment" class="input-xlarge" placeholder="Comment here..." />
                    </div>
                </div>
            </fieldset>
        </div>
        <div class="modal-footer">
            <button class="btn" data-dismiss="modal">Close</button>
            <button type="submit" class="btn btn-primary">Save outcome</button>
        </div>
    </form>
</div>
like image 626
ducin Avatar asked Jan 14 '23 19:01

ducin


1 Answers

You have a couple popular issues and misconceptions regarding this plugin:

  • You do not need a submit handler. The click event of the submit button is automatically captured and handled by this plugin.

  • As per the docs, you are supposed to put your ajax within the plugin's submitHandler callback option.

submitHandler: Callback, Default: default (native) form submit

Callback for handling the actual submit when the form is valid. Gets the form as the only argument. Replaces the default submit. The right place to submit a form via Ajax after it validated.

Assuming your ajax is written properly, re-arrange your code into something more like this:

$(document).ready(function () {

    $('#outcomeFormDialog form').validate({  // initialize plugin
        rules: {
            amount: {
                // money: true, //<-- no such rule
                required: true
            },
            comment: {
                required: false // superfluous; "false" same as leaving this rule out.
            }
        },
        highlight: function (element) {
            $(element).closest('.control-group')
                .removeClass('success').addClass('error');
        },
        success: function (element) {
            element.addClass('valid').closest('.control-group')
                .removeClass('error').addClass('success');
        },
        submitHandler: function (form) {
            // form validates so do the ajax
            $.ajax({
                type: $(form).attr('method'),
                url: "../php/client/json.php",
                data: $(form).serialize(),
                success: function (data, status) {
                    // ajax done
                    // do whatever & close the modal
                    $(this).modal('hide');
                }
            });
            return false; // ajax used, block the normal submit
        }
    });

});

Working DEMO: http://jsfiddle.net/duAkn/

like image 68
Sparky Avatar answered Jan 19 '23 12:01

Sparky