Simon Miller Team : Web Development Tags : Web Development Tips & Tricks

Two handy tricks in KnockoutJS

Simon Miller Team : Web Development Tags : Web Development Tips & Tricks

KnockoutJS is a powerful MVVM (Model-View-View Model) pattern built on JavaScript and otherwise server-language agnostic. It is popular due to how it automatically updates the UI when the data in your model changes. I have worked on a few projects so far with it, and while my own personal jury is still out on the overall technology I have learned a couple of tricks that have made my life easier when working with its form validation.

These apply to the view model definitions.

Conditional validation

I needed to implement form logic that only applied when certain criteria was met. Thankfully this functionality is baked into the framework. See this example.

 
            self.Phone.extend({
                required: {
                    message: "At least one phone number is required",
                    onlyIf: function () { return (ko.validation.utils.isEmptyVal(self.Mobile())); }
                }
            });

            self.Mobile.extend({
                required: {
                    message: "At least one phone number is required",
                    onlyIf: function () { return (ko.validation.utils.isEmptyVal(self.Phone())); }
                }
            });



I needed to ensure that the Phone field or the Mobile field were completed, but not necessarily both were required. There are two pieces to the puzzle above. Firstly, the required parameter has an optional onlyIf function that, as the name suggests, will only fire when conditions are met – in this case the Mobile field is only required when Phone is not supplied, and vice-verca. The second part of this technique is how to check for null values correctly – the ko.validation.utils library function isEmptyVal() sees to this, must like string.IsNullOrEmpty works in .NET

Select box defaults

I had an issue involving validation on select menus / drop down lists automatically firing as required when the page loaded, and not when the form was submitted. This of course is not ideal, and seemed like something obvious was wrong. It comes down to three things; your view, your model declaration and your validation.


The HTML on the view needs the parameter optionsCaption supplied. This provides the default placeholder value for the drop down box:

<select name="BillingTitle" data-bind="
                        options: titleOptions, 
                        value: BillingTitle,
                        optionsCaption: 'Choose...'
                        " />

The default model value must be set to empty string, like so:

newCheckoutModel = {
Email: null,
Phone: null,
Mobile: null,
BillingTitle: "",
...
                };

And lastly, the validation of the select box must be marked observable so that a watch is kept on the value in its initial empty state.

 
self.BillingTitle = ko.observable(undefined).extend({ required:  true });


With all three in place, you have a select box that is required, has a placeholder value and will not fire validation until it’s told to.