KnockoutJs : Toggling CSS class

A common scenario with Javascript is toggling a set of elements based on the selected element add applying, removing css classes.  You’ll see this on menu items, etc… and in my case where we want to have styled ‘button’s instead of a radio list.

An example of this might be handling the selection of the button and then applying a class and removing any other classes, for example:

$(‘.year_item’).bind(‘click’, function(){
$(“.year_Item”).removeClass(“selected_year”);
$(event.currentTarget).addClass(“selected_year”);
});

In my first attempt at such a toggle with knockoutjs, I followed a similiar route – calling back to my viewmodel :

setYear: function (year, event) {
$(“.year_Item”).removeClass(“selected_year”);
$(event.currentTarget).addClass(“selected_year”);
myViewModel.year(year);
}

The binding in the html looks like this:

<ul data-bind=”foreach: years”>
<li><input data-bind=”text: $data, click: $parent.setYear” type=’button’/></li>
</ul>

This works fine.  However, I can do better – since KnockoutJs supports setting the CSS class on binding.

ie. <div data-bind="css: { profitWarning: currentProfit() < 0 }">

So let’s take this example and show how we can effectively toggle the CSS class based upon the value of the binding – using our example above:

<ul class=”bigButtons” data-bind=”foreach: years”>
<li><input data-bind=”text: $data, click: $parent.year, css:{selected_year: $parent.year() === $data}”  type=’button’/></li>
</ul>

That is it.  No more function required in the viewmodel.  To understand what happens here is to understand the $parent.year click event.  Basically in KnockoutJs 2.0 by default $parent.year takes the $data property as a parameter.  The year binding is set, which in turn triggers the css selection on all the items reevaluating if it should have that CSS appended.

This has proved to be very terse and valuable in our UI.

Edit: I’ve put an example out on jsFiddle: http://jsfiddle.net/sgentile/pRC4c/

KnockoutJS ‘Addons’, etc…

This is not intended to be a full post – just wanted to highlight a few links to add ons to the javascript knockoutjs library I’ve been using on some recent projects:

Observable Dictionary :  github source  gist of example

Protected Observable: blog post with sample code  gist of example

KO ‘Datagrid’ : link to google group post  github source  samples

I’ll update this with more links – it would be great to have a knockoutjs community

Steve Michelotti has a KnockoutJs course of Pluralsight and an example of building a custom binding

Also just to add – I have an example of KnockoutJS with NodeJs on my github here with a few simple tests using jasmine-node for some specs, and QUnit showing some Knockoutjs test scenarios.

JavaScript Todos–Backbone with asp.net mvc

There are certainly plenty of articles, examples, etc… around creating the ‘Todos’ sample.  To learn more about different frameworks and a more complete example, check out Addy Osmani‘s examples here: http://addyosmani.github.com/todomvc/   This is a fantastic resource to learn about different available frameworks.

Most of these examples tend to use the localStorage.  Not that it’s a big deal, but I wanted to put together something very very simple that showed some connections between using Backbone.js to make calls to a backend server.  In this case, I have decided to use asp.net mvc.

The example uses IISExpress to be hosted.  To reduce some of the friction, there is no database, just a static List object on the server.  I am not handling edits in this simple example – just a GET call to show todos and POST call to add a new todo.

To get an example – you can get it on github https://github.com/sgentile/MvcBackbone

First, this is not a ‘how to use backbone’ nor a ‘how to use asp.net mvc’ – I’d probably fail you on both subject matters!  The goal here is to highlight the aspects of backbone that help in making the connection to the backend server.  Backbone is providing an abstraction over the ajax calls.  You certainly CAN use ajax directly if you want. 

So, let’s get started.   The ‘todo’ model is quite simple – see todo.js line 5 :

Todo = Backbone.Model.extend({
    // Default attributes for the todo.
    defaults: {
      content: "empty todo..."
    },
        // Ensure that each todo created has `content`.
    initialize: function() {
      if (!this.get("content")) {
        this.set({"content": this.defaults.content});
      }
    },
    
    url: "home/todos"
});

If you check the backbone.js document for Model url http://documentcloud.github.com/backbone/#Model-url

Returns the relative URL where the model’s resource would be located on the server. If your models are located somewhere else, override this method with the correct logic. Generates URLs of the form: "/[collection.url]/[id]", falling back to "/[urlRoot]/id" if the model is not part of a collection.

