Durandal and requirejs

I’ve had some problems building my durandal project with grunt-contrib-requirejs and using almond

Apparently durandal relies on a custom almond that has the onResourceLoad function.

Just wanted to post my r.js config here to help others:

name: '../bower_components/durandal-almond/almond',
include: [
	'main',

	//in addition list all viewmodels and views here like this
	'viewmodels/shell',
	'text!views/shell.html' 
	//etc
],
insertRequire: ['main'],
stubModules : ['text'], //important to avoid the toUrl error
baseUrl: "app",
optimize : 'uglify2', 
wrap: true, //important for almond
mainConfigFile: "app/main.js",
out: "app/main-built.js"

I am using bower to handle the dependency on bluespire’s custom almond. But They have currently not tagged the changes they did for durandal in almond so make sure you use this in your bower file

    "durandal-almond": "git@github.com:BlueSpire/almond.git#master"

A model for Knockout

I have created a model for knockout inspired/based off of JavaScriptMVC’s Model.

Go to the github project page for updated code and documentation

Knockout Model

A model for knockout

Inspired by and partially based on JavaScriptMVC’s Model

Also uses the jQuery.Class from that project.

Dependencies:

  • jQuery
  • jQuery Class
  • Knockout
  • Knockout mapping

Built with ASP.NET Web API in mind, so it assumes some conventions:

  • by default all url start with /api
  • urls are made up by the lowercase, pluralized name of the model, Person model => /api/persons
  • Built in conversion of ASP.NET JSON date format \/Date(1224043200000)\/
  • the id of the model defaults to Id

All conventions can however be overridden and you can use it with any server side framework

Usage

$.KnockoutModel('Person', {}, {});

This assumes a full REST way of accessing that model on the server:

GET /api/persons //Lists all persons
GET /api/persons/1 //Get person with id 1
POST /api/persons //Create a new person
PUT /api/persons/1 //Update person with id 1
DELETE /api/persons/1 //Delete person with id 1

Find all

Person.findAll().done(function(persons){
    //do things with the persons array
});

query with parameters (OData url conventions in example)

var page = 5,
    pagesize = 10,
Person.findAll({$top: 10, $skip: 20}).done(function(persons){
    //persons 21-30
});

Find One

Person.findOne({Id : 3}).done(function(person){
    //do things with person
});

Create new model

var person =  new Person({ Name:'John', Age: 15 });

Save

person.save().done(function(){
    //person is now updated/created on the server
});

Destroy

person.destroy().done(function(){
    //person is now deleted on the server
});

Tracking status

Every instance will have a property isModified (observable as well) that will change whenever any other observable in the model is changed. This also works with save, when something is saved, the modified status is checked up against the new values returned from the database.

Mapping

By default all properties are observable and part of the main object. However you can define specific mapping options that follow standard knockout mapping standards.

The following example doesn’t make observables of the Id, Created and Updated properties.

$.KnockoutModel('Person', {
    mapping : {
        'copy' : ['Id', 'Created', 'Updated']
    }
}, {});

If the server returns a model with a childmodel you can also combine models like so:

$.KnockoutModel('Address', {
    mapping : {
        'copy' : ['Id'] 
    }
}, {});

$.KnockoutModel('Person', {
    mapping: {
        'Address': {
            create: function(options) {
                return new Address(options.data)
            }
        }
    }
}, {});

This will make the Address property of Person a separate class, with it’s own methods like save, destroy etc. Also on Address, we choose to not make observable of the property Id;

This way you can call save on a person’s address to only update that if you please.

Model options

  • findAll
  • findOne
  • create
  • update
  • destroy

These methods are automatically created from the model name and api prefix as shown above, however they can be overridden with a templated string. For instance: update : ‘POST /api/persons/{Id}’ to use POST instead of PUT for updates.

  • apiPrefix : ‘/admin/api’

    • default : ‘/api’
  • id : ‘id’

    • default : ‘Id’

