Dr Nic

Prototype: “element-id”.$() instead of $(‘element-id’)

The Prototype library gives us the $() operation for converting a DOM element id into the DOM element: $('element-id'). It also appends a bunch of functions to the resulting object; as shown previously, you can add your own methods.

Sometimes though, passing a string into the $() function doesn’t read well; and only makes Javascript code harder to read. For example: $(window.button_list()[3]).hide()

Instead, it’d be nice to have normal chainability. I like the following syntax: window.button_list()[3].$().hide().

That is, call the $() method on a string object, instead of passing the string into the $() method.

Add this code into your application:

String.prototype.$ = function() {
  return $(document.getElementById(this));
}

UPDATE: After discussion on Ruby on Rails: Spinoffs forum

Alternate version:

String.prototype.$ = function() {
  return $(String(this));
}

But what doesn’t work is:

String.prototype.$ = function() {
  return $(this);
}

Let us know if you know why $(this) returns an array of single character strings (e.g. ["e","l","e","m","e","n","t","-","i","d"] for "element-id".$()?!

Extend Prototype $() yourself

If you’re using the prototype javascript library, its fun to add methods directly to the $() object.

So instead of typing:

new Effect.Move($('target-obj-name'), {x: 40, y: 50, mode: 'absolute'});
new Effect.Pulsate($('target-obj-name'));

You could type:

$('target-obj-name').moveTo(40,50).pulsate();

Much sexier. You could add any methods you want to $() to do anything you need to do in your application. Just reproduce the example below in a Javascript file (say prototype-extensions.js and include it in your web pages, using <script src="prototype-extensions.js"></script>):

Element.Methods.moveTo = function(element,x,y) {
    new Effect.Move(element, {x: x, y: y, mode: 'absolute'});
    return element;
}
Element.Methods.pulsate = function(element) {
  new Effect.Pulsate(element);
  return element;
}

Element.addMethods();

The methods you want to add to $() need to be added to the Element.Methods hash (so in the example above, Element.Methods.moveTo and Element.Methods['moveTo'] are equivalent in Javascript), with the first argument of the function being the target element.

Finally, you need to formally tell Prototype that these methods must be added into future $() objects, using the command Element.addMethods().

Now you can add any method to your $() objects that you want. Just like magic.

Foreign tourists to your websites (part 2)

As a follow-up to the recent “Spy on the Japanese” post, you might want a nice set of links for your visitors to translate your page sinto their language.

But, here are your requirements (I can read your mind, I’m a doctor):

  • You know what countries visit your site, so you want to configure it yourself.
  • Since it requires Javascript to be turned on for it to work, you don’t want the links to show if the visitor doesn’t.

Solution: create the links using Javascript.

To allow translations of your blogs/websites via Google Translation, add the following inline Javascript into the sidebar. It was designed for WordPress – you may need to twiddle with the DOM elements created and/or CSS if it looks bad on your site.

The flags can be found at: http://www.famfamfam.com/lab/icons/flags/, and I’ve assumed you’ll store the png images in the /images/flags/ folder. If you store them somewhere else, change the images variable at the top of the script.

So, paste this script into your sidebar and you are saying “Aliens Welcome Here” [1].

      <script>
        // Each lang in an array: [google lang code, flag name, language name]
        // Flags available at: http://www.famfamfam.com/lab/icons/flags/
        var to_langs  = [['ja', 'jp', 'Japanese'],
                         ['de', 'de', 'German'],
                         ['es', 'es', 'Spanish']];
        var from_lang = 'en';
        var images     = '/images/flags/';

        document.write("<li id='translation'></li>");
        var liDiv = document.getElementById('translation');
        var title = document.createElement("h2");
        title.appendChild(document.createTextNode("Translation"));
        liDiv.appendChild(title);
        var ulDiv = document.createElement("ul");
        liDiv.appendChild(ulDiv);
        for (var i=0; i < to_langs.length; i++) {
          var to_lang = to_langs[i][0];
          var flag    = to_langs[i][1];
          var name    = to_langs[i][2];
          liDiv = document.createElement('li');
          ulDiv.appendChild(liDiv);
          liDiv.innerHTML = "<a href='#' onclick=\"location.href=" +
            "'http://translate.google.com/translate?langpair=" +
            from_lang + "&" + to_lang + "&hl=" + to_lang +
            "&ie=UTF-8&oe=UTF-8&u='" +
            " + encodeURIComponent(location.href)\">" +
            "<img border=0 src='" + images + flag + ".png' /> " + name + "</a>";
        }
        var getme = "<a href='http://drnicwilliams.com/2006/08/30/foreign-tourists-to-your-websites-part-2/'>How to translate my site?</a>";
        var getme_li = document.createElement("li");
        getme_li.innerHTML = getme;
        ulDiv.appendChild(getme_li);
      </script>

[1] Americans mightn't know that when foreigners visitor your country, we are presented with paperwork to fillout that refers to us as Aliens. Perhaps your government never watches its own Hollywood movies, but this isn't the best phrase to use, I think. Not very welcoming.

Yehuda Katz starts a blog

Yehuda is the creator of autoDB – the wonderful admin console for Rails – and Visual jQuery – a dazzling set of documentation for the jQuery javascript library. I think many Prototype/Scriptaculous/Rails users would like to see their documentation be as attractive and complete as the Visual jQuery docco. (Which is generated from the jQuery libraries and marked up via XLS translation).

Fortunately, he’s started a blog.

We’ve had lots of discussions together about many topics over recent times, and anyone who places me at the top of their blogroll, must be a good bloke. :)

[ANN] Spy on the Japanese Rubists

Their Ruby code is surrounded by a shrouded of Japanese symbols. You know there is gold in there, but its left to the reader to interpret the purpose of the article. Happy Japanese man? Cranky Japanese man?

The creator of Ruby is Japanese, the Rubist magazine is in Japanese, and a great many users of Ruby are Japanese, yet I can’t understand a word they are saying. That’s not their fault. It’s my French teacher’s fault.

Wonder no longer. Thanks to Google Translate’s Japanese to English translation and the Bookmarklet feature of Firefox (and other browsers?)

Drag this Bookmarklet into your links toolbar, and start spying on the Japanese.

Bookmarklet: Spy on Japanese

Want to spy on the Germans? Drag it again, and change the embedded url. Look for the langpair=ja&en and change ja to de. (Cheat: Spy on Germans)

Want to encourage our Japanese friends to spy on you? Perhaps add links on your pages for instant translations from English to Japanese (change ja -> en, and en -> ja), and change the hl=en to hl=ja.

<a href="#" onclick="location.href='http://translate.google.com/translate?langpair=en&ja&hl=ja&ie=UTF-8&oe=UTF-8&u=' + encodeURIComponent(location.href)">Translate into Japanese</a>

Test this here: