admin管理员组

文章数量:1026125

I am working on KnockOut validation and so far so good. I do have a question though. I have some code like the following:

 shippingMethodModel.Description.extend({ required: true });

And that shows a validation message below BUT does it set a flag or something which I can read to disable my save button?

I am working on KnockOut validation and so far so good. I do have a question though. I have some code like the following:

 shippingMethodModel.Description.extend({ required: true });

And that shows a validation message below BUT does it set a flag or something which I can read to disable my save button?

Share Improve this question edited Feb 19, 2013 at 1:19 KingPin 133 bronze badges asked Sep 12, 2012 at 19:40 LostLost 13.8k36 gold badges128 silver badges210 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 2

I had this same need recently, so I'll try to translate what I did based on the line of code you provided above...

Try adding a ko.puted observable similar to the following:

shippingMethodModel.formIsNotValid = ko.puted(function () {
    // original line
    // var errors = ko.utils.unwrapObservable(ko.validation.group(self));

    // ** oops, not "self" in this case

    // UPDATED line
    var errors = ko.utils.unwrapObservable(ko.validation.group(shippingMethodModel));
    return (errors.length > 0);
});

UPDATE I made a correction in the code above after noticing my error.

For those declaring such a model/class as a function all at once, this code may look similar to the following:

var ShippingMethodModel = function () {
    var self = this;
    self.shippingMethodId = ko.observable().extend({ required: true });
    self.description = ko.observable().extend({ required: true });

    self.formIsNotValid = ko.puted(function () {
        var errors = ko.utils.unwrapObservable(ko.validation.group(self));
        return (errors.length > 0);
    });
};

/UPDATE

UPDATE2 Based on input from @ericb in the ments below, I made a change to the way I'm implementing my own solution, which I'll demonstrate by adapting the example code in my update above:

var ShippingMethodModel = function () {
    var self = this;
    self.shippingMethodId = ko.observable().extend({ required: true });
    self.description = ko.observable().extend({ required: true });

    self.formIsNotValid = ko.observable(false);

    self.validateObservableFormField = function (nameOfObservableToValidate, 
                                                 data, event) {
        for (var prop in data) {
            if (prop === nameOfObservableToValidate) {
                var theObservable = data[prop];
                theObservable.valueHasMutated();
                ko.validation.validateObservable(theObservable);
                if (theObservable.error) {
                    self.formIsNotValid(true);
                }
                else {
                    if (self.formIsNotValid()) {
                        var errors = 
                            ko.utils.unwrapObservable(ko.validation.group(self));
                        self.formIsNotValid(errors.length > 0);
                    }
                }
                return;
            }
        }
    };        
};

Notice that I've now defined formIsNotValid as an observable, but I'm using the validateObservableFormField function to help me with pre-submit form validity determination. This change ensures that the ko.validation.group function is called only as needed, and that call should only be needed when the observable being validated is valid, but formIsNotValid is true (to handle the case where that current observable was the one that had set formIsNotValid to true).

Here's an example of how I'm doing this:

<input data-bind="value: description, 
                  event: { blur: function(data, event) {
                                     validateObservableFormField('facilityName', 
                                                                  data, 
                                                                  event) 
                                 }
                         }" />

goofy formatting to eliminate horizontal scroll

NOTE: I was already using this technique, but I've adapted it to improve the performance of checking whether or not the form is valid. @Californicated, I realized after my last ment that calling this function from the blur event of validated form fields is why I was seeing my save/submit button toggle between enabled and disabled states.

Thanks again to @ericb for the performance tip.

Further tips, from anyone, are always wele!

/UPDATE2

Once you've got that in place, disabling the button is a matter of binding to that formIsNotValid puted observable in whatever way makes sense for how you intend to disable the button, e.g. css: { 'ui-state-disabled': formIsNotValid } and/or disable: formIsNotValid and/or some other method(s).

Hope this helps, and let me know if you run into trouble.

I would setup the following:

saveEnabled = ko.puted(function(){
    // possible other logic
    return shippingMethodModel.Description.isValid();
});

and then in your HTML:

<button data-bind="enable: saveEnabled"> Save </button>

Or, if you have multiple properties on your model, you could do something like:

ko.validation.group(shippingMethodModel);

and then in your HTML:

<button data-bind="enable: isValid"> Save </button>

the group function adds an isValid property to whatever it groups.