this is important to set if the id of your model is something else than ‘Id’, as the existence of it determines determines wheter the model creates or updates when calling save.

  • resourceName : ‘fishes’
    • default : model name + ‘s’, person => persons

The model only does simple pluralization (adds an ‘s’), in cases where other forms is needed or where you simply want to call the model something else than the service url, set the resourceName property.

Note: In case of missing pieces in this simple documentation, your best bet is to check out the documentation for JavaScriptMVC’s model and for mapping specifically check out the documentation for the mapping plugin.

Twitter might give your users MB’s of extra data to download

When someone uploads their profile picture to twitter, twitter has a limitation of 700 KB. Ok.
Twitter then compresses the image to something smaller, like a 48×48 px image. The size can typically be a few KB’s. Good!
However twitter does not remove any thumbnail data that is embedded in the image (typically photoshop’s fault). This might result in images much much bigger than a few KB’s. Fail!

This of course causes problems for websites that embed twitter widgets, or any twitter client for that matter, even the twitter website itself. I’ve seen in the wild 48×48 px images that is 500 KB+, if you are unlucky and many people in your twitter widget on your website have used photoshop to crop their images without using “save for web” (which removes the thumbnail data) then your users might end up downloading MB’s of unnecessary data.

Not to mention that twitter’s bandwidth bill goes up because of many images being 100+ times bigger than they need to be.

Please fix this twitter.

Kthxbye :)

Create hierarchical objects from flat data

Typically when you have a menu or similar, you might have it organized as following, with several levels hierarchical:

Home
 - Products
  - Hardware
 - About us

Let’s say you get the data from the server in JSON format like this

var menudata = [{
	id: 1,
	name: 'Frontpage',
	parentId: null
}, {
	id: 2,
	name: 'Products',
	parentId: 1
}, {
	id: 3,
	name: 'Hardware',
	parentId: 2
},{
	id: 4,
	name: 'About us',
	parentId: 1
}];

To make this structured in the desired way, I added a method ByHierarchy to linq.js, an excellent javascript library for easy manipulation of data.

You use it like this:

Enumerable.From(menudata).ByHierarchy(function(d) {
	return d.parentId == null;
}, function(parent, child) {
	return parent.id == child.parentId;
}).ToArray();

The first parameter determines what elements should be on the first level. In this example we want all elements that have no parent to be on the first level.
The second parameter tells you how to connect the deeper levels.

The above code will result in the following:

[
  {
    "item": {
      "id": 1,
      "name": "Frontpage",
      "parentId": null
    },
    "level": 1,
    "children": [
      {
        "item": {
          "id": 2,
          "name": "Products",
          "parentId": 1
        },
        "level": 2,
        "children": [
          {
            "item": {
              "id": 3,
              "name": "Hardware",
              "parentId": 2
            },
            "level": 3,
            "children": []
          }
        ]
      },
      {
        "item": {
          "id": 4,
          "name": "About us",
          "parentId": 1
        },
        "level": 2,
        "children": []
      }
    ]
  }
]

(Note that the object on each level also will have a function called “getParent”, that will return the parent if it exists, here it is not visible as this is serialized using JSON.stringify, which excludes functions)

You can also use this in other ways, say an array of numbers:

Enumerable.From([2,4,5,9,3,25,16,64,8,81]).ByHierarchy(function(d) {
	return d < 10;
}, function(parent, child) {
	return parent * parent == child;
});

This will result in a root level of all the numbers less than 10 and the children will be any number that is the parent number squared, and their children will be the same etc. until there is no more numbers. ByHierarchy works very well in combination with the already existing methods CascadeDepthFirst and CascadeBreadthFirst. Here is an example with CascadeDepthFirst:

Enumerable.From([2,4,5,9,3,25,16,64,8,81]).ByHierarchy(function(d) {
	return d < 10;
}, function(parent, child) {
	return parent * parent == child;
}).OrderBy('$.item').CascadeDepthFirst('$.children', '$.item').ToArray();

