Monthly Archives: October 2011

jQuery Logo

jQuery Chaining

jQuery is the jewel in the crown that is web development. Once you discover it, Javascript is no longer a chore to write, hell, it might even be considered fun! Sure being able to select elements by ID, class, or type is great, but what about all the other stuff? What about chaining? I’ve heard such great stuff about it!

Chaining

The first thing you need to know about chaining is that you chain actions on to collections. A collection is what is returned when you select something using jQuery.

$("input");  //Collection of all input elements on the page.

When most people start using jQuery, they do something like this:

$("input").val("123");
$("input").addClass("awesome");
$("input").attr("data-bind", "15");

Yes, this code will work, but it’s inefficient. Every time you perform a selection, jQuery must traverse the DOM and find all the input elements. If you use chaining, it will simply use the collection of input elements that it already has.

$("input")
	.val("123")
	.addClass("awesome")
	.attr("data-bind", "15");

So why does this work? Because each method that you call in the chain returns the collection. So in this case “val()”, “addClass()”, and “attr()” all return “$(input)”. However, not all methods support chaining. For instance, the “text()” method breaks the chain, so if you’re going to use it, do it at the end.
What if you want to keep the chain alive though? No problem. You can simply back-out of the destructive action using the “end()” method.

Before

<ol id='mylist'>
	<li>
	</li>
	<li>
	</li>
	<li>
	</li>
</ol>

Javascript

$('#mylist')
	.find('>li')
		.filter(':last')
			.addClass('Meow')
		.end()
		.filter(':first')
			.addClass('Mix')
		.end()
		.addClass('catfood')
	.end()
	.addClass('thelist');

After

<ol id='mylist' class='thelist'>
	<li class='Mix catfood'>
	</li>
	<li class='catfood'>
	</li>
	<li class='Meow catfood'>
	</li>
</ol>

While sometimes confusing, you can see that chaining is often the most efficient way to handle modifying the DOM.

Writing Chainable Plugins/Functions

Now that you know all about chaining, you’ll probably want to write your own chainable plugins/functions. It’s very easy to do this, since all you need to do is return the jQuery object at the end of the function.

In this example, we’ll write a plugin that attaches a second counter to an element.

Plugin

(function($) {
	$.fn.count = function() {
		return this.each(function() {  //We do an 'each', because the collection may have more than one item in it.
			var self = $(this);  //
			self.html('0');
			var theInterval = window.setInterval(function() {
				var c = parseFloat(self.text());
				self.html(c + 1);
			}, 1000);
		});
	}
}) (jQuery);

HTML

<div>
	<span id='test'></span>
</div>

Execution

$("#test").count().parent().addClass('counters'); //Chaining still works :)

PHP Dark Arts: References

Remember the first time you dabbled in C?  Oh, the glorious typing, functions, and structs!  Now do you remember the first time you ran in to a pointer?  ‘*’, ‘&’, ‘->’ all made your hurt, but eventually you figured it out.  It’s fortunate (depending how you look at it) that we don’t have need to dabble with pointers or references while web programming these days.  However, PHP does allow us to passing things around by reference.  It’s not used often, but when used correctly can be very beneficial to the quality of your code.

What are PHP references?

The first thing you need to know about PHP references is that they are not C references.  You can’t do pointer arithmetic on them because they aren’t actually addresses.  In PHP references are actually symbol table aliases.  This means that you can have 2 variable names sharing the same variable content.

What can you do with references?

There are 3 things that you can do with PHP references.

  • Assign by reference.
  • Pass by reference.
  • Return by reference.
$x =& $y;
$x = 3;
echo "X: $x, Y: $y";

The above code sets $x and $y’s references to the same content area. Therefore, when $x is assigned 3, $y has access to the same data.

function add_item(&$item) {
   	$item++;
}
 
$totalItems = 0;
for($i = 0; $i <; 5; $i++) {
	add_item($totalItems);
}
echo "Total items: $totalItems";

This code allows you to modify a variable’s value without ever returning anything. In this example I made a simple counter, but you can set the value of $item to anything and it should work out just fine.

class Test {
	public $count = 0;
 
	public function &getCount() {
		return $this->count;
	}
}
 
$t = new Test();
$value = &$t->getCount();
$t->count = 25;
echo $value;

This code returns a reference to the public $count variable of the Test class. Generally this isn’t best practice, as it lowers the readability of the code.

Unsetting References

In the event that you want to free a variable from it’s reference to another, you can simply use the unset function.

$x =& $y;
unset($x);

Fixing DreamHost’s Django Deployment Script

I recently created a trivial site locally with Django that I wanted to deploy on my DreamHost shared server.  DreamHost has made this process pretty painless by creating an easy-to-follow guide that can be found here.  The only problem is that it doesn’t work.  After entering in my project name and database info, i got the error message:

Creating project framework…  oops, django-admin failed to run!

With nothing to lose (and not wanting to figure out how to get Passenger set up on my own), I dove into their django-setup.py script.  As it turns out, the problem is on line 126.

if os.spawnl(os.P_WAIT, "/usr/bin/django-admin.py", "django-admin.py", "startproject", projname) != 0:

Apparently on DreamHost, django-admin.py has dropped the extension. So if you replace line 126 with the following, everything works great.

if os.spawnl(os.P_WAIT, "/usr/bin/django-admin", "django-admin", "startproject", projname) != 0: