My Web Log Book

Implementing an EventBus in MooTools

An event bus can be useful in making your web applications more maintainable and manageable. It does so by decoupling the source of the application events from their destination. In complex web applications, a change in one part of the screen might require other parts of the screen to update as a result.

A big part of this manageability comes with using custom events that are closer to our domain model than ‘clicks’, or ‘mouseovers’. If you have any doubts about the usefulness of custom events, you might want to read this article first.

A very common example of such a custom event is user registration. Once a user registers on a site, and assuming they are automatically logged-in right after, then various parts on the screen will need to be updated as a result. A registration successful message pops-up somewhere. The navigation panel is updated with a Logout link. Other things that only registered users can do will get activated.

If your application is highly modularized into widgets, views, etc., then you might not want to create an unnecessary binding between those components just because they need to listen to a particular event that some other component happens to fire. All that a widget needs to know is that an event of interest has fired, regardless of the source (for most cases), and that it must respond to it. Ray Ran gives a nice example with a full walkthrough in his talk at Google I/O and explains how an EventBus solves the problem. I highly recommend watching the talk since the problem and solution that he demonstrates is very much applicable to any complex web application and not just apps written in Google Web Toolkit. An event bus acts as a central broker for communicating events to various parts of the application that need not know about each other’s presence. It basically publish-subscribe and somewhat similar to the NSNotificationCenter in Cocoa if you’re familiar with that.

Once you are thoroughly convinced that you absolutely need this, you would really like the solution too if you’re using MooTools. Why? checkout for yourself -

var EventBus = new Class({Implements: Events});

1 line. That’s all that you need to start using an EventBus. MooTools classes can already handle events by implementing Events in Class.Extras. All that is need is creating an object of a class that does this and passing it around to whoever needs is using dependency injection and each object can register and post their events to this event bus.

Here’s a small example that makes use of this event bus with a couple of different types of classes:

Here’s a tiny wrapper around the EventBus class above. All it does is change the names addEvent, removeEvent, and fireEvent to be a little more semantic with observers. Nothing fancy.

Controlling a MooDialog of an existing element programatically

MooDialog is a very nice Javascript plugin for creating your own dialog boxes that are much better looking than the native confirms, alerts, and prompts. The plugin offers much more in functionality and can be used to create dialog boxes with an iframe’s content, ajax responses, and existing DOM elements among others.

Once created, these dialog boxes can be programmatically opened, closed, or disposed off. The online documentation is very well written, but it doesn’t mention how would you open or close a dialog that was created using an existing DOM element.

To create a dialog from an existing element, we would just call .MooDialog() on the element.

<div id="myElement">
  ...
</div>

$('myElement').MooDialog(); // that's all

However, since this method call simply returns myElement (for chaining purposes, I believe) and not the MooDialog object, we cannot call open() and close() on it. The plugin has a brilliant solution to take care of the problem - the Element store.

The dialog object is stored with the key “MooDialog” into the element store. So to get access to the dialog object for “myElement”, simply call retrieve(‘MooDialog’) on it.

var dialog = $('myElement').retrieve('MooDialog');
dialog.open();
dialog.close();

Chrome includes site search from the address bar

Google Chrome has a nice little feature that allows using a website’s own search through Chrome’s address bar directly.

For example, a query like “railscasts.com openid” will automatically goto railscasts.com and perform a search on that site itself.

The search is being performed in the site itself, and the local search box is populated with the query that was typed in Chrome’s address bar.

Google is parsing the search forms from various sites and providing direct access to those through the address bar. I’ve seen this work for all sites that do contain a identifiable search box, but not on sites that do not have any search capabilities.

Long live Chrome!

GWT project is resurrected after upgrade to 2.0

After upgrading to GWT 2.0, my project suddenly stopped compiling. Almost 4 hours into the problem, but its finally solved!

I was using the Base64 class in Apache Commons Codec library for some base64 encoding. GWT includes the commons codec package but an older version of Base64 which didn’t have the encodeToString(byte[]) method in it that I was using. Had to reorder the jars to get it working again.

MooTools class keyword breaks in Safari

Having test the app in Chrome and Firefox, I happily strolled to Safari in a delightful mood only to find a blank page and JavaScript errors, yikes. After some digging on Google, I found the problem. Safari is not only backward compliant but forward compliant too. The class keyword that is very often used while creating an Element in MooTools is a future reserved keyword in ECMAScript language specification ECMA-262. Don’t believe me? Check it out for yourself at http://www.ecma-international.org/publications/standards/Ecma-262.htm

Not a huge problem and we have to quote the class keyword. So something like this:

var container = new Element("div", {class: "link"});

now becomes this. Note the quotes around class

var container = new Element("div", {"class": "link"});

And we’re good to go!

Adding custom scrollbar-less scrolling with MooTools

This is a tiny class that adds scrolling capabilities with just a mouse wheel to any element in MooTools. Could not use the Slider class as I wanted it to be really lightweight, rather flyweight. Just remember, there are no bars - only content that can be scrolled with a mousewheel.

