Sneaky Abstractions

Subscribe to my Feed, follow me on , recommend me on Working With Rails or see my code on GitHub

Scope in JavaScript

Posted on October 23, 2007 13:30 Tagged with javascript, scope.

I wrote this article a few weeks ago as a part of JavaScript Eye for the Ruby Guy but have forgotten to publish it.. So, here it is:

Scope in JavaScript

It’s not very long, because scope in JavaScript is really simple once you know how it works.

FormHelper

Posted on September 28, 2007 23:28 Tagged with javascript.

An unobtrusive "unobtrusive" answer to the very frequently asked question “how do I create a dropdown that fills out another dropdown”.

<select name="foo" class="updates:bar">
  <option value="1">1</option>
  <option value="2">2</option>
</select>
<select name="bar">
  <optgroup label="1" class="foo:1">
    <option value="1">1.1</option>
    <option value="2">1.2</option>
  </optgroup>
  <optgroup label="2" class="foo:2">
    <option value="3">2.1</option>
    <option value="4">2.2</option>
  </optgroup>
</select>

And it just works.

Download now for the low price of nothing and get one extra feature for no added cost! But wait, there’s more! Download within the next ten years and receive the practical Checker for free!

New

Posted on September 20, 2007 23:13 Tagged with javascript.

I always thought new Class was too much like Java..

Function.prototype.new = function(){
  function F(){};
  F.prototype = this.prototype;
  var o = new F();
  this.apply(o, arguments);
  return o;
};

function Cat (name) {
  this.name = name;
};

Cat.prototype.greet = function(){
  return "Hello, my name is " + this.name;
};

var garfield = Cat.new("Garfield");
garfield.greet(); // "Hello, my name is Garfield"

Just like Ruby! I know, I know, “new” is a reserved word.. For some reason it works just fine in Firefox, but you can just as well call it “create” or “spawn”, or “beget”. I’m sure it’s still a pretty bad idea to begin with, and I can’t see any advantages at all with it. It’s just that I have a strong dislike for keywords.

JavaScript Eye for the Ruby Guy

Posted on August 05, 2007 03:15 Tagged with javascript, ruby.

A while ago a number of articles were written under the common name Ruby Eye for the Java Guy, which explained Ruby from a Java programmer’s point of view. I’ve been meaning to do the same for JavaScript for a while, explaining JavaScript from a Ruby programmer’s point of view, but I kept, ehm, not doing it. I finally got around to writing it this weekend though, and I’ve put it up here:

JavaScript Eye for the Ruby Guy

As good as every Ruby programmer who uses Rails also uses JavaScript, but not many actually know how it works. I used to only care enough to make it work and dismissed JavaScript as unimportant, but I’ve since learnt how wrong I was. Many like me are starting to see it for what it really is – a little quirky but at the same time a fascinating and powerful language. There is currently a big drive towards using more unobtrusive JavaScript and Ajax techniques in web pages, and knowing how to actually program in JavaScript is definitely an advantage :)

The article is by no means comprehensive, but it should explain the most basic (and most interesting) stuff.

Sanskrit updates

Posted on July 21, 2007 19:41 Tagged with sanskrit, javascript.

(Sanskrit is the Rich Textile Editor)

I’ve been tweaking Sanskrit the last few days, as it used to have some problems. It used to be kind of flaky in Gecko because of a (not so) weird problem with dynamically inserting iframes. Turns out I had to make it wait a little bit longer in order for Gecko to initialise the iframe document before working with it, which I was hesitant to do at first because it makes it seem less lightweight. I’ve also added a “textile” menu button which will let you edit the Textile directly, much like traditional WYSIWYG editors like TinyMCE will let you edit HTML. All in all, it should be a bit more solid now, and might actually be considered fit for production :)

routes.js update

Posted on July 04, 2007 11:18 Tagged with routes, javascript.

I’ve made a few changes to the JavascriptRoutes plugin to make it Even Betterâ„¢. One of those changes is to check hasOwnProperty on parameters and options, and it has made it clear to me how important it is to not mess around with Object.prototype (or, make sure an object’s properties don’t come from somewhere in the prototype chain).

Before:

