Unchecking Radio using Knockout Binding

The behaviour of knockouts check binding for radio buttons is useful if you have want to assign the value of the input tag into a observable like:

<input type="radio" value="Invoice" data-bind="checked:paymentOption">

But sometimes it is handy to to let the observable represent a boolean that checks/unchecks the radio button depending on its value

<input type="radio" value="Invoice" data-bind="checked:isSelected">

First note that there is no event firing upon un-checking, the event that is involved with a radio button selection is in in fact a change event on the group. Soo… How can we get around this in our knockout application? One approach is by adding a click binding that points to the parent of the view models that the radio buttons represent, like so:

<input type="radio" value="Invoice" data-bind="click: $parent.selectChild">

The selectChild method could look something like this:

self.selectChild = function (childViewModel) {
    for (var index = 0; index < self.childViewModels.length; index++) {
        var child = self.childViewModels[index];
        if (child.isSelected()) {
            child.isSelected(false);
        }
    }

    childViewModel.isSelected(true);
    return true;
};

The “return true” statement is a really funky thing in knockout that signals that you want the default action to be performed as well.

This leaves you with the expected behavior, but there is one more thing to do to get the nice finishing. Even though you have a boolean that can add/remove the checked attribute on the radio button, the ui will not be updated. The cleanest way I have found to solve this is to use the jQuery’s attr and remove checked (I know, it is wired… but jQuery does more things than just removing the attribute).

So as an addition to the click-binding I wrote a custom binding for just this:

ko.bindingHandlers.radio = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        // if subscribe is not defined, it is likely that the valueAccessor is not an observable
        if (typeof valueAccessor().subscribe == "undefined")
            return;

        if ($(element).attr('type') != 'radio')
            return;

        // subscribe to the changes to the observable in the binding 
        valueAccessor().subscribe(function (newValue) {
            // if the new value is false, we interperate it as it should be unselected
            if (!newValue) {
                // ... so we update the ui with the jQuery hack
                $(element).attr("checked", false);
            } else {
                $(element).attr("checked", true);
            }
        });
    }
};

It subscribes to the observable in the binding-expression and when change, it adds/removes checked using jQuery. There is some safe-guarding there as well, so that it does nothing if the valueAccesor is not an observable and the DOM-element is not of type radio. This should prevent errors to occur.

With these pieces of the puzzle, the data-bind expression would be something like this:

<input type="radio" value="Invoice" data-bind="click: $parent.selectChild, radio: isSelected">

Happy coding!

Best practice: Knockout observableArray inplace Add/Edit

The scenario is familiar: you have an observableArray in the viewModel that you want to be able to push new items to, or perhaps modify existing elements. There are just tons of code out there how to do so, for example knockout official example pages.

However, by mimicking that pattern, the viewModel quickly turns into a huge chunk of pointer to “active” elements, methods for “start edit”, “stop edit”. In the project I’m working, we’re going to have three different list with this functionality and it would just be such an repetitive work and overly complex code.

Just to make things worse, let’s imagine you want an in place editable table, like this guy wants to. If you look at his markup, there is just too much happening there with brackets, dubble equal signs,… Ugh, from my point of view the markup is the most important thing to get understandable and that’s not it.

Here’s the problem

Meet the Offers, an array with stuff that I’m offering. Yep, you guessed right it is an observableArray. As an admin, I want to be able to add/remove/edit Offers in place.

What you might have seen around is that an offer is created from a function call like so:

function Offer(id,name, shortName){
     this.id = ko.observable(id);
     this.name = ko.observable(name);
 }

Somewhere in your markup you end up with a

<input type="button" data-bind="click:$edit">

That must correlate to method on your viewModel

var viewModel = new function () {
    var self = this;
    self.Offers = ko.observableArray([]);
    self.selectedOffer = ko.observable();

    self.edit = function (item) {
        self.selectedOffer(item);
    };
}

But, hang on you also want to show an input text field if you edit the current item, as opposed to a div/span if you don’t edit. So you need some more methods that I am only going to name:

  • isOfferActive (used in the foreach in markup to evaluate what to show)
  • saveOffer (used to set selectedOffer to null so that none is edited)

Here’s the solution

So what we want to do is putting some of the “is active” “is inactive” logic on the element itself (rather than a comparing method on the viewModel $root). In the light of what I wrote earlier about the module pattern and jasmine testing, I ended up with this class:

var Offer = (function () {
    var activeOffer = function() {};

    //CONSTRUCTOR
    var offer = function(name, productMasterId, active) {

        var self = this;
        activeOffer = active;
        self.Name = ko.observable(name);
        self.Id = ko.observable(productMasterId);

        active(this);
        self.IsActive = ko.computed(function () {
            return self == active();
        });

        self.IsNotActive = ko.computed(function () {
            return self != active();
        });
    };

    var activateOffer = function () {
        activeOffer(this);
    };

    var deactivateOffer = function () {
        activeOffer(null);
    };

    offer.prototype = {
        constructor: offer,
        activateOffer: activateOffer,
        deactivateOffer: deactivateOffer
    };

    return offer;
}())