The key here is to let backbone know the url for Todos.  We will be making a ‘save’ call on our Todo model object when we add a new model  ( save: http://documentcloud.github.com/backbone/#Model-save ).  This will look for the url on the server:

the save will be a "create" (HTTP POST), if the model already exists on the server, the save will be an "update" (HTTP PUT).

 

The TodoFormView on line 38, handles connecting the forum submit call to our save function, which maps the form to the Todo model.  Calling ‘save’ directly on the model results in an ajax call – ie:

TodoFormView = Backbone.View.extend({
    initialize: function () {
        this.template = $("#formTemplate");
    },
    events: {
        "submit #todo-form": "save"
    },
    render: function () {
        var content = this.template.tmpl();
        $(this.el).html(content);
        return this;
    },
    save: function () {
        var val = this.$("input").val();
        var model = new Todo({ content: val });
        model.save();
        this.$("input").val('');
    }
});

The key items to see here is the save function call  – where we save the model – model.save();

So the ‘home/todos’ matches up to the HomeController Todos action – with is a new Todo, so therefore it cooresponds to the following:

        [HttpPost]
        public ActionResult Todos(Todo todo)
        {
            todo.id = Guid.NewGuid();
            TodoList.Add(todo);
            return Json(TodoList, JsonRequestBehavior.AllowGet);
        }

As you see, backbone is handling the underlying ajax POST calls to the server!

Obviously GET calls are equally as straightforward.  I have a collection of Todos defined:

Todos = Backbone.Collection.extend({
    model: Todo,
    url: "home/todos"
});

I am able to do a GET call with ‘fetch’ as seen below:

TodoListView = Backbone.View.extend({
    initialize: function () {
        _.bindAll(this, "render");
        this.collection.bind("change", this.render);
        this.collection.bind("add", this.render);
        this.collection.bind("fetch", this.render);

        todos.fetch({ add: true });
        
    },
    render: function () {
        //clear out the existing list to avoid "append" duplication
        $(this.el).empty();
        //use an array here rather than firehosing the DOM
        //perf is a bit better
        var els = [];
        //loop the collection...
        this.collection.models.forEach(function (todo) {
            //rendering a view for each model in the collection
            var view = new TodoItemView({ model: todo });
            //adding it to our array
            els.push(view.render().el);
        });
        //push that array into this View's "el"
        $(this.el).append(els);
        return this;
    }
});

The key here is the todos.fetch call.  You can learn more about collections and fetch here: http://documentcloud.github.com/backbone/#Collection-fetch

This is all for now, should be a good start – there is much to learn here obviously (ie bootstrapping). 

Next time, I hope to share more about using backbone with asp.net mvc and then add jquery mobile to the mix.  Thanks!

JavaScript: Revealing Module Pattern and Namespacing

This is a basic post regarding namespacing and revealing module pattern.  When starting a new JavaScript application it’s important to have a good starting foundation.  First let’s show how to use namespacing in JavaScript:

window._ns = window._ns || {};

_ns is attached to the global window object.  Alex MacCaw in his book ‘’JavaScript Web Applications’ describes this well:

We’re setting on the window object to ensure that it’s globally accessible.

Also, by using this pattern, it’s easy to see which global variables a script is declaring,

just look through the script for window references

Let’s show this in use, first using what is referred to as the singleton pattern:

_ns.Singleton = {
    _somethingConsideredPrivate: function () {
        document.write("Singleton doSomething complete<br/>");
    },
    doSomething: function () {
        this._somethingConsideredPrivate();
    }
};

 

_ns.Singleton.doSomething();   //note, everything is public – some use an underscore : _privateFunction : function … to denote private, but it’s still accessible

<html>
<head>
    <title>Module</title>
    
    <script src="/Scripts/Module.js" type="text/javascript"></script>
</head>
<body>
    <div>
        <script>
            _ns.Singleton.doSomething();
        </script>
    </div>
</body>
</html>

But what if we want to use the revealing module pattern which gives us the concept of private and public ?

basically we return what is public.

_ns.RevealingModule = function () {
    var privateData = {
        message: "RevealingModule doSomething complete"
    };

    var privateFunction = function () {
        document.write(privateData.message);
    };

    var doSomething = function () {
        privateFunction();
    };

    return {
        //since returned - it's public:
        doSomething: doSomething
    };

} ();   //end of module

 

It’s usage pattern as follows:

<!DOCTYPE html>

<html>
<head>
    <title>Module</title>
    
    <script src="/Scripts/Module.js" type="text/javascript"></script>
</head>
<body>
    <div>
        <script>
            _ns.Singleton.doSomething();
            _ns.RevealingModule.doSomething();
        </script>
    </div>

</body>
</html>

If you try to access the private function – it would fail:

 

_ns.RevealingModule.privateFunction();

would result in:

_ns.RevealingModule.privateFunction is not a function
[Break On This Error] _ns.RevealingModule.privateFunction(); 

I hope this helps clarifying namespacing and the revealing module pattern.  There are certainly some great resources to describe both. 

Recommended reading followup: http://www.klauskomenda.com/code/javascript-programming-patterns

Alex MacCaw’s book ‘JavaScript Web Applications’: http://shop.oreilly.com/product/0636920018421.do

Javascript/jQuery contains and not contains sample

<div class="navigationelementsContainer clear_fix">
{{each navelement}}
        {{if name != 'null'}}                             
            <div class="navigatorModifier pointer" data-name='${name.toUpperCase()}' data-modifier='${modifier}'>${name} (${count})</div>
        {{/if}}                                   
    {{/each}}
</div>

$(".navigatorModifierSearch").live('keyup', function (event) {
            var $navigationelementsContainer = $(this).parent().parent().find(".navigationelementsContainer");
            var searchTerm = $(this).val();

            if (searchTerm.length > 0) {
                $navigationelementsContainer.find('div[data-name*="' + searchTerm.toUpperCase() + '"]').removeClass("hideNavElement");
                $navigationelementsContainer.children().not('div[data-name*="' + searchTerm.toUpperCase() + '"]').addClass("hideNavElement");                
            } else {
                //make sure all are showing
                $navigationelementsContainer.children().removeClass("hideNavElement");
            }
        });

https://gist.github.com/1207961.js

 

Key section:

$navigationelementsContainer.find(‘div[data-name*="’ + searchTerm.toUpperCase() + ‘"]’).removeClass("hideNavElement");

$navigationelementsContainer.children().not(‘div[data-name*="’ + searchTerm.toUpperCase() + ‘"]’).addClass("hideNavElement");

Not the best blog post.. but it’s pretty nice way to select elements by attribute with ‘contains’ as well as ‘not contains’ Smile

‘Restoring’ Git after Upgrade to OSX Lion

I was surprised to find out my ‘git’ command didn’t work after upgrading to Lion.

It is still there (verify by checking for this directory: /usr/local/git/bin), just needs to be mapped.

I was able to find out that the git installer uses paths.d to add it to the path.

I went to /etc/paths.d and did ls  – but there was not git file.

open Terminal

cd /etc/paths/d

sudo vi git

enter /usr/local/git/bin at the top of the file (if new to vim, hit ‘I’ to enter ‘insert mode’)

hit escape – type :wq to save and quit

open new terminal – run ‘which git’

Should work now

Encoding, MemoryStream, XDocument

Edit: As mentioned in the comments, an easier alternative to what I show below is to directly use the XDocument.Parse call, ie.

XDocument = XDocument.Parse(xmlString);

Just recently I had one of those tasks where you are given a string that is xml.  In this case it was xml from a WebClient call asynchronously.  So the result coming back was a string.

There are several classes that work well to do this task, and each is probably a topic of it’s own.   Personally, Linq in all it’s flavors is one of my favorite things about the C# language.  Take for example the XDocument class- it allows us to use XPath style queries using a Linq syntax.

When you look at XDocument, you’ll notice it has the XDocument.Load() function with it’s various overloads.  One option is a string, however, this is a path to an xml file.  That leaves us with Streams, TextReader, XmlReader, etc…

So, we have a string, that is xml, we want to load it into a XDocument that takes a XDocument.Load(Stream).

I’ve decided to use a MemoryStream, as a MemoryStream will create a stream that is in memory vs. on disk, etc…  What we find out though, is our MemoryStream is expecting an array of bytes! 

In order to get our string into an array of bytes, we will need to use the C# Encoding class.  There are many different of encoding, which you can check out in the Encoding class.  In this case, I’m going to use UTF8Encoding.  If your new to Encoding, or want to learn more, I suggest reading the MSDN topic ‘Character Encoding in the .NET Framework’. 

So our Encoding.UTF8.GetBytes(string) will take our xml string and produce our byte array for the MemoryStream – we’ll take that stream and give it to our XDocument.Load to populate our XDocument object.

string xml = ...some xml...
byte[] bytes = Encoding.UTF8.GetBytes(xml);
using(MemoryStream stream = new MemoryStream(bytes))
{
    XDocument document = XDocument.Load(stream);
}

I’m not going to go into too much detail on linq to xml here but just to show what can be done with the XDocument will help close the topic – ie. pulling out all the titles in an Atom feed:

var entries = from feed in doc.Root.Elements()
    .Where(i => i.Name.LocalName == "entry")
        select new Feed
        {
            Title = feed.Elements()
                .First(i => i.Name.LocalName == "title")
                .Value
        };
return entries.ToList();

Hope this helps next time you need to work with a string of xml in C#  Smile