Rails 3 jQuery identifying "this" object
My setup: Rails 3.0.9, Ruby 1.9.2, jQuery 1.6.2
HTML
<textarea id="photo-42-9" class="comment_box">Write a comment...</textarea>
jQuery
$('#newsfeed').delegate('.comment_box', 'keydown', function (event){
if(event.keyCode == 13) {
event.preventD开发者_运维问答efault();
$.post('/comments', { title: ..., description: ... });
}
});
Rails
comments_controller.rb
def create
@comment = Comment.new
respond_to do |format|
format.html # new.html.erb
format.js
end
end
create.js.erb
$("<%= escape_javascript( render 'show_comments') %>").insertBefore(???);
render 'show_comments'
returns a <div>stuff</div>
that I wish to insert before textarea
. I could use the selector on #photo-42-9
but that id is dynamic depending on which textarea
element I clicked on. How do I access this
object in create.js.erb
?
in js:
$('#newsfeed').delegate('.comment_box', 'keydown', function (event){
if(event.keyCode == 13) {
event.preventDefault();
var params = { title: ..., description: ... };
var $this = $(event.target);
$.post('/comments', params, function(response) {
$this.before(response);
});
}
});
and in ruby (i guess, I don't do ruby):
"<%= escape_javascript( render 'show_comments') %>"
As you see, "this" isn't passed to rb. Instead, the $.post function waits for the rb response, and pastes it before the text area (the event target). This way is better as all your js code is actually in your js code.
note: "$(response).insertBefore($this)
" would work the same.
note: if you move the $this assigination out of the "if", you can easily check if the fresh comment is not empty and different than the ones already existing (event.keyCode == 13 && $this.val() != '' && $this.val() != $this.prev().text()
). As well, you can empty the textarea with $this.val('')
right after the "$this.before
" insertion.
There is no way to access this
-- which is determined in a client-side script -- from the create action on your controller which is executing server side in a different scope and different programming language.
You have two options. Either you can pass selector information along with your request so that it can be determined by the server, OR, you can name your selectors systematically so that your selector will be able to be determined by the properties of the object itself.
The latter is simpler. It looks like your form is posting comments on a photo, so for instance, if you use
div_for @photo
to generate the container for the photos you're commenting on, then you can always access that container using:
dom_id @photo
So then you could use inheritance to select the textarea you want to insert before.
In your create.js.erb:
$(...content...).append('#<%= dom_id @photo %>')
Obviously you'll have to structure that to fit the content that you are interacting with. It may be easier to append to the inside of the outer photo container or to select a comment you want to insertAfter or something like that.
Alternatively, you could put a hidden field in your form containing the generated ID of the form, something like hidden_field_tag :form_id, form_id_goes_here
.
Then in your controller set:
@selector = params[:form_id]
And in your create.js.erb:
$(...content...).insertBefore('<%= escape_javascript @selector %>')
精彩评论