module ActionView::Helpers::PrototypeHelper::JavaScriptGenerator::GeneratorMethods

def <<(javascript)

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

Example:

Writes raw JavaScript to the page.
def <<(javascript)
  @lines << javascript
end

def [](id)

page[Post.new] # => $('new_post')
page[@post] # => $('post_45')

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

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

used for further method calls. Examples:
Returns a element reference by finding it through +id+ in the DOM. This element can then be
def [](id)
  case id
    when String, Symbol, NilClass
      JavaScriptElementProxy.new(self, id)
    else
      JavaScriptElementProxy.new(self, ActionController::RecordIdentifier.dom_id(id))
  end
end

def alert(message)

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

Example:

Displays an alert dialog with the given +message+.
def alert(message)
  call 'alert', message
end

def arguments_for_call(arguments, block = nil)

def arguments_for_call(arguments, block = nil)
  arguments << block_to_function(block) if block
  arguments.map { |argument| javascript_object_for(argument) }.join ', '
end

def assign(variable, value)


page.assign 'tabulated_total', @total_from_cart
# Generates: tabulated_total = 47

page.assign 'record_count', 33
# Generates: record_count = 33;

page.assign 'my_string', 'This is mine!'
# Generates: my_string = "This is mine!";

Examples:

Assigns the JavaScript +variable+ the given +value+.
def assign(variable, value)
  record "#{variable} = #{javascript_object_for(value)}"
end

def block_to_function(block)

def block_to_function(block)
  generator = self.class.new(@context, &block)
  literal("function() { #{generator.to_s} }")
end

def call(function, *arguments, &block)

end
p[:two].hide
p[:one].show
page.call(:my_method) do |p|
# });
# $("two").hide();
# $("one").show();
# my_method(function() {
# Generates:

page.call 'alert', 'My message!'
# Generates: alert('My message!')

page.call 'Element.replace', 'my_element', "My content to replace with."
# Generates: Element.replace(my_element, "My content to replace with.")

Examples:

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

Calls the JavaScript +function+, optionally with the given +arguments+.
def call(function, *arguments, &block)
  record "#{function}(#{arguments_for_call(arguments, block)})"
end

def delay(seconds = 1)

end
page.visual_effect :fade, 'notice'
page.delay(20) do
# }, 20000);
# new Effect.Fade("notice",{});
# ;
# setTimeout(function() {
# Generates:

Executes the content of the block after a delay of +seconds+. Example:
def delay(seconds = 1)
  record "setTimeout(function() {\n\n"
  yield
  record "}, #{(seconds * 1000).to_i})"
end

def draggable(id, options = {})

See ActionView::Helpers::ScriptaculousHelper for more information.
Creates a script.aculo.us draggable element.
def draggable(id, options = {})
  record @context.send(:draggable_element_js, id, options)
end

def drop_receiving(id, options = {})

See ActionView::Helpers::ScriptaculousHelper for more information.
Creates a script.aculo.us drop receiving element.
def drop_receiving(id, options = {})
  record @context.send(:drop_receiving_element_js, id, options)
end

def hide(*ids)


page.hide 'person_29', 'person_9', 'person_0'
# Generates: ["person_29", "person_9", "person_0"].each(Element.hide);
# Hide a few people

Example:

Hides the visible DOM elements with the given +ids+.
def hide(*ids)
  loop_on_multiple_args 'Element.hide', ids
end

def insert_html(position, id, *options_for_render)


page.insert_html :bottom, 'list', '
  • Last item
  • '
    # Generates: Element.insert("list", { bottom: "
  • Last item
  • " });
    # Add a list item to the bottom of the
      with ID 'list'.

      page.insert_html :before, 'content', :partial => 'navigation'
      # Generates: Element.insert("content", { before: "-- Contents of 'navigation' partial --" });
      # element with ID 'content'.
      # Insert the rendered 'navigation' partial just before the DOM

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

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

      +position+ may be one of:

      identified by the given +id+.
      Inserts HTML at the specified +position+ relative to the DOM element
    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

    def javascript_object_for(object)

    def javascript_object_for(object)
      ::ActiveSupport::JSON.encode(object)
    end

    def literal(code)

    expression as an argument to another JavaScriptGenerator method.
    Returns an object whose to_json evaluates to +code+. Use this to pass a literal JavaScript
    def literal(code)
      ::ActiveSupport::JSON::Variable.new(code.to_s)
    end

    def loop_on_multiple_args(method, ids)

    def loop_on_multiple_args(method, ids)
      record(ids.size>1 ?
        "#{javascript_object_for(ids)}.each(#{method})" :
        "#{method}(#{javascript_object_for(ids.first)})")
    end

    def method_missing(method, *arguments)

    def method_missing(method, *arguments)
      JavaScriptProxy.new(self, method.to_s.camelize)
    end

    def page

    def page
      self
    end

    def record(line)

    def record(line)
      line = "#{line.to_s.chomp.gsub(/\;\z/, '')};"
      self << line
      line
    end

    def redirect_to(location)

    page.redirect_to(:controller => 'account', :action => 'signup')
    # Generates: window.location.href = "/account/signup";

    page.redirect_to(:action => 'index')
    # Generates: window.location.href = "/mycontroller";

    Examples:

    Redirects the browser to the given +location+ using JavaScript, in the same form as +url_for+.
    def redirect_to(location)
      url = location.is_a?(String) ? location : @context.url_for(location)
      record "window.location.href = #{url.inspect}"
    end

    def reload

    page.reload
    # Generates: window.location.reload();

    Examples:

    Reloads the browser's current +location+ using JavaScript
    def reload
      record 'window.location.reload()'
    end

    def remove(*ids)


    page.remove 'person_23', 'person_9', 'person_2'
    # Generates: ["person_23", "person_9", "person_2"].each(Element.remove);
    # Remove a few people

    Example:

    Removes the DOM elements with the given +ids+ from the page.
    def remove(*ids)
      loop_on_multiple_args 'Element.remove', ids
    end

    def render(*options)

    def render(*options)
      with_formats(:html) do
        case option = options.first
        when Hash
          @context.render(*options)
        else
          option.to_s
        end
      end
    end

    def replace(id, *options_for_render)


    page.replace 'person_45', :partial => 'person', :object => @person
    # Generates: Element.replace("person_45", "-- Contents of partial --");

    # Replace an existing person

    page.insert_html :bottom, :partial => 'person', :object => @person
    # Generates: new Insertion.Bottom({object: "Matz", partial: "person"}, "");
    #
    # Insert a new person


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


    Examples:

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

    page.replace 'person-45', :partial => 'person', :object => @person
    # 'person' partial for the appropriate object.
    # Replace the DOM element having ID 'person-45' with the

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

    contents) of the DOM element with the given +id+.
    Replaces the "outer HTML" (i.e., the entire element, not just its
    def replace(id, *options_for_render)
      call 'Element.replace', id, render(*options_for_render)
    end

    def replace_html(id, *options_for_render)


    page.replace_html 'person-45', :partial => 'person', :object => @person
    # Generates: Element.update("person-45", "-- Contents of 'person' partial --");
    # 'person' partial for the appropriate object.
    # Replace the HTML of the DOM element having ID 'person-45' with the

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

    Replaces the inner HTML of the DOM element with the given +id+.
    def replace_html(id, *options_for_render)
      call 'Element.update', id, render(*options_for_render)
    end

    def select(pattern)


    end
    item.hide
    page.select('#items li').collect('hidden') do |item|
    # Generates: var hidden = $$('#items li').collect(function(value, index) { return value.hide(); });

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

    end
    value.hide
    page.select('#items li').each do |value|
    # Generates: $$('#items li').each(function(value) { value.hide(); });

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

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

    used for further method calls. Examples:
    Returns a collection reference by finding it through a CSS +pattern+ in the DOM. This collection can then be
    def select(pattern)
      JavaScriptElementCollectionProxy.new(self, pattern)
    end

    def show(*ids)


    page.show 'person_6', 'person_13', 'person_223'
    # Generates: ["person_6", "person_13", "person_223"].each(Element.show);
    # Show a few people

    Example:

    Shows hidden DOM elements with the given +ids+.
    def show(*ids)
      loop_on_multiple_args 'Element.show', ids
    end

    def sortable(id, options = {})

    See ActionView::Helpers::ScriptaculousHelper for more information.
    or deleted.
    to recreate sortable elements after items get added
    Creates a script.aculo.us sortable element. Useful
    def sortable(id, options = {})
      record @context.send(:sortable_element_js, id, options)
    end

    def to_s #:nodoc:

    :nodoc:
    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

    def toggle(*ids)


    page.toggle 'person_14', 'person_12', 'person_23' # Shows the previously hidden elements
    page.toggle 'person_14', 'person_12', 'person_23' # Hides the elements
    # Generates: ["person_14", "person_12", "person_23"].each(Element.toggle);
    # Show a few people

    Example:
    Toggles the visibility of the DOM elements with the given +ids+.
    def toggle(*ids)
      loop_on_multiple_args 'Element.toggle', ids
    end

    def visual_effect(name, id = nil, options = {})

    ActionView::Helpers::ScriptaculousHelper for more information.
    Starts a script.aculo.us visual effect. See
    def visual_effect(name, id = nil, options = {})
      record @context.send(:visual_effect, name, id, options)
    end

    def with_formats(*args)

    def with_formats(*args)
      @context ? @context.update_details(:formats => args) { yield } : yield
    end