I've recently faced the problem: I need to generate javascript that would insert some HTML block unless it is already there. So, the code should be something like this:
if( !($('block_id')) ) {
// insert block
}
All that should go to RJS template.
First revision:
page << "if( !($('block_id')) ) {"
page.insert_html :before, 'container_id', ''
page << "}"
Next, it would be nice to make use of JavaScriptProxy objects (that are spawn, e.g., by page#[] method). The problem is that HTML is emited when those proxy created or evaluated, thus it's not possible to wrap that javascript code into e.g. "if( ... )"..
Solution, first try:
class << page
def if
self << "if("
end
def then
self << ") {"
end
def end
self << "}"
end
end
page.if
page['block_id']
page.then
page.insert_html .......
page.end
This is better then the first one, but too ugly though. A better solution would include some black magick:
module AcitiveView
module Helpers
class JavaScriptProxy
def respond_to?(name)
name.to_sym == :to_json
end
def to_json
@generator.instance_variable_get('@lines').pop.chomp(';')
end
end
end
end
Then:
class << page
def if(expr)
page << "if( #{expr.respond_to?(:to_json) ? expr.to_json : expr} ) {"
yield if block_given?
page << "}"
end
end
page.if page['block_id'] do
page.insert_html .....
end
And finally, the more peaceful variant:
module ApplicationHelper
def if_exists(element_id)
page << "if( !($('#{element_id}')) ) {"
yield if block_given?
page << "}"
end
end
page.if_exists 'block_id' do
page.insert_html .....
end