What’s so great with this? Well, it it takes a pointer to an observable that is considered to be the placeholder for the “current” selected Offer. The offer is then responsible to either set itself as active (offer.activateOffer()) or deactivate (offer.deactiveOffer()). Note that this observable does not need to be attached to the viewModel, actually this is how i do the add:

var viewModel = new function () {

    var activeUnlockedOffer = ko.observable(""); //we do not even need to add this to the viewModel

    this.Offers = ko.observableArray();

    this.addOffer = function () {
        var offer = new Offer("", "", activeUnlockedOffer);
        viewModel.Offers.push(offer);
    };

    this.removeOffer = function (data) {
        viewModel.Offers.remove(data);
    };
}

As you can see the activeUnlockedOffer is just a local variable. No need to pollute the viewModel with that. The only additional methods in my viewModel is the add/remove – which I think suits there (it should not be at the Offer anyways).

Perk number two, the markup will be easier to read, look at this:

<button title="Edit" data-bind="click: $data.activateOffer, visible: $data.IsNotActive" />
<button title="Save" data-bind="click: $data.deactivateOffer, visible: $data.IsActive" />

Another sweet thing with this solution is that when I add another list off offers, let’s call it OffersOnSales I can decide if I should allow one editable row in the two tables (in that case I would initialize all offers with the same observable), or if I want to allow the editing of one OfferOnSale and one normal Offer (in that case I would initialize the different groups with different observables).

And… yes, there’s a jsFiddle to it. Happy coding!

JavaScript: instance specific read only property with module pattern

The module pattern is a nice way to structure Javascript. It minimizes the use of global variables, enhances the script with private variables and public variables (which is very useful if you’re writing code that someone else will use along the way!). Let’s get a bit more hand-on about this.

Lets say that I’m modeling a (playing) card. It can either face up or down, which is indicated with a bool facingUp. The card may have other properties or dependencies that makes me want any developer that uses my card implementation to call the flip() function that, amongst other things, sets the facingUp property. Allright, so private prop seems like a good idea (and sure, we have that in a lot of other languages).

However, I think the objects gets a bit more slick if you can access properties without writing your own private variable and a getter. So, all of a sudden there is a need for read only props. It is indeed tricky to handle “this” in javascript, and it took me some time to get this working:

var Card = (function() {
  //constructor
  var card = function(settings) {
  settings = settings || {};

  // public properties
  Object.defineProperty(this, "imgSrc", { get: function() { return settings.imgSrc || ""; } });
  Object.defineProperty(this, "facingUp", { get: function() { return false; }, configurable : true });
};

    // instance specific function
    var flip = function () {
        var newValue = !this.facingUp;
        Object.defineProperty(this, "facingUp", { get: function () { return newValue; }, configurable: true });
    };

    card.prototype = {
        constructor: card,
        flip: flip,
    };

    return card;
})();

Object defineProperty

I read about this method  at Mozillas dev-pages. The descriptor has a few interesting literals, namely

  • get, that is a function that acts like a getter
  • configurable: which is a bool that indicates if any aspect of the property may change after it is defined. In my case, I want to be able to redefine it to the “new value” when calling flip.

Define read only in constructor

I tried to define the read only prop in the constructor, but that would not go. Sure, I could define facingUp : false there, but then I would not get the read only property.

Update read only in flip()

This took me some time to get right. The first argument in defineProperty is the object which you want to extend/manipulate. since the card prototype has a public flip literal that points to the flip method, “this” be the instance of the card. Hence this as the first parameter in the call to defineProperty

Avoiding eternal loop

The first thing that happens in the flip function is that the new value is extracted from the old value. My ambision was to make the function a nice one liner that defined “facingUp” as !facingUp – however, it turned out to be a bad idea to read the property in the getter redefine function.

Here’s the jsfiddle!

Getting the right width and height on you canvas

I learned something today. I was playing around with the <canvas> HTML5 element. When rendering on the canvases you do it by using the canvas’ context:

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');

context.fillRect(0,0,10,10) // makes a square at (0,0) with sides 10

the unit that is used when drawing the square is dependent on the width and height property of the canvas.

So,let’s say that you do this:

canvas.width = 100;
canvas.height = 50;
context.fillRect(0,0,10,10);

On a canvas element that is styled (using css) to have width equal to height. What you’re getting is a rectangle that is more higher – since you’re filling 10 of the available 50 units (that’s 20%) of height but only 10 of the 100 units for width (10%).

By default, in Chrome, the canvas is 300×150. For the application I’m developing right now I want it to be window.innerHeight x window.innerWidth. I even wrote a converter form my “application units” and actual pixels. Looking back at this, I would have styled the canvas to full screen, then set it’s width and height in accordance to the measures of the game. Well… that’s for next time.

