I was asked if one can do partial rjs files by a coworker recently. Some of our RJS code is becoming large and difficult to maintained. I figured why should RJS be different then the other templates. So I started up my test rails application. This is very filled with 1/2 crazy ideas and 1/2 unsure syntax examples. So I added two calls rjs1 and rjs2. I created a link_to_remote[1] on rjs1 pointing to rjs2.
I did nothing in rjs2 but created an rjs2.rjs file in side of my views directory. My rsj2.rjs file looks like
page.replace_html "one","one"
page<<"#{render(:partial=>"moo")}"
_moo.rjs looks like
page.replace_html "two","two"
I understand that render will return the JavaScript of the rjs rendering. I also understand that I need to use page<< to append the JavaScript to the call like I would use <%= %> in an RHTML file. Would appear to work, but it seems off.
What I do not understand is why firebug[2] only shows me the first replace call in the response.
try {
Element.update("one", "one");
} catch (e) { alert('RJS error:\n\n' + e.toString()); alert('Element.update(\"one\", \"one\");'); throw e }
What it is close to what I expect to but not complete. This is what I think I should see:
try {
Element.update("one", "one");
try {
Element.update("two", "two");
} catch (e) { alert('RJS error:\n\n' + e.toString()); alert('Element.update(\"two\", \"two\");'); throw e }
} catch (e) { alert('RJS error:\n\n' + e.toString()); alert('Element.update(\"one\", \"one\");'); throw e }
Note the nested try catch is only there because of the rjs debug setting. So I changed debug to false and restarted the server. I now see this in firebug:
Element.update("one", "one");
Element.update("two", "two");
I am happy because this can help clean out view logic from the controller RJS calls, but I am also concerned that the improper display in firebug[3] can have a negative impact on developing JavaScript. I am also thinking that this can be done in a different way.
[1]
http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper.html
[2]
http://www.getfirebug.com/
[3]
Firebug display issueIf you find your self using the page<< command a lot extend the page object.
module ActionView
module Helpers
module PrototypeHelper
class JavaScriptGenerator
module GeneratorMethods
def becker
assign 'window.location.href', "http://stephenbeckeriv.com"
end
end
end
end
end
end
Save this in a ruby file in the lib directory and then require "file_name" in environment.rb after the boot line.
Now you can call this from your rjs template.
page.becker
I do not have any good code examples. I am not a big javascript person which is why I am happy I can extend it in ruby.
I recently posted about using RJS partials. I could of found out how to do this by searching the google. I found a nice
site that sums up a peep code screencast.
I still think that this is an ugly way of doing this. It also has an extra debug statement that makes it look messy. So like my rjs extension example I created a partial render method. Odd little side note: I can not name my method render. I am looking in to why.
module ActionView
module Helpers
module PrototypeHelper
class JavaScriptGenerator
module GeneratorMethods
def partial(*args)
reset_rjs_debug = ActionView::Base.debug_rjs
ActionView::Base.debug_rjs = false
@lines << "#{render(*args)}"
ActionView::Base.debug_rjs = reset_rjs_debug
end
end
end
end
end
end
Now your rjs script looks like
page.partial(:partial=>"moo",{:local=>"var"})
I do not like how the arguments repeat the partial. It would make more sense if I could call my method render (page.render). I also could do more with the arguments.
partial(name,*args)
...
@lines << "#{render(:partial=>name,*args)}"
I did not test this but it should work. Maybe there is a problem if no *args are passed in.