Ajax Bestiary: A Javascript Field Guide
 
Ajax Bestiary: A Javascript Field Guide
 
 

Entries Tagged as 'Article'

Why I’m Excited about SproutCore 2.0

Posted by Don Albrecht

If you’ve never seen it, SproutCore is a gorgeous framework for developing desktop style apps with rich user experiences and a robust data model.

In particular, the apps it produces are pretty gorgeous, especially in comparison to what would be created from a default dojo or ext.js approach.

Unfortunately, this like the other desktop app style frameworks, was incredibly limiting for those of us looking to build rich web experiences that resemble traditional web content instead of recreating the desktop app experience on the web.  A great example of this is the difference between Google’s search app and gmail.  While the two applications are both rich and complex user experiences, Google Search is definitely more “web like” in its user experience.

SproutCore 2.0 is really making an effort to support the “web like” style of rich web development.  Something much more conducive to the more “web like” user experience needed for most consumer facing web apps.  From the developer release announcement:

Today we’re announcing SproutCore 2.0: a rebuilt SproutCore, designed from the ground up to support every kind of web application. SproutCore 2.0 is highly modular and decoupled, allowing you just to opt in to the features you need.

By removing the need to opt into SproutCore’s view layer, you gain an ability to do complex data driven web front end with a lighter weight view perfect for a significantly greater number of projects.

Read the full announcment here:

http://blog.sproutcore.com/announcing-sproutcore-2-0/

My Friend “use strict”

Posted by Don Albrecht

At this point you’ve probably been seeing it around a bit, but if you haven’t  you should probably start placing

"use strict";

at the top of every js file you write.

So why should you use it?

The big win for me has been catching all the time I fail to define a local variable before assigning to it.  For those of you unaware, writing a = ‘b’; when a is undefined used to create a globally scoped variable a.  With strict mode, it throws an exception.

In the past, I’ve spent many an hour debugging errors I’ve created by this mistake.  Now, I just get exceptions and all is happy.

There are several other ways ‘use strict’ can make your coding life easier, but this feature alone has made it a life saver for me.

In Fact, if you aren’t ready to use it globally in your project yet.  you can use it locally at a function level but placing the statement in the first line of the function like so:

function(){
 
    "use strict";
 
    //other code
 
   }

What is the best part about “use strict”?

The best part about using “use strict” is that for all practical purposes, browser support doesn’t matter.  Compared to all of the other shiny new features emerging for javascript, ‘Strict Mode’ gets the biggest bang for its buck when it’s available for the browser you the developer use.  After all, you’re the one creating and testing the bugs it’s going to catch.  This is a case where ‘Runs On My Machine’ is almost all you need; ‘Runs On My Bosses Machine’ might be handy as well tho.

Creating Dynamic Styles with Handlebars.js and InsertRule

Posted by Don Albrecht

2 months ago, I wrote about InsertRule: a handy way to dynamically write style rules.  The problem is, building giant strings for complex CSS3 style rules is more than a little tedious to write and debug.  Today I’m going to discuss a method for streamlining this process using templates.

Step 1: Create a template for the CSS rule.

I’m using an html script tag for demonstration purposes.  In a  production setting you’ll want to precompile this.

    <script id="tab-template" type="text/x-handlebars-template">
        -webkit-border-top-left-radius: {{leftRadius}}px;
        -webkit-border-bottom-left-radius: {{leftRadius}}px;
        -moz-border-radius-topleft: {{leftRadius}}px;
        -moz-border-radius-bottomleft: {{leftRadius}}px;
        border-top-left-radius: {{leftRadius}}px;
        border-bottom-left-radius: {{leftRadius}}px;
        -webkit-border-top-left-radius: {{rightRadius}}px;
        -webkit-border-bottom-left-radius: {{rightRadius}}px;
        -moz-border-radius-topleft: {{rightRadius}}px;
        -moz-border-radius-bottomleft: {{rightRadius}}px;
        border-top-left-radius: {{rightRadius}}px;
        border-bottom-left-radius: {{rightRadius}}px;
        -moz-box-shadow: 0 0 5px #888;
        -webkit-box-shadow: 0 0 5px#888;
        box-shadow: 0 0 5px #888;
        
        width: 100px;
        border: 1px solid black;
        padding: 5px;
        background-color: #cecece;
</script>

Step 2: Define your custom attributes.

Handlebars takes an object as input to replace the dynamic variables in the template.  Here we’re specifying a large left radius and a right radius of 0.

var source   = $(“#tab-template”).html();
var tab_template = Handlebars.compile(source);
var rule =  tab_template( {leftRadius: 20, rightRadius: 10});

 

Step 3: Writing the Style

Use Style.Insert to attach the new rule, We’re using an ID here, but it could just as easily be any other selector.

 $.style.insertRule( ['#displaynode'], rule  );

You can learn more about InsertRule here:

InsertRule, A handy way to add CSS rules on the fly with jQuery

Templatize your dynamic site with mustache

Posted by Dave Mahon

Let’s face it. We spend a lot of time writing markup in all sorts of languages. Whether we’re producing the next big social networking site or creating a funky template, there is a lot of boilerplate that is continuously repeated. More importantly, chances are we’re implementing it in a mix of JavaScript, HTML and our backend language of choice.

It makes managing our presentation a muddled mess. That’s where template engines come in. If you’re using pure PHP, you could use Smarty, but this is a JavaScript-focused blog and you probably have some of your presentation in pure JavaScript anyway.

That’s where mustache comes in. Available in most web languages, it provides a simple and flexible way of integrating content into your site.

Let’s say we’re implementing a receipt purely in JavaScript. Our data looks like this:

{
  "title": "Our Web Store",
  "items": [
    {"name": "Widget",
     "unitprice": "1.45",
     "quantity": "2",
     "totalprice": "2.90"
    },
    {"name": "Whosit & Whatsit",
     "unitprice": "0.45",
     "quantity": "1",
     "totalprice": "0.90"
    }
  ]
}

First, we’ll integrate the mustache library, like so:

<script type="text/javascript" src="mustache.js"></script>

Next, we’ll define the template:

var template = "<h1>{{title}}</h1>

{{#items}}
    <dt<strong>{{name}}</strong></dt>
    <dd>${{totalprice}}</dd>
    <dt>{{quantity}} @ {{unitprice}}</dt><dd></dd>
{{/items}}";

Finally, we simply have to render the HTML, like so:

var html = Mustache.to_html(template, json);

This will produce output like:

<h1>Our Web Store</h1>
<dt><strong>Widget</strong></dt>
<dd>$2.90</dd>
<dt>2 @ 1.45</dt><dd></dd>
<dt><strong>Whosit &amp; Whatsit</strong></dt>
<dd>$0.90</dd>
<dt>1 @ 0.45</dt><dd></dd>

You can then use your DOM manipulation technique of choice to insert the markup.

Note that it automatically escaped the ampersand. Had we used three curly brackets, then it would have allowed it to remain literal.

What happens when we items is an empty array or, worse, isn’t there at all? It simply doesn’t appear, because the hash prefix in our template makes it conditional. You can invert the condition (say, for presenting a special message for missing information) by using a caret (^).

Since the items element was actually an array, mustache also automatically knew to loop through, which could potentially be handy for commenting systems.

Date.js My New Favorite Javascript Date Library

Posted by Don Albrecht

Earlier this week, I discovered that Safari doesn’t support dates in ISO 8601 UTC combined format:  “2010-06-19T03:11Z”.  This was a problem as my production system was delivering me a json file with dates in this format and my project was simply a new UI for the existing server.  A quick round of googling found DateJS a powerful chainable Date extension that enables both unified parsing and mask based date rendering.  I’d only played with it for a few minutes before I was completely hooked on it.  Just look at what it can do.

   1: // What date is next thursday?

   2: Date.today().next().thursday();

   3:  

   4: // Add 3 days to Today

   5: Date.today().add(3).days();

   6:  

   7: // Is today Friday?

   8: Date.today().is().friday();

   9:  

  10: // Number fun

  11: (3).days().ago();

  12:  

  13: // 6 months from now

  14: var n = 6;

  15: n.months().fromNow();

  16:  

  17: // Set to 8:30 AM on the 15th day of the month

  18: Date.today().set({ day: 15, hour: 8, minute: 30 });

  19:  

  20: // Convert text into Date

  21: Date.parse('today');

  22: Date.parse('t + 5 d'); // today + 5 days

  23: Date.parse('next thursday');

  24: Date.parse('February 20th 1973');

  25: Date.parse('Thu, 1 July 2004 22:30:00');

And Yes It supports ISO 8601 UTC combined format!.

A quick replacement of my existing date toolkit in the project and my bugs were fixed.

How to Write a jQuery Plugin

Posted by Don Albrecht

I know there’s a slew and a half of tutorials on this out there, but I’m adding my own to the mix.  I’ve been working on a generic template for plugin development and have cobbled together what I feel is a solid one.

First thing first, however, building a plugin is about being a good citizen

  1. You’ve got a naming convention to deal with.  jquery[your plugin name].js
  2. Be considerate of the $.XXX namespace.  Only claim 1, and try to make it both developer friendly and unique.  In our case it will be $.plugin
  3. Always return this.
  4. Always end with a “;”
  5. Wrap the entire thing in an anonymous function call, this will protect the plugin from instances where jquery has been renamed. 

So, with all that said and done, the skeleton of a plugin looks like this:

   1: (function($) {

   2:  

   3:   $.fn.myPlugin = function(settings) {

   4:     var config = {'foo': 'bar'};

   5:     if (settings) $.extend(config, settings);

   6:     this.each(function() {

   7:       // element-specific code here

   8:     });

   9:     return this;

  10:   };

  11:   

  12:    var newMethods = {

  13:        a   : function() {

  14:                 var config = {'foo': 'bar'};

  15:                 if (settings) $.extend(config, settings);

  16:  

  17:                this.each(function() {

  18:                   // element-specific code here

  19:                 });

  20:  

  21:                 return this;

  22:                   },

  23:        b   : function() { return this },

  24:        c     : function() { return this }

  25:       };

  26:       

  27:  jQuery.each(newMethods, function(i) {

  28:    jQuery.fn.myPlugin[i] = this;

  29:  });

  30:  

  31:  

  32: })(jQuery);

 

Note, what this code is doing.

First, we define the core behavior of the plugin, then extend the plugin once.  This way we keep our declarations concise, clear and well encapsulated.

We have an established closure structure for shared private functions.

We keep everything encapsulated to protect the jquery namespace as much as possible, and iterate over the child functions to extend the plugin.

PS– most of this is adapted from the jquery extension guide here: http://docs.jquery.com/Plugins/Authoring

jQuery 1.4.1 released

Posted by Dave Mahon

The 1.4 release of jQuery improved a lot upon this library, but there were some serious issues and unimplemented features. These have been resolved with today’s 1.4.1 release.

Some of the most notable are:

  • Firing ajaxError when a request returns a 404
  • The change event can now be used with live()
  • Incorrect handling of self-closing DIV’s in html()
  • jQuery.parseJSON has been exposed, so you can transparently support native implementations of parseJSON
  • Live() now supports focus, blur and hover events

Getting and setting values for jQuery widgets

Posted by Dave Mahon

If you come from an OOP background you’re likely used to defining class variables like this:

class MyClass {
   var internalValue1;
   var internalValue2;
   function constructor() {}
}

The values which are to be stored in your object are simple, straightforward, likely to be typed, and the compiler will detect typos in the variable names. JavaScript, as a loosely types language which treats its objects more like collections than discrete objects, can’t really offer us those protections. Conversely, that also means that we have a great deal of flexibility.

In essence, we can dynamically subclass our objects, which you have to admit is a neat trick.

So, for jQuery.UI widgets, the variables stored within our widget are not defined until we assign them. The act of assignment defines the variable name, which can then be called upon at will.

Assignment is simply:

this._setData(‘variablename’, variablevalue);

Retrieval of this value is similarly straightforward:

this._getData(‘variablename’);

This does mean that the old problem of misnamed variables is alive and well. It also means that you need to be prepared to handle an undefined response to the _getData call.

Constraining a numeric value to a range

Posted by Dave Mahon

Okay, so this doesn’t strictly have anything to do with any JavaScript library, but it’s a handy little snippet of code to keep in your arsenal.

val = Math.max(cMin, Math.min(val, cMax));

In one line of code, we’ve automatically constrained val between cMin and cMax. Note that if cMax and cMin are reversed (cMax is less than cMin) val will immediately be set to cMin (the higher of the values).

We can, of course, rectify this when cMin and cMax are assigned values by calling

cMin = Math.min(cMin, cMax);
cMax = Math.max(cmin, cMax);

Event handling in jQuery widgets

Posted by Dave Mahon

This is simple – provided you understand that the reference the keyword this refers to changes depending on when it is called.

When called during initialization, this refers to the widget you’re initializing. When the event itself is triggered, this refers to the DOM node node and not the widget.

As such, we need to introduce a new variable during initialization which the jQuery.UI library calls self which is, of course, equal to the initialization this, not triggered this. (Those of you familiar with Object Oriented Programming and by-reference calls should have no issue with this concept).

<$.widget("ui.clicker", {
   _init: function() {
      self = this;
      this.element.click(function() {
         self.increment(self);
         self.render();
      });
      this.render();
   },
   increment: function(target) {
      target.value(target.value()-1);
      //The exact handling of target.value will be shown another day
   },
   render: function() {
      this.element.text(this.value());
   },
   value: function(val) {}
});

You’ll note that we have to pass self to the increment method or the widget won’t actually be able to find itself, but the render method, which was called during initialization, is henceforth always able to correctly reference this (the widget)!