Object.prototype.iThinkEveryObjectShouldHaveThis = 'for sure';
Routes.generate({controller:'lolcats', action:'show', id:1}, {onlyPath:true})
// => "/lolcats/1?iThinkEveryObjectShouldHaveThis=for%20sure"

Now:

Object.prototype.iThinkEveryObjectShouldHaveThis = 'for sure';
Routes.generate({controller:'lolcats', action:'show', id:1}, {onlyPath:true})
// => "/lolcats/1"

This also means the plugin won’t work in browsers that don’t have the hasOwnProperty method. Those that I know of that don’t have this are Safari 1.3 and IE 5.0. It also uses try-catch, which was only introduced in JavaScript 1.5. If enough people complain, I might try to change this.

routes.js, episode two: The Plugin

Posted on June 29, 2007 16:50 Tagged with routes, javascript, plugin, rails.

Now with all routes created equal (not just named routes anymore).

It turns out replicating Rails’ route generation in JavaScript wasn’t trivial, but it was definitely doable and it seems to work pretty well too. I’ve packaged it up in a plugin for easy consumption. Read more about it here.

Routes.generate({controller:'foo', action:'bar', id:'baz'})
Routes.page(1)
Routes.blog_entry_comment(1, 2)
Routes.page({id:42}, {onlyPath:true, escape:false})
Routes.generate({controller:'rabbits', rabid:'yes'})

You can test the route generation “live” here, or if you have FireBug installed, just use that.

ActsAsMonkey, a sample Rails plugin

Posted on June 21, 2007 01:17 Tagged with rails, plugin.

After seeing a lot of people ask for information on writing plugins to Rails, I wrote a sample plugin so people could take a peek inside and see how it’s built. It may not be the World’s Best Plugin, and you can see how any plugin is built, but it should cover the basics, and I’ve tried to comment it where (I think is) necessary.

More here.

ActsAsFile: Simple file storage plugin

Posted on June 14, 2007 16:00 Tagged with acts_as_file, plugin, rails.

ActsAsFile will save files attached to a model in a specified directory on the file system. It will add validation errors on the model if the file can’t be saved. And.. I think that’s it. As I said, it’s simple, and I like simple. Read more about it here.

class UploadedFile < ActiveRecord::Base

  acts_as_file
  
  self.save_path = File.join(RAILS_ROOT, 'public', 'uploads')
  self.read_path = 'uploads'

end

routes.js

Posted on June 09, 2007 22:55 Tagged with routes, rails, javascript.

Update: I’ve put this in a plugin which also includes non-named routes, here.

If you’re writing unobtrusive JavaScript with Rails, figuring out URLs can sometimes be a bit of a show stopper. I’ve hard-coded URLs into my JS files more than once, and that smells. Wouldn’t it be just terrific if we could access Rails’ routes in JavaScript? Well, it turns out that’s not so difficult to achieve. Just put this in environment.rb:

File.open(File.join(RAILS_ROOT, 'public', 'javascripts', 'routes.js'), 'w') do |file|
  file << "var Routes = {\n"
  ActionController::Routing::Routes.named_routes.routes.each do |name, route|
    dynamic_segments = route.segments.select{|s| s.respond_to?(:key) }
    file << "  #{name}: function(#{dynamic_segments.map(&:key).join(', ')}) {\n"
    file << "    return '"
      route.segments.each do |segment|
        if segment.respond_to?(:key)
          file << "'+#{segment.key}+'"
        else
          file << segment.to_s
        end
      end
    file << "';\n"
    file << "  },\n\n"
  end
  file << "};"
end

It only works for named routes, but if you’re RESTful that should be enough. Getting “normal” routes in there should be possible, but it basically means you’d have to replicate the route recognition generation system in JavaScript, which I think would be non-trivial.

How to use it? Well, first of all, include routes.js:

<script src="/javascripts/routes.js" type="text/javascript"></script>

All the named routes will be defined as functions on the Routes object, and each function takes 0 or more parameters. They work pretty much like the generated helper methods in Rails. Let’s say we have these routes defined in routes.rb:

map.resources :articles
map.home '', :controller => 'main'

To generate the URLs in JavaScript, we’d use:

Routes.articles() // => "/articles/"
Routes.article(1) // => "/article/1"
Routes.home() // => "/"

1 2 3 4 5

There were giants in the earth in those days, they were men of old, men of renown