Category Archives: jQuery

RESTful API with JSON messages in Rails 3 and jQuery

Rails 3 makes it really easy to return JSON data in the HTTP response. Consider this fragment:

class ListsController < ApplicationController
 
  respond_to :json
 
  def index
    @lists = List.all
    respond_with(@lists)
  end
 
  # ...
end

index might return e.g.

If you look at jQuery-ujs when sending an Ajax request, the content type is set to ‘application/x-www-form-urlencoded’ by default: The data is serialized as form data and send through the wire.

While this is absolutely fine, I was wondering how to use ‘application/json’ as content type when sending an Ajax request with jQuery. IMHO that’s cleaner because you then send JSON in the request and get back JSON in the response. Content types like ‘application/json’ and ‘text/xml’ are also much better if 3rd party applications will consume your service.

Rails by default creates seven different routes for a single (not nested) resource:

          GET    /lists(.:format)               {:action=>"index", :controller=>"lists"}
    lists POST   /lists(.:format)               {:action=>"create", :controller=>"lists"}
 new_list GET    /lists/new(.:format)           {:action=>"new", :controller=>"lists"}
          GET    /lists/:id(.:format)           {:action=>"show", :controller=>"lists"}
          PUT    /lists/:id(.:format)           {:action=>"update", :controller=>"lists"}
     list DELETE /lists/:id(.:format)           {:action=>"destroy", :controller=>"lists"}
edit_list GET    /lists/:id/edit(.:format)      {:action=>"edit", :controller=>"lists"}

Below the jQuery Ajax code for each of these routes:

GET /lists(.:format) {:action=>"index", :controller=>"lists"}

$.ajax({
	url: "http://localhost:3000/lists",
	dataType: "json",
	type: "GET",
	processData: false,
	contentType: "application/json"
});

POST /lists(.:format) {:action=>"create", :controller=>"lists"}

$.ajax({
	url: "http://localhost:3000/lists",
	dataType: "json",
	type: "POST",
	processData: false,
	contentType: "application/json",
	data: "{\"list\":{\"title\":\"test\"}}"
});

GET /lists/new(.:format) {:action=>"new", :controller=>"lists"}

// .new
$.ajax({
	url: "http://localhost:3000/lists/new",
	dataType: "json",
	type: "GET",
	processData: false,
	contentType: "application/json"
});

GET /lists/:id(.:format) {:action=>"show", :controller=>"lists"}

$.ajax({
	url: "http://localhost:3000/lists/3",
	dataType: "json",
	type: "GET",
	processData: false,
	contentType: "application/json"
});

PUT /lists/:id(.:format) {:action=>"update", :controller=>"lists"}

$.ajax({
	url: "http://localhost:3000/lists/3",
	dataType: "json",
	type: "POST",
	processData: false,
	contentType: "application/json",
	data: "{\"list\":{\"title\":\"hallo welt\"}}",
	beforeSend: function(xhr)   
	{
		xhr.setRequestHeader("X-Http-Method-Override", "PUT");
	}
});

DELETE /lists/:id(.:format) {:action=>"destroy", :controller=>"lists"}

$.ajax({
	url: "http://localhost:3000/lists/3",
	dataType: "json",
	type: "POST",
	processData: false,
	contentType: "application/json",
	beforeSend: function(xhr)   
	{
		xhr.setRequestHeader("X-Http-Method-Override", "DELETE");
	}
});

GET /lists/:id/edit(.:format) {:action=>"edit", :controller=>"lists"}

// .edit
$.ajax({
	url: "http://localhost:3000/lists/3/edit",
	dataType: "json",
	type: "GET",
	processData: false,
	contentType: "application/json"
});

Note that you need to override the HTTP method for update and destroy. You could use also type: "PUT" and type: "DELETE", but not all browsers understand these verbs. Therefore it's probably better to use the 'X-Http-Method-Override' header instead.

For those routes which require to send data, the data is send as JSON. The format of the JSON string needs to match what Rails would return in the response. If you used a different JSON string, you would have to parse it server side by yourself.

processData is set to false. If it is 'true' (the default), jQuery will try to serialize it into a form post. In this case that's not desirable, that's why it needs to be turned off.

DeliciousTwitterFacebookLinkedInRedditSlashdotTechnorati FavoritesDiggShare
Posted in jQuery, RubyOnRails | 2 Comments

Generating frame for new jQuery Plugins

The jQuery documentation gives great advice on how to create plugins for the jQuery library. When I start a new plugin I usually go to that page, copy the frame for the plugin and then start coding.

To make this process a little faster I wrote a little Rakefile which auto-generates the plugin frame for me

rake create_plugin name=MyNewPlugin

You can get the code here: jQuery-Plugin-Generator. I’ll also add a template for a jQuery UI Widget sometime during the next couple of days.

Textmate

If you are using Textmate you might just want to create a New File Template. Here is how that goes:

  1. Click File >> New From Template >> Edit Templates.
  2. Select JavaScript, click the “+”-button and call the template something like “jQuery Plugin”
  3. Type in “js” as the extension
  4. The command is
    [ -f "$TM_NEW_FILE" ] ||  perl -pe 's/\$\{([^}]*)\}/$ENV{$1}/g' <jqueryplugin .js> "$TM_NEW_FILE"</jqueryplugin>
  5. Now select the new template in the left hand list and click once more the “+”-button. Click “New Template File”
  6. Rename the template file to jqueryPlugin.js
  7. Copy this code to the template file:
    (function( $ ) {
     
    	var methods = {
    		init : function( options ) {
    			var settings = {
    				// Replace with you own settings
            // 'location'         : 'top',
            // 'background-color' : 'blue'
          };
     
          // If options exist, lets merge them
    			// with our default settings
    			if ( options ) {
    				$.extend( settings, options );
    			}
     
    			return this.each(function() {
    				var $this = $(this);
     
    				// Read / Write Data
    				// $this.data("mykey", value)
    				// temp = $this.data("mykey")
     
    	    });
    		},
     
    		destroy : function() {
    			// pseudo destructor. Needs to be called manually.
    			// Add here things like unbind and removeData calls
    		}
     
    		// Add here your functions
    		// myFunc1 : function( ) { },
    		// myFunc2 : function( ) { }
    	};
     
    	$.fn.${TM_NEW_FILE_BASENAME} = function( method ) {
    		// Method calling logic
    		if ( methods[method] ) {
    			return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    		} else if ( typeof method === 'object' || ! method ) {
    			return methods.init.apply( this, arguments );
    		} else {
    			$.error( 'Method ' +  method + ' does not exist on jQuery.${TM_NEW_FILE_BASENAME}' );
    		}
      };
    })( jQuery );
  8. Close the template editor.

You can use the template by clicking File >> New From Template >> Javascript >> jquery Plugin. Alternatively select a folder in the project drawer and hit Shift + Cmd + N. Give the file a name following the jQuery convention like “jquery.MyPlugin.js”, select the template and hit Create.

Update:
I just added the template for jQuery UI Widgets. Check out the latest code at Github.

DeliciousTwitterFacebookLinkedInRedditSlashdotTechnorati FavoritesDiggShare
Posted in jQuery | Leave a comment

jQuery.UrlParams

I wrote a tiny jQuery plugin which helps you parsing URL parameters.

Find the code at Github: UrlParams

Usage

$.urlParams("get", "param_name") 
// => returns unescaped string of the parameter "param_name"
 
$.urlParams("keys") 
// => returns an array of all parameter keys
 
$.urlParams("exists", "param_name") 
// => returns true if "param_name" exists; false otherwise
 
$.urlParams("all") 
// => returns a hash with all key, value pairs

Let me know if there are any problems with that.

DeliciousTwitterFacebookLinkedInRedditSlashdotTechnorati FavoritesDiggShare
Posted in jQuery | Leave a comment