(The first parameter to CascadeDepthFirst is the parameter that holds the children, and the other is what to select from each child)

This will produce the following :

[2,4,16,3,9,81,4,16,5,25,8,64,9,81]

Be aware that any method like OrderBy or Where etc is only applied to the top level. Here is an example with Where:

Enumerable.From([2,4,5,9,3,25,16,64,8,81]).ByHierarchy(function(d) {
	return d < 10;
}, function(parent, child) {
	return parent * parent == child;
}).Where('$.item < 4').ToArray();

This will filter so that we only get 2, and 3 at the root level. However the children will still contain 4, 16 and 9, 81.

However if you change the code as follows then you will get only children less than 4 (none in this case).

 return parent * parent == child && child < 4;

All parameters

firstLevel - elements that matches this condition will be on the first level
connectBy - if this condition is met the item will be added as a child to the parent, be aware of possible endless loops. returning true always will create endless children and fail. This method receives 2 arguments, parent, and child
orderBy - a order expression to apply to the children at the time of creating the hierarchy. This does not sort the top level as well, that you have to do after.
ascending - leave out or set to true for ascending sort or false to use descending sort.

The method will create new objects that have this structure:

{
    level : indicating the level of the current item,
    item : the original underlying data,
    children : contains any children,
    getParent : a method that returns the parent if any
}

Let me know if you have some problem or general feedback and I will try to answer them. I might also submit a pull request to the original project, and maybe they will include it as a standard method.

More examples

jQuery version:

<div id="flatlists">
	<ul id="categories" >
		<li data-subcategory="fruits">Fruits</li>
		<li>Clothes</li>
	</ul>


	<ul id="fruits">
		<li data-subcategory="citrusfruits">Citrus fruits</li>
		<li data-subcategory="plumfruits">Plum fruits</li>
	</ul>


	<ul id="plumfruits">
		<li>Red plum</li>
		<li>Yellow plum</li>
	</ul>

	<ul id="citrusfruits">
		<li>Lemon</li>
		<li>Lime</li>
		<li>Orange</li>
	</ul>
</div>

<ul id="resultlist">

</ul>
$('#flatlists li').toEnumerable().ByHierarchy(function(d) {
    return d.parent().attr('id') == 'categories';
}, function(parent, child) {
    return parent.attr('data-subcategory') == child.parent().attr('id');
}).CascadeDepthFirst('$.children').Select('$').ForEach(function(list) {

    list.item.css('padding-left', list.level * 10 + 'px');
    $('#resultlist').append(list.item);

});

Result:

The forked project is hosted at codeplex (since the original is a codeplex project) You can find it here http://linqjs.codeplex.com/SourceControl/network/forks/mokkabonna/ByHierarchy

The code is inspired by this similar LINQ C# method in an answer by Thomas Levesque over at stackoverflow.

ASUS U36SD windows experience index score

After getting my new laptop, an ASUS U36SD, weighting only 1,7 KG, replacing the HDD with an SSD and upgrading the RAM to 8 GB (I can’t believe how cheap ram is these days.) I ran the windows experience index test. These are the results I came up with.

I think that is pretty good for a laptop of this size and price.

Format your json with userscript

I have created a very small userscript for opera (might work ok with other browsers) that formats /indents/ beautifies the JSON data in a document if it’s only JSON there.

For opera to open the JSON by itself and this to work (the default is to present it as a download), you will have to enable that in opera. Go to preferences -> advanced -> downloads -> Add

Mimetype: application/json
Select open with opera

That will result in your JSON looking like this in the browser:

