Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout.js validation using extenders - prevent validation on load

I have implemented a very basic required validation on "first name" largely based on the example suggested on knockout website (http://knockoutjs.com/documentation/extenders.html) - Live example 2: Adding validation to an observable.

My problem is that I don't want the validation to fire when the form is first loaded. Below is my code

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
<link href="Style.css" rel="stylesheet" />
</head>
<body>
<p data-bind="css: { error: firstName.hasError }">
    <span>First Name</span>
    <input data-bind='value: firstName, valueUpdate: "afterkeydown"' />
    <span data-bind='visible: firstName.hasError, text: firstName.validationMessage'></span>
</p>
<p>
    <span>Last Name</span>
    <input type="text" data-bind="value: lastName, valueUpdate: 'afterkeydown'" />
</p>

<div data-bind="text: fullName" />
<script src="Scripts/jquery-2.0.3.js"></script>
<script src="Scripts/knockout-2.3.0.debug.js"></script>
<script src="script.js"></script>
</body>
</html>

var AppViewModel = function () {
var firstName = ko.observable().extend({ required: "Please enter First Name" }),
    lastName = ko.observable(),
    fullName = ko.computed(function () {
        return firstName() + " " + lastName();
    });
return {
    firstName: firstName,
    lastName: lastName,
    fullName: fullName
};
};


ko.extenders.required = function (target, overrideMessage) {
//add some sub-observables to our observable
target.hasError = ko.observable();
target.validationMessage = ko.observable();

//define a function to do validation
function validate(newValue) {

    target.hasError($.trim(newValue) ? false : true);
    target.validationMessage($.trim(newValue) ? "" : overrideMessage || "This field is    required");
}

//initial validation
validate(target());

//validate whenever the value changes
target.subscribe(validate);

//return the original observable
return target;
};



var viewModel = new AppViewModel();
ko.applyBindings(viewModel);

You will see the demo of issue I am facing at this link http://jsfiddle.net/tCP62/22/``

Please Note that the JSFiddle link that i have provided to demo showing the problem - works in "Chrome" and does not work in IE.

Please can anyone help me resolve this.

Regards, Ankush

like image 741
ankush.net Avatar asked Oct 21 '22 05:10

ankush.net


1 Answers

Just get rid of the following line and it should do what you want:

//initial validation
validate(target());

The required extender gets called when your page loads, and because it contains the above call, it causes the validation to trigger immediately. The next line of code target.subscribe(validate); ensures that it is triggered when the observable changes value (as stated by the comment). And that's all you need in this case.

like image 135
Robbie Avatar answered Nov 02 '22 07:11

Robbie