Improving Javascript Minification by Using Closure

Update
While you can improve minification by following below description, you might experience a negative performance impact, especially if you have a lot private functions since all these functions are hold within the closure of the anonymous function. I’m not sure how bad that really is, but I for myself went back to build an object directly, not using the closure of the anonymous function.

Like jQuery, I’m using the Google Closure Compiler to minify the code of my Image Color Picker plugin.

When I looked over the minified code, I noticed that quite a few function names don’t get minified.
Let’s take a closer look at the v0.1 version of ImageColorPicker.js (github):

$.widget("ui.ImageColorPicker", {
 options: {},
  _create: function() {
  },
 
  destroy: function() {
  },
 
  selectedColor: function() {
  },
 
  _d2h: function(d) {
  },
 
  _h2d: function(h) {
  },
 
  _createImageColorPicker: function() {
  }
});

option, _create, destroy, selectedColor and all the other function names don’t get minified. Everything within these function gets minified pretty well. The reason for this is that the Closure Compiler regards all these functions and objects as public. Since they are public the compiler does not know whether another, external library uses one or more of the functions. In order not to break external libraries or, more generally, code that depends on our code, the Closure compiler does not touch the names.

In case you have quite a few “private” functions and / or use them heavily, it can become pretty space wasting to not minify them. So how to fix this?

The solution is: Use a Javascript Closure. By using closures you can make functions truly private, compared to marking them private by using the underscore convention. This is ImageColorPicker.js after the refactoring (github):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var uiImageColorPicker = function(){
 
	var _d2h = function(d) {
	};
 
	var _h2d = function(h) {
	};
 
	var _createImageColorPicker = function(widget) {
	};
 
 
 
	return {
		options: {},
 
		_create: function() {
		},
 
		destroy: function() {
		},
 
		selectedColor: function() {
		}
 
	};	
}();
$.widget("ui.ImageColorPicker", uiImageColorPicker);

In line 1 a function is assigned to uiImageColorPicker. But not really. Take a closer look at line 27. It’s directly executed. Therefore the value which is assigned to uiImageColorPicker is not a function, but the object which is returned by the function. This object is supposed to contain all public functions of your plugin and option, _create and destroy, since these are expected by the jQuery UI Widget implementation.
All private functions go to the function body, outside of the object. After the outer function ran, they won’t be accessible any more, but if you use them in functions of the returned object they are bound through a closure and thus can be used by the object’s functions even after the outer function finished execution.

When doing such thing, there are two things I can think of which require a little extra attention:

  • Don’t store object specific data in the function body. That’s like storing data in an object prototype. All objects would either read the same data, or worse, overwrite data. Therefore, keep object related data in the object.
  • this refers to the object when used within the object and to the function when used outside of the object in the function body. If you need to use the object’s this reference in your private function, pass it in as a parameter. I’m doing this for example in the create function. Check out github for the code.

A bonus: In case you ever forget to remove a private function which you don’t use anymore it will be removed entirely by the Closure Compiler in the minified version of your plugin ;-)

Measuring the result

After refactoring the code, I ran the Closure Compiler again. Before the minified version of the plugin had 3729 bytes. After the refactoring it had 3475 bytes. That’s about 8% smaller. Hm, not quite a lot you’d say. But:

  • ImageColorPicker is a very small plugin anyway. If your plugin has a lot more private functions and / or uses them more frequently the savings will increase.
  • If you have thousands of hits per day, each percent you save in download size will save yourself or your company cash money.
DeliciousTwitterFacebookLinkedInRedditSlashdotTechnorati FavoritesDiggShare
Posted in JavaScript, jQuery | Leave a comment

Image Color Picker v0.1

Today I’m releasing my first jQuery plugin :-)

Read more about it here: Image Color Picker or check out the demo.

You can find the code on Github.

DeliciousTwitterFacebookLinkedInRedditSlashdotTechnorati FavoritesDiggShare
Posted in JavaScript, jQuery | Leave a comment