// ==UserScript==
// @name 		   JSON formatter
// @version        1.0
// @description	   Formats JSON if the document only contains JSON
// @compability    Only tested with Opera, might work with others
// @author		   Martin Hansen
// @website        http://martinhansen.no
// ==/UserScript==
(function(){
	var indentation = 4;//Change this to vary the indentation

	var pre = document.querySelector('body pre:only-child');
	if(!pre) return; //Don't do anything if this don't seem to be a json only document
	try{		
		pre.innerHTML = JSON.stringify(JSON.parse(pre.innerHTML), null,indentation);
	}
	catch(e){
		console.log(e);	
	}
})();

Either save the sourcecode directly from here, or get it from userscripts.org

Text selection mode off in opera

A nice feature in opera is to turn off text selection when dragging on the web page. For instance when using opera on an iPad over remote desktop to your pc. This allows you to drag the page as you would in the native browser on the iPad.

To enable this, right click any toolbar and press customize – apperance – buttons – browser view. Then drag the button “text selection on” to any toolbar of your choice. Then whenever you want to activate the mode, click the button.

Getting the bearing/heading betweet 2 coordinates

Thanks to rjsteward with his answer over at stackoverflow.com I have now a simple function for getting the bearing between to coordinates:

The function is meant to be used with google maps, so the parameters are google.maps.LatLng objects

function getBearing (from, to) {
            var lat1 = from.lat() * Math.PI / 180;
            var lon1 = from.lng();

            var lat2 = to.lat() * Math.PI / 180;
            var lon2 = to.lng();

            var dLon = (lon2 - lon1) * Math.PI / 180;
            var y = Math.sin(dLon) * Math.cos(lat2);
            var x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);

            var bearing = Math.atan2(y, x) * 180 / Math.PI;
            if (bearing < 0) {
                bearing = bearing + 360;
            }
            return bearing;
        }

This allows you to easily set the heading in the streetview, between your “streetviewman” and the actual position you are trying to see. So that you are looking to that direction from the street.

map.getStreetView().setPov({ heading: getBearing(streetViewManPosition, myLocationPosition), zoom: 1, pitch: 0 });

Resulting in something like this:

How to return clean JSON from EF object with data attributes

Returning JSON is very simple in ASP.NET MVC:

 return Json(Person,  JsonRequestBehavior.AllowGet);

(Person is an Entity Framework object)

The problem with this is if Person have related objects, like e.g. Friends. Then the serializer will throw an error because it will get a circular reference when tying to serialize Person.

So one common solution is to just create a new anonymous object on the fly like so:

 return Json(new {Name = Person.Name, Age = Person.Age},  JsonRequestBehavior.AllowGet);

A second solution is to create a Poco class that you fill with data from the entity object.

A third solution is to “tag” your model members with Attributes. But you cannot do this with an EF class, since the codefile is autogenerated, and if you change the code then your changes will be overwritten the next time you use the designer.

The following code demonstrates how to make this work anyway.

public class PocoAttribute : System.Attribute
{
}

[MetadataType(typeof(PersonMeta))]
public partial class Person
{          
}

public class PersonMeta
{
    [Poco]
    public string Name { get; set; }
    [Poco]
    public int Age { get; set; }
}