I still had problems getting things to work. It turned out to be a “feature” of jQuery. Look at this:

Confusing JavaScript / jQuery

 

Create NuGet package for Javascript Library (pt1)

In an earlier post, I wrote about how you should setup the build of a NuGet package. I really liked the simplicity of making the package out of my .csproj file. However, the package I’m working with currently only contains one minified javascript file, and it turned out that if I created the package out of the csproj-file, I got an assembly reference to the project as well.

There are people who never would use Visual Studio to make JavaScript libraries. For me, comming from a .NET background, I’m more than familiar with VS, and with the Jasmine Testrunning Setup I described earlier, I run javascript unit tests just as I have always run nUnit-tests (Ctrl + U + R). In addition I think the intellisence is splendid.

I could of course create a .nuspec file and run the package command on build. But I would run in to problems, since the NuGet update command only works if there is a newer version out there. That would mean manually change the <version> content in the nuspec-file before build in order to be able to update the package in other projects. This is just something that I can’t live with.

After a few hours of work, this was the result:

My NuGet Package, versioned after todays date in my Local Repo

What is worth noting with this picture?

  • The version of the package is 1.YYmmDD.hhMM (that is year month day [dot] hour minute – every time I build with Release Configuration, a new package will be created with an incremented version number to the previous newest version. It also has some sort of time stamp, which I like for this project since I’m not going to work with major and minor versions.
  • It’s from my local repo C:\NuGet\Repo

In my following posts, I will explain how I accomplished this.

10 minute guide to get Visual Studio to combine and minify your javascripts on build

I thought this was going to be a tough nut to crack, but it turned out to be pretty straight forward.

Install JsMin

JsMin is a pretty slick tool. I like it because it is stand alone and small enough to have in your Solutions “tool” folder. So the first step is just to head over, download it and put it somewhere in your solution.

Add post-build event

Right click on your project, select options and go to the tab Build event. You will find a small (too small if you ask me!) textarea; Post-build event command line. You will want to write something like this:

type “$(ProjectDir)\Scripts\Pitfall\*.js” | “$(ProjectDir)..\tools\jsmin” > “$(ProjectDir)\Scripts\pitfall.min.js”

let’s go through the different things that happens in that oh so slick one-liner:

  • type “$(ProjectDir)\Scripts\Pitfall\*.js”: type is a command that displays content in files. In this case, since I have wildcard .js it will give me the content of all the files I have there
  • “$(ProjectDir)..\tools\jsmin” > “$(ProjectDir)\Scripts\pitfall.min.js”: this first finds the directory in which I have places JsMin. Since I used the pipe command (“|”) it will take that as first input. Lastly it outputs the minified file to pitfall.min.js

Given that you don’t have a more complex scenario with dependencies that you don’t want to add into the minified file this is pretty much it. I said it was going to be a ten minute guide. Looking back, it feels more like a 2 minute guid. Good luck :)

 

Headless Jasmine unit test with PhantomJs

Just adding a quick not to my previous rant about running jasmine test with ReSharper test runner. Because the fact is that there was still one thing that bugged me about the setup:

Every time I run the unit test, it would open a new tab in my browser to execute the test. Feeling that there should be a way to change that I browsed around in ReSharper options today and found this:

There is was, the option to run tests with PhantomJs

PhantomJs is basically a headless WebKit  browser, that implements a Javascript API. Running javascript unit tests feels just like running a normal nUnit suit. Sweet!

Running Jasmine unit test with ReSharper

What would I do without ReSharper? The reason why I’m extra happy about it today is the fact that it integrates so nicely with other test runners, like Jasmine. At first, I looked at other test runners, such as Chutzpah, but I don’t want to run my unit test from a terminal.

So I downloaded Jasmine together with a sample of how it’s used (it had Song.js and Player.js together with a spec). It also contained a html file which I could browse to in order to run my tests.That is not optimal, so to my surprise I saw the little ReSharper test runner symbol next to all the jasmine unit tests

Code snippet from the jasmine sample

There was only one thing left to do in order to get these test running properly:

// Classes to test
/// <reference path="~/Scripts/jasmine-samples/Song.js"/>
/// <reference path="~/Scripts/jasmine-samples/Player.js"/>
// The Jasmine Test Framework
/// <reference path="~/Jasmine/Runner/jasmine.js"/>
/// <reference path="~/Jasmine/Runner/jasmine-html.js"/>
/// <reference path="~/Jasmine/Runner/SpecHelper.js"/>

These XML comments just refers to the files we need to run the test. The reason they weren’t there at the first place is because they were refereed in the sample HTML file.

So now when I run the unit test (Ctrl.+ R works nicely), this is what I get:

Results when running the unit tests

That means I’m all set to start writing my own javascript unit tests