I am working on KnockOut validation and so far so good. I do have a question though. I have some code like the following:

 shippingMethodModel.Description.extend({ required: true });

And that shows a validation message below BUT does it set a flag or something which I can read to disable my save button?

I am working on KnockOut validation and so far so good. I do have a question though. I have some code like the following:

 shippingMethodModel.Description.extend({ required: true });

And that shows a validation message below BUT does it set a flag or something which I can read to disable my save button?

Share Improve this question edited Feb 19, 2013 at 1:19 KingPin 133 bronze badges asked Sep 12, 2012 at 19:40 LostLost 13.8k36 gold badges128 silver badges210 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 2

I had this same need recently, so I'll try to translate what I did based on the line of code you provided above...

Try adding a ko.puted observable similar to the following:

shippingMethodModel.formIsNotValid = ko.puted(function () {
    // original line
    // var errors = ko.utils.unwrapObservable(ko.validation.group(self));

    // ** oops, not "self" in this case

    // UPDATED line
    var errors = ko.utils.unwrapObservable(ko.validation.group(shippingMethodModel));
    return (errors.length > 0);
});

UPDATE I made a correction in the code above after noticing my error.

For those declaring such a model/class as a function all at once, this code may look similar to the following:

var ShippingMethodModel = function () {
    var self = this;
    self.shippingMethodId = ko.observable().extend({ required: true });
    self.description = ko.observable().extend({ required: true });

    self.formIsNotValid = ko.puted(function () {
        var errors = ko.utils.unwrapObservable(ko.validation.group(self));
        return (errors.length > 0);
    });
};

/UPDATE

UPDATE2 Based on input from @ericb in the ments below, I made a change to the way I'm implementing my own solution, which I'll demonstrate by adapting the example code in my update above:

var ShippingMethodModel = function () {
    var self = this;
    self.shippingMethodId = ko.observable().extend({ required: true });
    self.description = ko.observable().extend({ required: true });

    self.formIsNotValid = ko.observable(false);

    self.validateObservableFormField = function (nameOfObservableToValidate, 
                                                 data, event) {
        for (var prop in data) {
            if (prop === nameOfObservableToValidate) {
                var theObservable = data[prop];
                theObservable.valueHasMutated();
                ko.validation.validateObservable(theObservable);
                if (theObservable.error) {
                    self.formIsNotValid(true);
                }
                else {
                    if (self.formIsNotValid()) {
                        var errors = 
                            ko.utils.unwrapObservable(ko.validation.group(self));
                        self.formIsNotValid(errors.length > 0);
                    }
                }
                return;
            }
        }
    };        
};

Notice that I've now defined formIsNotValid as an observable, but I'm using the validateObservableFormField function to help me with pre-submit form validity determination. This change ensures that the ko.validation.group function is called only as needed, and that call should only be needed when the observable being validated is valid, but formIsNotValid is true (to handle the case where that current observable was the one that had set formIsNotValid to true).

Here's an example of how I'm doing this:

<input data-bind="value: description, 
                  event: { blur: function(data, event) {
                                     validateObservableFormField('facilityName', 
                                                                  data, 
                                                                  event) 
                                 }
                         }" />

goofy formatting to eliminate horizontal scroll

NOTE: I was already using this technique, but I've adapted it to improve the performance of checking whether or not the form is valid. @Californicated, I realized after my last ment that calling this function from the blur event of validated form fields is why I was seeing my save/submit button toggle between enabled and disabled states.

Thanks again to @ericb for the performance tip.

Further tips, from anyone, are always wele!

/UPDATE2

Once you've got that in place, disabling the button is a matter of binding to that formIsNotValid puted observable in whatever way makes sense for how you intend to disable the button, e.g. css: { 'ui-state-disabled': formIsNotValid } and/or disable: formIsNotValid and/or some other method(s).

Hope this helps, and let me know if you run into trouble.

I would setup the following:

saveEnabled = ko.puted(function(){
    // possible other logic
    return shippingMethodModel.Description.isValid();
});

and then in your HTML:

<button data-bind="enable: saveEnabled"> Save </button>

Or, if you have multiple properties on your model, you could do something like:

ko.validation.group(shippingMethodModel);

and then in your HTML:

<button data-bind="enable: isValid"> Save </button>

the group function adds an isValid property to whatever it groups.

本文标签: javascriptKnockout validation beyond message displayStack Overflow