Archive for category KnockoutJS

KnockoutJS custom binding to handle ISO to UK dates

Date’s are a nightmare in code- especially when crossing technology boundaries when posting data from C# to Javascript using JSON- the ambiguity caused by the UK date format (dd/mm/yyyy… or is it mm/dd/yyyy) so I stick to using the ISO 8601 format (yyyy-mm-dd hh:mm:ss) however user’s hate this. To overcome this problem I wrote a knockout binder which keeps the view model in the ISO format but renders the date in UK format and allows the user to interact with it in this format.

Here’s the code..


ko.bindingHandlers.isoToUKDate = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var underlyingObservable = valueAccessor();

        var interceptor = ko.computed({
            read: function () {
                var momentDate = null;

                if (typeof (underlyingObservable) !== 'function')
                {
                    momentDate = moment(underlyingObservable, 'YYYY-MM-DD');
                    console.log(underlyingObservable);
                }
                else
                {
                    momentDate = moment(underlyingObservable(), 'YYYY-MM-DD');
                    console.log(underlyingObservable());
                }

                if (momentDate !== null && momentDate.isValid())
                    return momentDate.format('DD/MM/YYYY');
            },

            write: function (newValue) {
                var current = underlyingObservable(),
                    valueToWrite = moment(newValue, 'DD/MM/YYYY').format('YYYY-MM-DD');

                if (valueToWrite !== current) {
                    underlyingObservable(valueToWrite);
                    underlyingObservable.valueHasMutated();
                }
            }
        });

        ko.applyBindingsToNode(element, { value: interceptor, text: interceptor });
    }
};

It’s usage is easy…


<input data-bind="isoToUKDate: MyDate" /> <!-- A writeable form field -->
<span data-bind="isoToUKDate: MyDate" /> <!-- A read only piece of html -->

No Comments

JQuery Validate() method for JQueryUI AutoComplete drop down boxes, while using KnockoutJS

It seems to be a rare mix, but on my form I have fields which are bound at client side using KnockoutJS, in drop downs styled using jQueryUI, using the expirmental autoComplete variant, which I then want to validate using jquery Validate method, to ensure someone actually selects something from the drop down!

So my form field looks like this;

<select data-bind='options: lookUps.Titles, optionsCaption: "Select...", value: Title, uniqueName: true'></select>

I have the following javascript to add the combobox autocomplete functionality;

 $("select").combobox({
                selected: function (event, ui) {
                    $(ui.item.parentNode).change();
                }
            });

Again, you’ll notice there’s another hack here to make everything play together nicly (see my blog post here)

Finally, the validation fix;

$.validator.addMethod('selectValueSelected',
          function(value, element) {
              return this.optional(element) ||
                (value.indexOf("__ko.bindingHandlers.options.optionValueDomData__") == -1);
          }, "Please select an option");
        $.validator.addClassRules("mustPopulateDropdown", {
            selectValueSelected: true
        });

All you need do now is add the css class “mustPopulateDropdown” to your select tags and they will be validated.

1 Comment

KnockoutJS won’t bind to fields with numbers at the end?

Maybe this is just me? Almost finished my Sales Entry form I’ve been tinkering with- adding a “Create Customer” dialogue, and every field bound as it should (using Knockout) except for 3; Address1, Address2 and Address3. The moment I changed Address1 to AddressHouseNumber, it started working- so i changed the other, and sure enough they all started working. I tripple checked for typo’s so it wasn’t that- the input fields looked like this;

<input data-bind="value: Address1, uniqueName: true" class=""/>
<input data-bind="value: Address2, uniqueName: true" class=""/>
<input data-bind="value: Address3, uniqueName: true" class=""/>

Weird! has any one else come across something like this?

2 Comments

KnockoutJS/ jQuery tmpl with jQuery Validate

Quick post; I found tonight that my jquery validate was letting my knockoutjs viewModel.save() method run, even if the form wasn’t valid. This turned out to be because you need to set “uniqueName: true” on any form fields you want validated. Eg

<input data-bind="value: ChargedShipping, uniqueName: true" class="required number"/>

1 Comment

Using JQueryUI combobox() with KnockoutJS

This is something I had a great deal of trouble with, but in the end the solution was simple. Basically when using the combobox() autocomplete drop down in jQueryUI (in prototype at time of writing) along side KnockoutJS I found changing your selection in the drop down list didn’t update the viewModel in knockout as expected. This is because knockoutjs attached itself to the change() event of the drop down, and jqueryUI wasn’t raising this event when it changed the drop down. This is easily fixed by adding an event handler to thre jqueryUI combobox which forces the event to be called when the user selects a new option;

$("select").combobox({
            selected: function(event, ui) { 
                $(ui.item.parentNode).change();
            }
        });

Thanks go out to the “Rob on programming” blog, which helped me get my head around what was going on in the events in combobox.

2 Comments

MVC with MVVM using Knockout.js

Previously, on Shawson.co.uk..

see “Creating an Order/ Order Details style view using ASP.net MVC2 & Entity Framework 4″

So following on from my last MVC post I posed my question to Scott Hanselman himself via email, and he took the time to write me a very helpful response;

Interesting solution. Good job getting it working.
Take a look at maybe using some cleaner JS on the client…check out my last podcast on Knockout and check out this demo: http://knockoutjs.com/examples/contactsEditor.html
The pod cast he’s refering to is here.  The contacts editor example he pointed me to is exactly what I’m trying to do here.  This implementation would totally resolve my issue as you are no longer binding directly to the entity framework objects- I could instead create simple cut down DTO’s for the sale and it’s associated sale lines and serialise it to JSON then use Knockout (an open source javascript library which deals with clientside binding of UI elements to a data structure, like your ViewModel represented as JSON) to deal with all the client-side binding and editing before posting the data back as JSON.  I shall post again once I have something up and working.

6 Comments