Module: ActionView::Helpers::PrototypeHelper::JavaScriptGenerator::GeneratorMethods

Defined in:
lib/action_view/helpers/prototype_helper.rb,
lib/action_view/helpers/scriptaculous_helper.rb

Overview

JavaScriptGenerator generates blocks of JavaScript code that allow you to change the content and presentation of multiple DOM elements. Use this in your Ajax response bodies, either in a <script> tag or as plain JavaScript sent with a Content-type of "text/javascript".

Create new instances with PrototypeHelper#update_page or with ActionController::Base#render, then call insert_html, replace_html, remove, show, hide, visual_effect, or any other of the built-in methods on the yielded generator in any order you like to modify the content and appearance of the current page.

Example:

Generates:

new Element.insert("list", { bottom: "
  • Some item
  • " });

    new Effect.Highlight("list");

    ["status-indicator", "cancel-link"].each(Element.hide);

    update_page do |page| page.insert_html :bottom, 'list', "

  • #@[email protected]
  • " page.visual_effect :highlight, 'list' page.hide 'status-indicator', 'cancel-link' end

    Helper methods can be used in conjunction with JavaScriptGenerator. When a helper method is called inside an update block on the page object, that method will also have access to a page object.

    Example:

    module ApplicationHelper
    def update_time
      page.replace_html 'time', Time.now.to_s(:db)
      page.visual_effect :highlight, 'time'
    end
    end
    
    # Controller action
    def poll
    render(:update) { |page| page.update_time }
    end
    

    Calls to JavaScriptGenerator not matching a helper method below generate a proxy to the JavaScript Class named by the method called.

    Examples:

    Generates:

    Foo.init();

    update_page do |page| page.foo.init end

    Generates:

    Event.observe('one', 'click', function ()

    $('two').show();

    );

    update_page do |page| page.event.observe('one', 'click') do |p| p.show end end

    You can also use PrototypeHelper#update_page_tag instead of PrototypeHelper#update_page to wrap the generated JavaScript in a <script> tag.

    Instance Method Summary collapse

    Dynamic Method Handling

    This class handles dynamic methods through the method_missing method

    #method_missing(method, *arguments) ⇒ Object (private)

    
    
    566
    567
    568
    # File 'lib/action_view/helpers/prototype_helper.rb', line 566
    
    def method_missing(method, *arguments)
      JavaScriptProxy.new(self, method.to_s.camelize)
    end

    Instance Method Details

    #<<(javascript) ⇒ Object

    Writes raw JavaScript to the page.

    Example:

    page << "alert('JavaScript with Prototype.');"

    
    
    500
    501
    502
    # File 'lib/action_view/helpers/prototype_helper.rb', line 500
    
    def <<(javascript)
      @lines << javascript
    end

    #[](id) ⇒ Object

    Returns a element reference by finding it through id in the DOM. This element can then be used for further method calls. Examples:

    page['blank_slate']                  # => $('blank_slate');
    page['blank_slate'].show             # => $('blank_slate').show();
    page['blank_slate'].show('first').up # => $('blank_slate').show('first').up();
    

    You can also pass in a record, which will use ActionController::RecordIdentifier.dom_id to lookup the correct id:

    page[@post]     # => $('post_45')
    page[Post.new]  # => $('new_post')
    
    
    251
    252
    253
    254
    255
    256
    257
    258
    # File 'lib/action_view/helpers/prototype_helper.rb', line 251
    
    def [](id)
      case id
        when String, Symbol, NilClass
          JavaScriptElementProxy.new(self, id)
        else
          JavaScriptElementProxy.new(self, ActionController::RecordIdentifier.dom_id(id))
      end
    end

    #alert(message) ⇒ Object

    Displays an alert dialog with the given message.

    Example:

    Generates: alert('This message is from Rails!')

    page.alert('This message is from Rails!')

    
    
    423
    424
    425
    # File 'lib/action_view/helpers/prototype_helper.rb', line 423
    
    def alert(message)
      call 'alert', message
    end

    #assign(variable, value) ⇒ Object

    Assigns the JavaScript variable the given value.

    Examples:

    Generates: my_string = "This is mine!";

    page.assign 'my_string', 'This is mine!'

    Generates: record_count = 33;

    page.assign 'record_count', 33

    Generates: tabulated_total = 47

    page.assign 'tabulated_total', @total_from_cart

    
    
    491
    492
    493
    # File 'lib/action_view/helpers/prototype_helper.rb', line 491
    
    def assign(variable, value)
      record "#{variable} = #{javascript_object_for(value)}"
    end

    #call(function, *arguments, &block) ⇒ Object

    Calls the JavaScript function, optionally with the given arguments.

    If a block is given, the block will be passed to a new JavaScriptGenerator; the resulting JavaScript code will then be wrapped inside function() { ... } and passed as the called function's final argument.

    Examples:

    Generates: Element.replace(my_element, "My content to replace with.")

    page.call 'Element.replace', 'my_element', "My content to replace with."

    Generates: alert('My message!')

    page.call 'alert', 'My message!'

    Generates:

    my_method(function()

    $("one").show();

    $("two").hide();

    );

    page.call(:my_method) do |p| p.show p.hide end

    
    
    474
    475
    476
    # File 'lib/action_view/helpers/prototype_helper.rb', line 474
    
    def call(function, *arguments, &block)
      record "#{function}(#{arguments_for_call(arguments, block)})"
    end

    #delay(seconds = 1) ⇒ Object

    Executes the content of the block after a delay of seconds. Example:

    Generates:

    setTimeout(function()

    ;

    new Effect.Fade("notice",{);

    }, 20000);

    page.delay(20) do page.visual_effect :fade, 'notice' end

    
    
    514
    515
    516
    517
    518
    # File 'lib/action_view/helpers/prototype_helper.rb', line 514
    
    def delay(seconds = 1)
      record "setTimeout(function() {\n\n"
      yield
      record "}, #{(seconds * 1000).to_i})"
    end

    #draggable(id, options = {}) ⇒ Object

    Creates a script.aculo.us draggable element. See ActionView::Helpers::ScriptaculousHelper for more information.

    
    
    250
    251
    252
    # File 'lib/action_view/helpers/scriptaculous_helper.rb', line 250
    
    def draggable(id, options = {})
      record @context.send(:draggable_element_js, id, options)
    end

    #drop_receiving(id, options = {}) ⇒ Object

    Creates a script.aculo.us drop receiving element. See ActionView::Helpers::ScriptaculousHelper for more information.

    
    
    256
    257
    258
    # File 'lib/action_view/helpers/scriptaculous_helper.rb', line 256
    
    def drop_receiving(id, options = {})
      record @context.send(:drop_receiving_element_js, id, options)
    end

    #hide(*ids) ⇒ Object

    Hides the visible DOM elements with the given ids.

    Example:

    Hide a few people

    Generates: ["person_29", "person_9", "person_0"].each(Element.hide);

    page.hide 'person_29', 'person_9', 'person_0'

    
    
    401
    402
    403
    # File 'lib/action_view/helpers/prototype_helper.rb', line 401
    
    def hide(*ids)
      loop_on_multiple_args 'Element.hide', ids
    end

    #insert_html(position, id, *options_for_render) ⇒ Object

    Inserts HTML at the specified position relative to the DOM element identified by the given id.

    position may be one of:

    :top:: HTML is inserted inside the element, before the element's existing content. :bottom:: HTML is inserted inside the element, after the element's existing content. :before:: HTML is inserted immediately preceding the element. :after:: HTML is inserted immediately following the element.

    options_for_render may be either a string of HTML to insert, or a hash of options to be passed to ActionView::Base#render. For example:

    Insert the rendered 'navigation' partial just before the DOM

    element with ID 'content'.

    Generates: Element.insert("content", { before: "-- Contents of 'navigation' partial --" });

    page.insert_html :before, 'content', :partial => 'navigation'

    Add a list item to the bottom of the
      with ID 'list'.

    Generates: Element.insert("list", { bottom: "
  • Last item
  • " });

    page.insert_html :bottom, 'list', '

  • Last item
  • '

    
    
    316
    317
    318
    319
    # File 'lib/action_view/helpers/prototype_helper.rb', line 316
    
    def insert_html(position, id, *options_for_render)
      content = javascript_object_for(render(*options_for_render))
      record "Element.insert(\"#{id}\", { #{position.to_s.downcase}: #{content} });"
    end

    #literal(code) ⇒ Object

    Returns an object whose to_json evaluates to code. Use this to pass a literal JavaScript expression as an argument to another JavaScriptGenerator method.

    
    
    262
    263
    264
    # File 'lib/action_view/helpers/prototype_helper.rb', line 262
    
    def literal(code)
      ::ActiveSupport::JSON::Variable.new(code.to_s)
    end

    #redirect_to(location) ⇒ Object

    Redirects the browser to the given location using JavaScript, in the same form as url_for.

    Examples:

    Generates: window.location.href = "/mycontroller";

    page.redirect_to(:action => 'index')

    Generates: window.location.href = "/account/signup";

    page.redirect_to(:controller => 'account', :action => 'signup')

    
    
    436
    437
    438
    439
    # File 'lib/action_view/helpers/prototype_helper.rb', line 436
    
    def redirect_to(location)
      url = location.is_a?(String) ? location : @context.url_for(location)
      record "window.location.href = #{url.inspect}"
    end

    #reloadObject

    Reloads the browser's current location using JavaScript

    Examples:

    Generates: window.location.reload();

    page.reload

    
    
    447
    448
    449
    # File 'lib/action_view/helpers/prototype_helper.rb', line 447
    
    def reload
      record 'window.location.reload()'
    end

    #remove(*ids) ⇒ Object

    Removes the DOM elements with the given ids from the page.

    Example:

    Remove a few people

    Generates: ["person_23", "person_9", "person_2"].each(Element.remove);

    page.remove 'person_23', 'person_9', 'person_2'

    
    
    377
    378
    379
    # File 'lib/action_view/helpers/prototype_helper.rb', line 377
    
    def remove(*ids)
      loop_on_multiple_args 'Element.remove', ids
    end

    #replace(id, *options_for_render) ⇒ Object

    Replaces the "outer HTML" (i.e., the entire element, not just its contents) of the DOM element with the given id.

    options_for_render may be either a string of HTML to insert, or a hash of options to be passed to ActionView::Base#render. For example:

    Replace the DOM element having ID 'person-45' with the

    'person' partial for the appropriate object.

    page.replace 'person-45', :partial => 'person', :object => @person

    This allows the same partial that is used for the insert_html to be also used for the input to replace without resorting to the use of wrapper elements.

    Examples:

    <%= render :partial => 'person', :collection => @people %>

    Insert a new person

    Generates: new Insertion.Bottom("Matz", partial: "person", "");

    page.insert_html :bottom, :partial => 'person', :object => @person

    Replace an existing person

    Generates: Element.replace("person_45", "-- Contents of partial --");

    page.replace 'person_45', :partial => 'person', :object => @person

    
    
    365
    366
    367
    # File 'lib/action_view/helpers/prototype_helper.rb', line 365
    
    def replace(id, *options_for_render)
      call 'Element.replace', id, render(*options_for_render)
    end

    #replace_html(id, *options_for_render) ⇒ Object

    Replaces the inner HTML of the DOM element with the given id.

    options_for_render may be either a string of HTML to insert, or a hash of options to be passed to ActionView::Base#render. For example:

    Replace the HTML of the DOM element having ID 'person-45' with the

    'person' partial for the appropriate object.

    Generates: Element.update("person-45", "-- Contents of 'person' partial --");

    page.replace_html 'person-45', :partial => 'person', :object => @person

    
    
    331
    332
    333
    # File 'lib/action_view/helpers/prototype_helper.rb', line 331
    
    def replace_html(id, *options_for_render)
      call 'Element.update', id, render(*options_for_render)
    end

    #select(pattern) ⇒ Object

    Returns a collection reference by finding it through a CSS pattern in the DOM. This collection can then be used for further method calls. Examples:

    page.select('p')                      # => $$('p');
    page.select('p.welcome b').first      # => $$('p.welcome b').first();
    page.select('p.welcome b').first.hide # => $$('p.welcome b').first().hide();
    

    You can also use prototype enumerations with the collection. Observe:

    Generates: $$('#items li').each(function(value) { value.hide(); });

    page.select('#items li').each do |value| value.hide end

    Though you can call the block param anything you want, they are always rendered in the javascript as 'value, index.' Other enumerations, like collect() return the last statement:

    Generates: var hidden = $$('#items li').collect(function(value, index) { return value.hide(); });

    page.select('#items li').collect('hidden') do |item| item.hide end

    
    
    288
    289
    290
    # File 'lib/action_view/helpers/prototype_helper.rb', line 288
    
    def select(pattern)
      JavaScriptElementCollectionProxy.new(self, pattern)
    end

    #show(*ids) ⇒ Object

    Shows hidden DOM elements with the given ids.

    Example:

    Show a few people

    Generates: ["person_6", "person_13", "person_223"].each(Element.show);

    page.show 'person_6', 'person_13', 'person_223'

    
    
    389
    390
    391
    # File 'lib/action_view/helpers/prototype_helper.rb', line 389
    
    def show(*ids)
      loop_on_multiple_args 'Element.show', ids
    end

    #sortable(id, options = {}) ⇒ Object

    Creates a script.aculo.us sortable element. Useful to recreate sortable elements after items get added or deleted. See ActionView::Helpers::ScriptaculousHelper for more information.

    
    
    244
    245
    246
    # File 'lib/action_view/helpers/scriptaculous_helper.rb', line 244
    
    def sortable(id, options = {})
      record @context.send(:sortable_element_js, id, options)
    end

    #to_sObject

    :nodoc:

    
    
    229
    230
    231
    232
    233
    234
    235
    236
    237
    # File 'lib/action_view/helpers/prototype_helper.rb', line 229
    
    def to_s #:nodoc:
      (@lines * $/).tap do |javascript|
        if ActionView::Base.debug_rjs
          source = javascript.dup
          javascript.replace "try {\n#{source}\n} catch (e) "
          javascript << "{ alert('RJS error:\\n\\n' + e.toString()); alert('#{source.gsub('\\','\0\0').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }}'); throw e }"
        end
      end
    end

    #toggle(*ids) ⇒ Object

    Toggles the visibility of the DOM elements with the given ids. Example:

    Show a few people

    Generates: ["person_14", "person_12", "person_23"].each(Element.toggle);

    page.toggle 'person_14', 'person_12', 'person_23' # Hides the elements page.toggle 'person_14', 'person_12', 'person_23' # Shows the previously hidden elements

    
    
    413
    414
    415
    # File 'lib/action_view/helpers/prototype_helper.rb', line 413
    
    def toggle(*ids)
      loop_on_multiple_args 'Element.toggle', ids
    end

    #visual_effect(name, id = nil, options = {}) ⇒ Object

    Starts a script.aculo.us visual effect. See ActionView::Helpers::ScriptaculousHelper for more information.

    
    
    236
    237
    238
    # File 'lib/action_view/helpers/scriptaculous_helper.rb', line 236
    
    def visual_effect(name, id = nil, options = {})
      record @context.send(:visual_effect, name, id, options)
    end