Monday, April 23, 2012

My website starterkit - 1kb Grid, Less, Formalize & Reset

I made starter kit for web development. It's a simple 960 grid-based kit with Less CSS. My starter kit is based on Tyler Tates' 1KB CSS grid, but it also has other stylesheets like:
  1. Meyer's Reset - to reset everything
  2. Formalize - for well mannered forms. 
  3. Style.less - This is where you should be adding your CSS, in the Less format.
I also turned Formalize and Grid into Less style sheets so I can combine all three into a single style sheet.

The starter kit also has jquery1.7 (via CDN) already added. You might want to change this during development.

To get the most of my starter kit you'll need something to turn Less style sheets to valid cascading style sheets. Try out Winless or Simpless.

You can clone my mercurial repo at https://bitbucket.org/jaypax/grid10kless if you want to try it out.

In case your wondering the code is DBAD licensed.

Wednesday, April 18, 2012

Getting knocked around while dealing with a check box

I've been using Knockoutjs heavily these couple of weeks and I think it has place in my programming toolkit. With Knockout, my markup is significantly cleaner and my pages with form elements are not a pain.

Knockout isn't that hard to use. I bet you can get a good handle of it once you finish some of the tutorials. Knockout, also has a couple of cool extensions like combining it with Kendo. I got good with Knockout but I had stuff to learn.

I had to implement a feature where an "admin" can select a "role" for new accounts. To select a role, admin had to select one of three check boxes in the page. The data for the check boxes is from JSON. Not a big problem since Knockout plays nice with jQuery.

So what exactly is the problem then?

The problem was that I needed to capture the "checked" value and push it into a new array. You would think that this a straight-forward preposition. So my first attempt went something like:

My Knockout script
<script type="text/javascript"> 
...{some code omitted for clarity}
        function roleModel(id, name, description) {
            var self = this;
            self.RoleId = id;
            self.RoleName = name;
            self.Description = description;
        }

        function viewModel(){
            var self = this;
            self.AvailableRoles = ko.observableArray();
            $.getJSON("/Role/GetRoles", function (data) {
                for (var i = 0; i < data.length; i++) {
                    self.AvailableRoles.push(new roleModel(data[i].RoleId, data[i].RoleName, data[i].Description));
                }
            });
            self.Roles = ko.observableArray();
        }
...{some code omitted for clarity}

        ko.applyBindings(new viewModel());

My Markup (HTML5)
<div data-bind="foreach: AvailableRoles">  
    <input type="checkbox" data-bind="attr: {value: AvailableRoles}, checked: Roles"/>  
    <span data-bind="text: RoleName"></span>  
</div>  
Notice the Roles and AvailableRoles properties. Apparently you can't bind the AvailbleRoles "directly" into the value field of the checkbox.

After looking around the web, I hit on the that idea I needed an intermediary field to store a key (thus I can bind it into the checkbox's value field) then I can use that key to retrieve the right role object from the AvailableRole object which is an array of role objects and store it in the Role property.
            
            self.Roles = ko.computed(function () {
                return ko.utils.arrayMap(self.SelectedRolesIds(), function (roleId) {
                    return ko.utils.arrayFirst(self.AvailableRoles(), function (item) {
                        return item.RoleId == roleId;
                    });
                });
            });
            self.SelectedRolesIds = ko.observableArray();
That's the SelectedRolesIds property in my viewModel. I also changed the Roles propety to be a computed field to make it "dependent" on what Role Ids are present in the SelectedRolesIds property. You still have to make changes to the markup. This all made nice with knockout utility functions - arrayMap and arrayFirst.

<div data-bind="foreach: AvailableRoles">  
    <input type="checkbox" data-bind="attr: {value: RoleId}, checked:$root.SelectedRolesIds"/>  
    <span data-bind="text: RoleName"></span>  
 </div>
The AvailableRoles property stays the same. 

Wednesday, April 11, 2012

Debugging Javascript: Blackbird, JSLint & dumpProps

JavaScript can be difficult to debug despite the tooling we got - IDE, Firebug, etc.

A naive way of doing debugging in JavaScript is to use alert() function. Unfortunately, alert falls short in this respect. Enter Blackbird. Blackbird is sort of a JavaScript console that is better than using alert(). As their website says, "You might never use alert() again."


Blackbird is attractive and useful but not might fall short in some debug scenarios. All too often, I have had a need to dump the insides of a JavaScript object - its properties. Fortunately, plain JavaScript can do this. This script can be found at the www.breakingpar.com site and it works nicely with Blackbird (with a few modifications).

function dumpProps(obj, parent) {  
   // Go through all the properties of the passed-in object   
   for (var i in obj) {  
    // if a parent (2nd parameter) was passed in, then use that to   
    // build the message. Message includes i (the object's property name)   
    // then the object's property value on a new line   
    if (parent) { var msg = parent + "." + i + "\n" + obj[i]; } else { var msg = i + "\n" + obj[i]; }  
    // Display the message. If the user clicks "OK", then continue. If they   
    // click "CANCEL" then quit this level of recursion   
    if (!confirm(msg)) { return; }  
    // If this property (i) is an object, then recursively process the object   
    if (typeof obj[i] == "object") {   
      if (parent) { dumpProps(obj[i], parent + "." + i); } else { dumpProps(obj[i], i); }  
    }  
   }  
 }  

When you get your script working as expected you might want to run it through JSLint. JSLint is a code analysis tool following the coding rules as discussed by Douglas Crockford's book, JavaScript: The good parts. Essentially, JSLint looks for problems in JavaScript program. It is a code quality tool.

I hope that these stuff makes debugging JavaScript a little more pleasant.