Module: DeRjs::JqueryGenerator::GeneratorMethods
- Defined in:
- lib/de_rjs/jquery_generator.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: "<li>Some item</li>" });
# new Effect.Highlight("list");
# ["status-indicator", "cancel-link"].each(Element.hide);
update_page do |page|
page.insert_html :bottom, 'list', "<li>#{@item.name}</li>"
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[:two].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.
Constant Summary collapse
- SCRIPTACULOUS_EFFECTS =
{ :appear => {:method => 'fade', :mode => 'show'}, :blind_down => {:method => 'blind', :mode => 'show', :options => {:direction => 'vertical'}}, :blind_up => {:method => 'blind', :mode => 'hide', :options => {:direction => 'vertical'}}, :blind_right => {:method => 'blind', :mode => 'show', :options => {:direction => 'horizontal'}}, :blind_left => {:method => 'blind', :mode => 'hide', :options => {:direction => 'horizontal'}}, :bounce_in => {:method => 'bounce', :mode => 'show', :options => {:direction => 'up'}}, :bounce_out => {:method => 'bounce', :mode => 'hide', :options => {:direction => 'up'}}, :drop_in => {:method => 'drop', :mode => 'show', :options => {:direction => 'up'}}, :drop_out => {:method => 'drop', :mode => 'hide', :options => {:direction => 'down'}}, :fade => {:method => 'fade', :mode => 'hide'}, :fold_in => {:method => 'fold', :mode => 'hide'}, :fold_out => {:method => 'fold', :mode => 'show'}, :grow => {:method => 'scale', :mode => 'show'}, :shrink => {:method => 'scale', :mode => 'hide'}, :slide_down => {:method => 'slide', :mode => 'show', :options => {:direction => 'up'}}, :slide_up => {:method => 'slide', :mode => 'hide', :options => {:direction => 'up'}}, :slide_right => {:method => 'slide', :mode => 'show', :options => {:direction => 'left'}}, :slide_left => {:method => 'slide', :mode => 'hide', :options => {:direction => 'left'}}, :squish => {:method => 'scale', :mode => 'hide', :options => {:origin => "['top','left']"}}, :switch_on => {:method => 'clip', :mode => 'show', :options => {:direction => 'vertical'}}, :switch_off => {:method => 'clip', :mode => 'hide', :options => {:direction => 'vertical'}}, :toggle_appear => {:method => 'fade', :mode => 'toggle'}, :toggle_slide => {:method => 'slide', :mode => 'toggle', :options => {:direction => 'up'}}, :toggle_blind => {:method => 'blind', :mode => 'toggle', :options => {:direction => 'vertical'}}, }
Instance Method Summary collapse
-
#<<(javascript) ⇒ Object
Writes raw JavaScript to the page.
-
#[](id) ⇒ Object
Returns a element reference by finding it through
id
in the DOM. -
#alert(message) ⇒ Object
Displays an alert dialog with the given
message
. - #arguments_for_call(arguments, block = nil) ⇒ Object
-
#assign(variable, value) ⇒ Object
Assigns the JavaScript
variable
the givenvalue
. -
#call(function, *arguments, &block) ⇒ Object
Calls the JavaScript
function
, optionally with the givenarguments
. -
#delay(seconds = 1) ⇒ Object
Executes the content of the block after a delay of
seconds
. -
#hide(*ids) ⇒ Object
Hides the visible DOM elements with the given
ids
. -
#insert_html(position, id, *options_for_render) ⇒ Object
Inserts HTML at the specified
position
relative to the DOM element identified by the givenid
. -
#jquery_id(id) ⇒ Object
:nodoc:.
-
#jquery_ids(ids) ⇒ Object
:nodoc:.
- #jquery_ui_effect(name, js_options) ⇒ Object
-
#jquery_ui_visual_effect(name, element_id = false, js_options = {}) ⇒ Object
Returns a JavaScript snippet to be used on the Ajax callbacks for starting visual effects.
-
#literal(code) ⇒ Object
Returns an object whose
to_json
evaluates tocode
. -
#redirect_to(location) ⇒ Object
Redirects the browser to the given
location
using JavaScript, in the same form asurl_for
. -
#reload ⇒ Object
Reloads the browser’s current
location
using JavaScript. -
#remove(*ids) ⇒ Object
Removes the DOM elements with the given
ids
from the page. -
#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
. -
#replace_html(id, *options_for_render) ⇒ Object
Replaces the inner HTML of the DOM element with the given
id
. -
#select(pattern) ⇒ Object
Returns a collection reference by finding it through a CSS
pattern
in the DOM. -
#show(*ids) ⇒ Object
Shows hidden DOM elements with the given
ids
. -
#to_s ⇒ Object
:nodoc:.
-
#toggle(*ids) ⇒ Object
Toggles the visibility of the DOM elements with the given
ids
. -
#visual_effect(name, id = nil, options = {}) ⇒ Object
Starts a script.aculo.us visual effect.
Instance Method Details
#<<(javascript) ⇒ Object
Writes raw JavaScript to the page.
Example:
page << "alert('JavaScript with Prototype.');"
392 393 394 |
# File 'lib/de_rjs/jquery_generator.rb', line 392 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')
132 133 134 135 136 137 138 139 |
# File 'lib/de_rjs/jquery_generator.rb', line 132 def [](id) case id when String, Symbol, NilClass JavaScriptElementProxy.new(self, id) else JavaScriptElementProxy.new(self, ActionView::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!')
314 315 316 |
# File 'lib/de_rjs/jquery_generator.rb', line 314 def alert() call 'alert', end |
#arguments_for_call(arguments, block = nil) ⇒ Object
504 505 506 507 |
# File 'lib/de_rjs/jquery_generator.rb', line 504 def arguments_for_call(arguments, block = nil) arguments << block_to_function(block) if block arguments.map { |argument| javascript_object_for(argument) }.join ', ' 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
383 384 385 |
# File 'lib/de_rjs/jquery_generator.rb', line 383 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[:one].show
p[:two].hide
end
366 367 368 |
# File 'lib/de_rjs/jquery_generator.rb', line 366 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
406 407 408 409 410 |
# File 'lib/de_rjs/jquery_generator.rb', line 406 def delay(seconds = 1) record "setTimeout(function() {\n\n" yield record "}, #{(seconds * 1000).to_i})" 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'
290 291 292 293 |
# File 'lib/de_rjs/jquery_generator.rb', line 290 def hide(*ids) call "#{JQUERY_VAR}(\"#{jquery_ids(ids)}\").hide" #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 <ul> with ID 'list'.
# Generates: Element.insert("list", { bottom: "<li>Last item</li>" });
page.insert_html :bottom, 'list', '<li>Last item</li>'
197 198 199 200 201 202 203 204 |
# File 'lib/de_rjs/jquery_generator.rb', line 197 def insert_html(position, id, *) insertion = position.to_s.downcase insertion = 'append' if insertion == 'bottom' insertion = 'prepend' if insertion == 'top' call "#{JQUERY_VAR}(\"#{jquery_id(id)}\").#{insertion}", render(*) # content = javascript_object_for(render(*options_for_render)) # record "Element.insert(\"#{id}\", { #{position.to_s.downcase}: #{content} });" end |
#jquery_id(id) ⇒ Object
:nodoc:
112 113 114 |
# File 'lib/de_rjs/jquery_generator.rb', line 112 def jquery_id(id) #:nodoc: id.sub(/<%=.*%>/,'').to_s.count('#.*,>+~:[/ ') == 0 ? "##{id}" : id end |
#jquery_ids(ids) ⇒ Object
:nodoc:
116 117 118 |
# File 'lib/de_rjs/jquery_generator.rb', line 116 def jquery_ids(ids) #:nodoc: Array(ids).map{|id| jquery_id(id)}.join(',') end |
#jquery_ui_effect(name, js_options) ⇒ Object
482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 |
# File 'lib/de_rjs/jquery_generator.rb', line 482 def jquery_ui_effect(name, ) if SCRIPTACULOUS_EFFECTS.has_key? name.to_sym effect = SCRIPTACULOUS_EFFECTS[name.to_sym] name = effect[:method] mode = effect[:mode] = .merge(effect[:options]) if effect[:options] end [:queue] = if [:queue].is_a?(Hash) '{' + [:queue].map {|k, v| k == :limit ? "#{k}:#{v}" : "#{k}:'#{v}'" }.join(',') + '}' elsif [:queue] "'#{[:queue]}'" end if [:queue] [:color, :direction, :startcolor, :endcolor].each do |option| [option] = "'#{[option]}'" if [option] end [:duration] = ([:duration] * 1000).to_i if .has_key? :duration "#{mode || "effect"}(\"#{name}\",#{()})" end |
#jquery_ui_visual_effect(name, element_id = false, js_options = {}) ⇒ Object
Returns a JavaScript snippet to be used on the Ajax callbacks for starting visual effects.
If no element_id
is given, it assumes “element” which should be a local variable in the generated JavaScript execution context. This can be used for example with drop_receiving_element
:
<%= drop_receiving_element (...), :loading => visual_effect(:fade) %>
This would fade the element that was dropped on the drop receiving element.
For toggling visual effects, you can use :toggle_appear
, :toggle_slide
, and :toggle_blind
which will alternate between appear/fade, slidedown/slideup, and blinddown/blindup respectively.
You can change the behaviour with various options, see script.aculo.us for more documentation.
463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 |
# File 'lib/de_rjs/jquery_generator.rb', line 463 def jquery_ui_visual_effect(name, element_id = false, = {}) #element = element_id ? ActiveSupport::JSON.encode(jquery_id((JavaScriptVariableProxy === element_id) ? element_id.as_json : element_id)) : "this" if element_id element = if element_id =~ /\A<%=.*%>\z/ # if completely using erb "\"##{element_id}\"" # USER BEWARE ! else ActiveSupport::JSON.encode(jquery_id((JavaScriptVariableProxy === element_id) ? element_id.as_json : element_id)) end else element = "this" end #if ['fadeIn','fadeOut','fadeToggle'].include?(name) # "$(\"#{jquery_id(element_id)}\").#{name}();" #else "#{JQUERY_VAR}(#{element}).#{jquery_ui_effect(name, )}" #end 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.
143 144 145 |
# File 'lib/de_rjs/jquery_generator.rb', line 143 def literal(code) JsonLiteral.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')
327 328 329 330 331 |
# File 'lib/de_rjs/jquery_generator.rb', line 327 def redirect_to(location) #url = location.is_a?(String) ? location : @context.url_for(location) url = location.to_s record "window.location.href = #{url.inspect}" end |
#reload ⇒ Object
Reloads the browser’s current location
using JavaScript
Examples:
# Generates: window.location.reload();
page.reload
339 340 341 |
# File 'lib/de_rjs/jquery_generator.rb', line 339 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'
264 265 266 267 |
# File 'lib/de_rjs/jquery_generator.rb', line 264 def remove(*ids) call "#{JQUERY_VAR}(\"#{jquery_ids(ids)}\").remove" #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:
<div id="people">
<%= render :partial => 'person', :collection => @people %>
</div>
# Insert a new person
#
# Generates: new Insertion.Bottom({object: "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
251 252 253 254 |
# File 'lib/de_rjs/jquery_generator.rb', line 251 def replace(id, *) call "#{JQUERY_VAR}(\"#{jquery_id(id)}\").replaceWith", 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
216 217 218 219 |
# File 'lib/de_rjs/jquery_generator.rb', line 216 def replace_html(id, *) call "#{JQUERY_VAR}(\"#{jquery_id(id)}\").html", 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
169 170 171 |
# File 'lib/de_rjs/jquery_generator.rb', line 169 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'
277 278 279 280 |
# File 'lib/de_rjs/jquery_generator.rb', line 277 def show(*ids) call "#{JQUERY_VAR}(\"#{jquery_ids(ids)}\").show" #loop_on_multiple_args 'Element.show', ids end |
#to_s ⇒ Object
:nodoc:
100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/de_rjs/jquery_generator.rb', line 100 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 @lines * $/ 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
303 304 305 306 |
# File 'lib/de_rjs/jquery_generator.rb', line 303 def toggle(*ids) call "#{JQUERY_VAR}(\"#{jquery_ids(ids)}\").toggle" #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.
414 415 416 |
# File 'lib/de_rjs/jquery_generator.rb', line 414 def visual_effect(name, id = nil, = {}) record jquery_ui_visual_effect(name, id, ) end |