I am looking for a recipe to use the controller’s global variables into a coffeescript like this :
Controller :
respond_to :js
def create
@commentable = commentable
@comment = @commentable.comments.build({:comment => params[:comment], :user => current_user})
@comment.save
respond_with(@comment, @commentable)
end
create.js.coffee :
$("#form_#{@commentable.class}_#{@commentable.id}").hide()
The idea is to have several commentables in a single page and to identify the one which is currently commented to hide/show a form to comment it ; the form’s id is built using the class and the id of the commentable. At this time, if I try to access an element with the code above, it does not work because @commentable does not seem to exist in the script.
EDIT:
I read the answer here, and I tried the following :
In my posts/show.haml
:javascript
var commentable_comments_id;
#post
@post.body
= render :partial => 'comments/list', :locals => {:commentable => @post}
In my partial _list.haml
#comments_container
%div{:id => "comments_#{commentable.class}_#{commentable.id}"}
- commentable.comments.reverse_each do |comment|
= render :partial => 'comments/comment', :locals => {:comment => comment}
- if current_user
.add_comment_link{:id => "link_#{commentable.class}_#{commentable.id}"}
#{link_to "Commenter"}
.add_comment{:id => "form_#{commentable.class}_#{commentable.id}"}
= render :partial => 'comments/comment_form', :locals => {:commentable => commentable}
And in the partial _comment_form.haml
.comment_form
= form_tag polymorphic_path([commentable, Comment]) , :method => :post, :remote => true do |f|
.comment_field
= text_area_tag :comment, params[:comment], :id =>"comment_area", :rows => 4, :cols => 50
.comment_field
= submit_tag "Commenter", :id => "submit_comment_#{commentable.class}_#{commentable.id}", :class => "submit_comment"
In the posts.js.coffee :
jQuery ->
commentable_link_id = null
commentable_form_id = null
hide_element_by_id = (id_name) ->
$("#"+id_name).hide()
show_element_by_id = (id_name) ->
$("#"+id_name).show()
$('.add_comment_link').click ->
currentId = $(this).attr('id')
if(commentable_link_id != null && commentable_form_id != null)
hide_element_by_id(commentable_form_id)
show_element_by_id(commentable_link_id)
commentable_link_id = currentId
commentable_form_id = currentId.replace("link", "form")
hide_element_by_id(commentable_link_id)
show_element_by_id(commentable_form_id)
commentable_comments_id = currentId.replace("link", "comments")
false
$('.submit_comment').click ->
if(commentable_link_id != null && commentable_form_id != null)
hide_element_by_id(commentable_form_id)
show_element_by_id(commentable_link_id)
So when the user click on the link to add a comment, it hides the previous comment form (if any), it shows the new correct one, builds the id of the comments’container (for example comments_Post_3) and store it in a global js variable of the page :
commentable_comments_id = currentId.replace("link", "comments")
Then in the create.js.coffee, I try to append the new comment in the stored container using this variable :
$('<%= escape_javascript(render(:partial => @comment))%>')
.appendTo("#"+commentable_comments_id)
.hide()
.fadeIn()
I think this is not correct because the last operation (the append with fading) is not working, so the global variable commentable_comments_id must not be initialized or something else…
You can do it using coffeebeans.
Just add it to your Gemfile:
And then create the file as you want: