UPDATE: JavascriptGenerator has a method name literal that will do the exact same thing, so the code below should do the trick:

 page.insert_html :bottom, page.literal("$$('p.welcome b').first()"), "Some item" 

Bill Burhcam over at Meme Rocket made a post that almost solved a problem for me the other day. We're currently doing some work that ends up creating html. Pretty standard stuff, but for a few reasons that aren't really worth going into we can't easily rely on our element ids being unique. The prototype functions 'up' and 'down' are perfect for this situation though.

So our problem basically boils down to this - RJS converts this code:

page.insert_html :bottom, "$$('p.welcome b').first()", "Some item" 

into this javascript:

 new Insertion.Bottom("$$('p.welcome b').first()", "Some item" 

Because the $$('p...') is in quotes, Insertion.Bottom just looks for an element with that id. Which isn't what we really wanted.

After digging around in the ActionView source for a while I found JavascriptGenerator::GeneratorMethods and its javascript_object_for method. It turns out that if you pass in a ActiveSupport::JSON::Variable then insert_html will behave how we want. So for the example above, the code below will work as expected.

 js_literal = "$$('p.welcome b').first()" js_literal = ActiveSupport::JSON::Variable.new(js_literal) page.insert_html :bottom, js_literal, "Some item" 

will output:

 new Insertion.Bottom($$('p.welcome b').first(), "Some item" 

Thank you open source.