Skip to content

1. JavaScript Generator

MadRabbit edited this page Sep 13, 2010 · 4 revisions

RightRails provides a new JavaScript generator, which is more flexible and lets write most of the calls in ruby practically the same way as you would do it in JavaScript.

The key difference is that new generator doesn’t have just a list of predefined methods, but instead of that it kinda mocks the usual JavaScript programming process and provides you an access to virtually any functions and objects on your page in Ruby. Like that

rjs do |page|
  page[@record].update(render(@record)).show.highlight('blue')
  page.my_function('boo', 'boo', 'boo')
  page.my_variable = nil
  page['some_element'].select('div.zing').each do |element, index|
    element.innerHTML = @my_local_text
    element.setAttribute('id', "that-div-"+ index);
  end
end

Working with this generator you always have access to your template level variables and you don’t need to worry about type conversions, just feed the thing with what you’ve got and it will automatically figure out what to do with that.

Types Conversion Principles

When you assign value or send it to a method, the type of value will be automatically converted, by usual principle, strings to strings (will be automatically escaped), numbers to numbers, booleans to booleans, nils to nulls, blocks and lambdas to functions, arrays and hashes to JavaScript arrays and hashes. And then if your variable a JSON exportable it will try that too.

The only exception is symbols. Symbols are used to refer to the javascript level variable names, so when you say something like this

page[@record].onClick('hide')

it will hide the element on click, but when you say
page[@record].onClick(:hide)

it will assume you have a global function called hide and it will pass it as an argument, like that
$('record-1').onClick(hide);

Attributes, methods and functions access

When you do usual calls in your template, following the same principle as Ruby language you perform a method or function call

page.my_function
page.another_function(1,2,3)

will be converted in calls like that
my_function();
another_function(1,2,3);

But when you do the same with the assign symbol it assumes you change an attribute or a global variable.
page.my_var = 1
page.find_that.attribute = 2

This will be converted into the following code
my_var = 1;
find_that().attribute = 2;

Note that it’s not creating a new variable my_var but reassign the existing one. If you need to actually create a new variable you do it by using the get and set methods
page.set('my_var', 1)
page.alert page.get('my_var')

As the result you will have this
var my_var = 1;
alert(my_var);

You also can mix the approaches and assign not just values out of the Ruby context but results of the JavaScript expressions and even mix of them.
page['element'].innerHTML = page.get('my_string_variable')
page['element'].innerHTML = page['another-element'][:innerHTML]
page['element'].innerHTML = page['another-element'][:innerHTML] + @my_ruby_string

Yes, you can read and refer your javascript object attributes via the [:name] construction.

Predefined Methods

There are number of predefined methods that the generator knows.

NOTE: methods that generate JavaScript all works through the RR JavaScript interface and mostly just feed JavaScript methods with strings of HTML. All the actual work, like dom-manipulations and visual effects happens inside the interface.

NOTE: the record to dom-id conversions happen though the rails native dom_id method and the scripts expect you was following the rails conventions for the element IDs.

  • [record_or_id] – reference to an element on the page, if an ActiveRecord was used as the attribute then it will be converted into a corresponding dom-id
    page['element-id']
    page[@record]
  • <<(String code) – for embedding a raw JavaScript code
    page << 'if (something) do_something_about_that();'
  • find(String css_rule) – selects all the elements on the page that match the css-rule
    page.find('div.zing').each('remove')
  • get(String name) – returns a reference to the page’s global variable
    page[@record].innerHTML = page.get('my_variable_with_content')
  • set(String name, any value) – defines a new JavaScript variable
    page.set('my_var', @my_value)
  • redirect_to(mixed url) – creates a redirection script
    page.redirect_to home_path
    page.redirect_to :action => 'boo'
  • reload – creates a page reloading script
  • insert(ActiveRecord record[, String position]) – automatically renders the record with a corresponding partial template and then generates a JavaScript code that will insert the piece of HTML into an element on the page that has the same ID as the record table name. So that say
    page.insert(Zing.create(:id => 1))

    this will generate a piece of HTML from the _zing template and insert the result into an element on the page that has the zings id. Optionally you can specify where to insert this new element 'top', 'bottom'
  • replace(ActiveRecord record) – automatically render the record with a corresponding partial template and then generates a JavaScript code that will find a page element with the same dom-id and replace it with a new content
    page.replace(@zing)
  • remove(ActiveRecord record) – generates a script that will remove an element on the page that has a corresponding dom-id for the record
    page.remove(@zing)
  • update_flash([String content=nil]) – updates an element with the #flashes ID on the page. It calls the flashes method for content, or you optionally can pass your own content as the attribute
    page.update_flash
  • show_form_for(ActiveRecord record) – will automatically generate a piece of HTML from the _form partial and create a JavaScript that will insert it into an element that corresponding to the record. Used for AJAX elements editing.
    page.show_form_for(@zing)
  • replace_form_for(ActiveRecord record) – will automatically generate a new form HTML for the record and create a JavaScript code that will replace the old form with the new one. Used for remote form submits handling.
    page.replace_form_for(@zing)
  • insert_and_care(ActiveRecord record[, String position]) – a shortcut for insert + update_flash + replace_form
  • replace_and_care(ActiveRecord record) – a shortcut for replace + update_flash