RubbleFord
RubbleFord

Reputation: 7646

Knockout + Jquery Validate

I'm trying to setup validation with jquery validate, and i've got the viewmodel coming back from the server, mapped to the client and successfully have knockout js binding some data.

I included a called to validate but the validation never triggers, however if I put a class on the input box and then call valid it triggers as expected.

Any ideas?

<script type="text/javascript">
        var viewModel;
        $(document).ready(function () {
            $.ajax({
                url: 'Home/GetUserData',
                type: 'post',
                success: function (data) {
                    viewModel = ko.mapping.fromJS(data);
                    viewModel.save = function () { sendToServer(); };
                    ko.applyBindings(viewModel);
                    main();
                }
            });
        });

        function main() {
            $("form").validate({
                rules: {
                    birthPlace: {
                        required: true,
                        minlength: 2
                    }
                }
            });
        }

        function sendToServer() {
            alert($("form").valid());
        }

    </script>
}
<h2>@ViewBag.Message</h2>
<form id="nameSubmit" action="">
    <div>
        The name is: <span id="test" data-bind="text: Name"></span>
    </div>
    <div>
        He's <span id="age" data-bind="text: Age"></span>
    </div>
    <div>
        He's from
        <input type="text" id="birthPlace" name="birthPlace"/>
    </div>
    <div>
        <button data-bind="click: save">Click Me</button>
    </div>
</form>

Upvotes: 20

Views: 25997

Answers (5)

Gudlaugur Egilsson
Gudlaugur Egilsson

Reputation: 2460

I'd like to recommend against using jQuery validate with knockout. The reason is that jQuery validate binds to the DOM, while knockout recommends working with the view model. This will lead to problems once you start adding more dependencies on the validation, such as preventing certain behavior if data is invalid, but you still need to retain the data. Go for knockout validation, it does the job very well.

Upvotes: 11

Richard
Richard

Reputation: 4840

There is now a knockout jQuery validate binding, which I find very useful:

https://github.com/Knockout-Contrib/Knockout-Validation

Upvotes: 18

MikeBeaton
MikeBeaton

Reputation: 3890

It is correct that jQuery Validation only does its validation on the form submit event (as per Ryley's answer). So if you use Knockout style data-bind="click:modelSubmit" this will prevent the form submit from firing (by default) and so prevent jQuery Validation from doing anything.

You have two options. The first is to return true from modelSubmit(), which will make Knockout fire the form submit (but only after modelSubmit has finished) (http://knockoutjs.com/documentation/click-binding.html).

The second - and most likely what you want - is to leave off data-bind="click" altogether and use a jQuery Validation submit handler instead (https://jqueryvalidation.org/validate).

$("#myform").validate({
    submitHandler: function(form) {
        viewModel.modelSubmit();
    }
});

This handler only gets called once the validation has succeeded.

Upvotes: 1

craigb
craigb

Reputation: 16907

I've been using the submitHandler option on validate():

$("#myform").validate({
 submitHandler: function(form) {
   viewModel.sendToServer()
 }
});

On the form, just use a standard <input type="submit"> and jQuery validation will pick up the event, validate, and if valid will call your handler on the viewModel.

Upvotes: 2

Ryley
Ryley

Reputation: 21226

By default jQuery Validate does it's validation on submit. So if knockout is interrupting that, i.e. by not actually triggering the onSubmit event, that would do it. Your best bet may be to do as you were somewhat planning there in your sendToServer function - manually trigger the validation from your knockout submit event:

if (!$('form').valid()){
    $('form').showErrors();
    return false;
}

//otherwise, get on with whatever knockout needs to do
...
return true;

Upvotes: 25

Related Questions