To use, pass in an Element and an options object. The options object only takes one parameter “direction” which may be “horizontal” or “vertical”. The default value is vertical.

var scrollable = new Scrollable($("#content"));

And the actual class.

/*
 * Makes any Element scrollable. The element needs to have the overflow property as "auto".
 * This is a lightweight class, and does not require any libraries other than Core.
 *
 * To use, create a new Object of Scrollable, and pass in an Element.
 * var scrollable = new Scrollable($('div'));
 *
 * @Author Anurag Mishra
 * @Date Jan 13, 2010
 *
 */
var Scrollable = new Class({
	Implements: Options,
	options: {
		direction: "vertical"
	},
	/*
	 * @param content Element the element that is to be made scrollable.
	 * @param options Options optional hash to indicate direction of scroll. Possible
	 * values are "horizontal" or "vertical". The default value is "vertical".
	 */
	initialize: function(content, options) {
		this.setOptions(options);
		this.content = content;
		this.content.addEvent("mousewheel", this.onScroll.bind(this));
	},
	pickValue: function(horizontal, vertical) {
		return this.isVerticalScroll() ? vertical : horizontal;
	},
	onScroll: function(event) {
		var stepSize = this.getScroll() - event.wheel;
		if(this.isVerticalScroll()) {
			this.content.scrollTo(0, stepSize);
		}
		else {
			this.content.scrollTo(stepSize, 0);
		}
	},
	getContent: function() {
		return this.content;
	},
	getScroll: function() {
		return this.pickValue(this.content.getScroll().x, this.content.getScroll().y);
	},
	isVerticalScroll: function() {
		return this.options.direction == "vertical";
	},
	isHorizontalScroll: function() {
		return !this.isVertical();
	}
});

Insert and Delete for Javascript Arrays

Javascript is an awesome language but lacks some useful API’s such as for Arrays. Insert and delete at a particular position are two very basic array operations that can be done by using the splice method. I didn’t even know what splice meant till I bumped across Javascript Arrays. Now Array can be easily extended to do that using prototype, but a better home for such methods and wrappers is in the core language itself.

For the time being, it’s easy to create wrappers that use splice under the hood.

// Insert element at the given index in array
Array.prototype.insert = function(element, index) {
	this.splice(index, 0, element);
}
// Remove the element at the given index
Array.prototype.remove = function(index) {
	this.splice(index, 1);
}

Project Euler Problem 24

Used the algorithm on Wikipedia at http://en.wikipedia.org/wiki/Permutation#Lexicographical_order_generation. It’s a generic method that takes any arbitrary list and the desired permutation number k.

Problem Statement

A permutation is an ordered arrangement of objects. For example, 3124 is one possible permutation of the digits 1, 2, 3 and 4. If all of the permutations are listed numerically or alphabetically, we call it lexicographic order. The lexicographic permutations of 0, 1 and 2 are:

012   021   102   120   201   210

What is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9?

require "fixnum.rb" # Fixnum.factorial
def permutation(k, list)
  size = list.size
  factorial = (size-1).factorial
  result = []

  while result.size != size
    x = k / factorial
    x -= 1 if (k % factorial).zero?
    result << list.delete_at(x)
    k = k % factorial
    factorial = (list.size - 1).factorial
  end
  result
end

puts permutation(1000000, [0,1,2,3,4,5,6,7,8,9]).join

Project Euler Problem 23

This problem required generating all “abundant” numbers below the specified limit, and then canceling out those that could not be reached by adding up any two abundant numbers from the generated list.

A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.

A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.

As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.

Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.

Solution in Ruby:

require "mathn"
require "set"
require "fixnum.rb" # for Fixnum.factor?
require "array.rb" # for Array.sum

abundant = []
all = (1..max).to_set
sum_of_abundant_numbers = Set.new
max = 28123

# find all abundant numbers
(1..max).each do |n|
  factors = Set.new
  (1..Math.sqrt(n)).each do |f|
    if n.factor?(f)
      factors << f
      factors << (n/f) unless f == 1
    end
  end
  abundant << n if factors.to_a.sum > n
end

# find sum of all abundant number pairs
abundant.each do |a|
  abundant.each do |b|
    break if a + b > max
    sum_of_abundant_numbers << a + b
  end
end

all = all - sum_of_abundant_numbers
puts all.to_a.sum

One liner for Project Euler problem 20

I was needlessly worrying about about the capabilities of Bignum in being able to handle this factorial which has 158 digits in its result. Wasn’t an issue at all though.

Ruby certainly brings conciseness to the code. It maybe possible in a lot lesser characters in J or other functional languages, but this is good enough for me for the time being.

The problem statement is

Find the sum of the digits in the number 100!

Solution in Ruby

puts (1..100).to_a.inject{|prod, n| prod * n}.to_s.split(//).map{|d| d.to_i}.inject{|sum, n| sum + n}

Edit: even shorter with the reduce method in Ruby 1.9

(1..100).reduce(:*).to_s.split(//).map{|d| d.to_i}.reduce(:+)