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

jQ.Mobi: Less compatible, but better performance

Posted by Dave Mahon

The plain reality is that the vast majority of mobile web traffic is on Android and iOS devices. BlackBerry users have, by and large, been so disappointed by the poor web experience out of the box that they tend not to go on the web. Windows smartphones are still a small slice of the mobile market, especially when you focus on 3G and LTE devices, which use the lion’s share of the traffic, at least until Nokia ramps up its smartphone production.

With that in mind, jQ.Mobi saw its first public release on Monday. Its developer, appMobi, calls it a beta.

The core engine and UI is 15KB gripped, which means that even when your user drops to EDGE, they’ll still have a good experience, since you still have 10KB leeway for images and markup. It is also optimized for simulating apps, including support for integration in tools like PhoneGap.

Further, it’s designed to make the interface as consistent as possible between Android and iOS devices, including fixed headers and footers and smooth CSS3 transitions. It’s not quite ready for tablet devices. If you watch the video, the interface during the Kindle Fire segment feels clunky, but they say they are working on tablet-optimized CSS.

In terms of syntax, jQuery users will feel at home. Still, be cautious with jQuery plugins, because while they should be run, many are still optimized for desktop environments and jQ.mobi is not intended for desktop use.

jQuery Mobile 1.0 Final

Posted by Dave Mahon

The long anticipated jQuery Mobile library has hit version 1.0 Final. With support for most mobile devices, it facilitates rapid development of mobile friendly sites.

Note that it does require jQuery 1.6.4 and the jQuery Mobile 1.0 CSS file, in addition to the jQuery Mobile 1.0 JavaScript file. This means that pages that use it will very likely exceed the 25KB limit of some very old phones, preventing the page from loading at all on them. That said, most phones sold since 2008 do not have this limitation, so it shouldn’t hinder you too much. Still, focus on keeping image assets, JS, CSS and HTML as optimized as possible, because mobile performance is still pretty slow for most users.

Also, it does require a number of custom attributes, so you will want to explore their Getting Started documentation.

Gantt charts made easier, with ideas for improvements

Posted by Dave Mahon

Tait Brown has released an interesting jQuery extension for generating Gantt charts.

The most recent version adds support for local as well as JSON data sources and improves standard compliance while reducing the likelihood of CSS rule collisions.

One of the very first comments to the tumblr announcement was from jh asking, “Is it possible to represent dependencies among tasks?” This is an important Gantt chart feature, but not one that seems implemented – yet.

Using the live demo, I was able to inject a simple snippet between div.bar.ganttGreen and div.fn-label:
<div style="border-left: 1px solid #000; border-bottom: 1px solid #000; margin-top:-18px;height:30px; width:1px;"></div>

This produces a small black line to represent the relationship. While an arrow would be nicer, there is not enough space to represent it cleanly. I’m also using border-left and border-bottom so that it can eventually show relationships that don’t start and end at the same time.

Obviously, this is incomplete.

We will need to find a way to represent the relationship with another bar in the data. Each one is rendered by fillBars(), which simply iterates over the data property of the passed object, calling createProgressBar(). Presumably, we could add a parent property and use the array index of the parent bar as the value of parent.

We would still, however, need to calculate the relative positions of the bars, which will require a store of the row ID’s for each bar, so that we can test for visibility and horizontal and vertical positions.

These are not trivial changes, but they’re not insurmountable.

jQuery UI fixes: z-index and modals

Posted by Dave Mahon

jQuery UI is useful, but several of its widgets suffer from an annoying bug by design. If you never deal with simulated modal windows then you’ll never even experience it, but if you try to use an autocomplete or datepicker widget within a simulated modal window, you’ll find the dynamically generated DIV’s behind the modal.

You might try hardcoding a very high z-index to compensate for this, but it’s not terribly flexible, especially within a complicated third-party template.

That is why I now use this snippet in the beforeShow (date picker) or open (autocomplete) events, acquired from sources I no longer recall, to fix it.

function(input, inst) {
  var zMax = 1;
  $(input).parents().each(function(){
    zMax = Math.max(zMax, $(this).css('z-index'));
  });

  setTimeout(
    function() {
      $('.ui-datepicker .ui-autocomplete').css('z-index', zMax + 1);
    },
    300
  );
}

Sadly, the use of setTimeout() is necessary, because the event fires before the markup is appended to the DOM. You may be able to cut it down to about 150 ms, but that can sometimes fail in IE on slow machines.

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

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

Posted by Don Albrecht

I just stumbled across a great post on StackOverflow.  A contributed answered a question with a sweet plugin for dynamically creating CSS rules that apply page wide on the fly with javascript.

Here’s a simple example:

$.style.insertRule(['p','h1'], 'color:red;');
$.style.insertRule(['p'], 'text-decoration:line-through;'); 
$.style.insertRule(['div p'], 'text-decoration:none;color:blue');

Pretty sweet when you need to change styling on the fly, no?

You can view the original StackOverflow post here:

http://stackoverflow.com/questions/4232557/jquery-css-write-into-the-style-tag

The code is also cross posted to jsfiddle here:

http://jsfiddle.net/doktormolle/ubDDd/

Lettering.js A fun way to spice up Typography

Posted by Don Albrecht

CSS is awesome, but it lacks the ability to fine tune typography to the nth degree.  Want a spectacular drop cap, tighter kerning on a few letters, magical rainbow type?  You’re stuck with a bespoke and labor intensive solution.  Lettering.js can help alleviate those pains.

How it works, calling .lettering() on a text node, the node is broken up into a collection of spans uniquely classed for each letter.

For Example:  the HTML Node

<code><h1 class="fancy_title">Some Title</h1></code>

Can be transformed by

<code> $(document).ready(function() {    
 $(".fancy_title").lettering(); });</code>

And yields

<code><h1 class="fancy_title"> 
<span class="char1">S</span> 
<span class="char2">o</span>
 <span class="char3">m</span>
 <span class="char4">e</span> 
<span class="char5"></span> 
<span class="char6">T</span> 
<span class="char7">i</span> 
<span class="char8">t</span> 
<span class="char9">l</span> 
<span class="char10">e</span> </h1></code>

Now, you can style the code with css char# classes!

Check it out here:

http://daverupert.com/2010/09/lettering-js/

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.