This is the same approach used to add data annotations to members in your EF objects. (See http://www.asp.net/mvc/tutorials/validation-with-the-data-annotation-validators-cs)

Now we need a way to automatically return a JsonResult with only the properties we have given our attribute to. For this we can create an extension method:

public static Dictionary<string, object> GetPocoDictionary(this EntityObject obj)
{
    PropertyInfo[] properties = obj.GetType().GetProperties();
    var pocoMembers = properties.Where(d=> d.GetCustomAttributes(typeof(PocoAttribute), true).Count() >= 1).ToArray();

    var metadataAttribute = (MetadataTypeAttribute)obj.GetType()
    .GetCustomAttributes(typeof(MetadataTypeAttribute), true).FirstOrDefault();
    
    var metaClassMembers = metadataAttribute.MetadataClassType.GetProperties()
    .Where(d=> d.GetCustomAttributes(typeof(PocoAttribute), true).Count() >= 1).ToArray();

    var combinedPoco = pocoMembers.Union(metaClassMembers);
    var allMembers = from propall in properties
                     join combined in combinedPoco on propall.Name equals combined.Name
                     select propall;

    var dict = new Dictionary<string, object>();
    foreach (var item in allMembers)
    {
        dict.Add(item.Name, item.GetValue(obj, null));
    }
    return dict;
}

This will take any EF object and return a dictionary with only the members that we have given the attribute to.
Now to use it:

 return Json(Person.GetPocoDictionary(),  JsonRequestBehavior.AllowGet);

That’s it!

jQuery checkbox/radiobutton dependence plugin

I have made a small jQuery plugin that enables you to have checkboxes and radiobuttons that depends on each other in a nested way.

The usage is very simple, just take a collection of radios or checkboxes and define an element they depend on. If you check an element that depends on something, the parent will be checked as well.

In the same way, if you uncheck a parent element that have children, then the children will be unchecked as well.

The plugin is designed to also work with jQuery UI buttons

$('#fruitlist>li>input').dependsOn('#fruits');
$('#citruslist input').dependsOn('#citrus');
<ul>
	<li><input type="radio" name="products" value="books">books</li>
	<li><input type="radio" name="products" id="fruits" value="fruits">fruits
		<ul id="fruitlist">
			<li><input type="checkbox">apples</li>
			<li><input type="checkbox" id="citrus">citrus fruits
				<ul id="citruslist">
					<li><input type="radio" name="citrus">lemons</li>
					<li><input type="radio" name="citrus">oranges</li>
				</ul>
			</li>
		</ul>
	</li>
	<li><input type="radio" name="products" value="pens">pens</li>
</ul>

Demo:


  • books
  • fruits
    • apples
    • citrus fruits
      • lemons
      • oranges
  • pens

Here is the code:

/* jQuery checkbox/radiobutton dependance plugin
* By Martin Hansen http://martinhansen.no
* MIT Licensed.
*/
(function($) {
  $.fn.dependsOn = function(parent) {       
    // build main options before element iteration     
    if(parent === undefined){ console.log('Parent is required'); return;   }        

    var opts = {parent: parent, value: null};

     //If parent is a radiobutton part of a group, make the group the parent
    if($(opts.parent).attr('type') == 'radio'){
      opts.origparent  = $(opts.parent);
      opts.parent = 'input[name=' +$(opts.parent).attr('name') +']';          
    }  
   
    return this.each(function() {
    var caller = $(this);
    $.data(this, 'dependsOnOptions', opts);//Store the dependency options
    
    caller.bind('click iterate', function(event){
      var parent = (opts.origparent) ? opts.origparent : $(opts.parent);
      parent.attr('checked', true).trigger('iterate', ['Iterate', 'Event']);
      if (jQuery.ui)parent.button('refresh'); //If jquery ui is loaded try to refesh button
    });              

    $(opts.parent).each(function(i){
      var pp = $(this);
      //Do first time checks
      var checked = pp.attr('checked'); 
      if(checked){
        $.fn.dependsOn.check(pp, caller, opts);            
      }
      //bind for change
      pp.change(function(event){
        $.fn.dependsOn.check($(this), caller, opts);            
      });
    });
   
   });
  };     

   $.fn.dependsOn.check = function(parent, child, opts){
    if (!parent.is(':checked') || !$(opts.origparent).is(':checked')) {
      child.attr('checked', false).change(); //uncheck the checked child, and trigger the change event so that any potential grandchildren also gets updated
      if (jQuery.ui)parent.button('refresh'); //If jquery ui is loaded try to refesh button
    }
   };
})(jQuery);

On github: https://github.com/mokkabonna/jQuery-dependency

Edit:updated the code to use .is(‘:checked’) instead of .attr(‘checked’), as jQuery 1.6.3 returns ‘checked’ instead of true. Thanks to “all” in the comments for making me aware of if.