Knockout Validation with Bootstrap Popover

I wanted to use Twitter’s Bootstrap Popover’s to let the user know they need to enter values into each of the form’s inputs.
On top of Knockout’s Validation, I decided to create a custom Knockout binding that allows me to check if the Knockout observable is valid and either show or hide the popover with the error message.

See the image below for the final result.

Example of KO Validation with Popover

The mark up is

1
2
3
4
5
6
7
 <div class="row">
                            <div class="col-xs-6">
                                <div class="form-group" data-bind="validationElement: item.notes">
                                    <textarea id="notes" rel="validatePopover" data-position="right" class="form-control input-sm" rows="3" placeholder="Notes ..." data-bind="value: item.notes, validationPopUp: item.notes"></textarea>
                                </div>
                            </div>
                        </div>

If you would like the knockout custom binding code, please visit Github.

Generic View Model under Knockout.js

I found that my problem on this particular project was having to generate knockout.js models from JSON data that was generated from ASP.NET MVC.   The back-end has several .NET classes, i.e viewdata classes that have several other classes, collections, properties etc. I wanted to treat the back-end as being the master of my model structure so I wouldn’t need to have the model duplicated in several different places through out the project. One of the elements in this problem is how to deal with creating knockout.js models with re-usable code.  The solution I went with was to create a generic JS wrapper that allowed me to pass in JSON and return me a knockout view model using the knockout.js JSON mapping class. This allowed me to use a re-usable wrapper to generate the model and keep the code consistent.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var genericDemo = genericDemo || {};

genericDemo = {
UpdateViewModel: function(data, viewModel) {
ko.mapping.fromJS(data, viewModel);
},
CreateViewModel: function (data, propertyName) {
var appViewModel = function(data)
{
var self = this;
self[propertyName] = ko.mapping.fromJS(data);
}
return new appViewModel(data);
}
};

And here is the implementation

1
2
3
4
5
//this allowed me to have several view models
var masterViewModel = function() { };
masterViewModel.genericDemoViewModel = genericDemo.Generic.CreateViewModel(@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.MyModelFromMVC)),"propertyname");

console.log(masterViewModel.genericDemoViewModel.propertyname.propertyFromMyMVCModel());