Reputation: 19873
I like the idea of separating functionality and this seems like the way of the future.
But I'm used to integrating javascript inside loops in an embedded language like Rails ERB or PHP, where I can use the ID of a particular object as a reference in the javascript.
Rails example:
<% @comments.each do |comment| %>
<div id="comment_<%= comment.id %>">
<%= comment.text %>
<% link_to_function "Reply", "$('comment_#{comment.id}').insert(\"#{escape_javascript(render :partial => "_form", :locals => {:comment => comment})}\", {position: 'bottom'});" %>
</div>
<% end %>
This isn't the only time I've ended up wanting to use Ruby methods inside javascript either. I may want to use constants, or call other ruby methods on an object inside a loop user.enabled?
or user.full_name
, or render partials with those objects, etc.
So how is this supposed to be accomplished if all the javascript is in another file or outside the loop? I get that you can iterate through a bunch of divs in javascript using CSS selectors, but this doesn't allow me to call ruby methods on objects.
What am I missing? Thanks!
Upvotes: 1
Views: 331
Reputation: 3928
You just need some more JavaScript knowledge to see power of it, especially jQuery. Your example I would solve like:
<% @comments.each do |comment| %>
<div class="comment">
<%= comment.text %>
<a href="reply.php?id=<%= comment.id %>" class="reply">Reply</a>
</div>
<% end %>
<script type="text/javascript">
$('.comment .reply').click(function(e) {
e.preventDefault();
var url = $(this).attr('href');
var result = url.match(/\?id=(\d+)([^\d]|$)/);
var id = (result && result[1]);
if (id) {
// do whatever you want to do with the id
}
});
</script>
Benefits:
(1) You don't have javascript all over the place
(2) Works without javascript
Upvotes: 0
Reputation: 76766
Make your client-side script take an 'options' object as a parameter. Don't use any server-side scripting; put the script in its own .js file.
Then create the 'options' object with a server-side script which outputs js. Include your script and call its entry-point function, passing in your 'options' object.
Upvotes: 0
Reputation: 115392
For your particular example you already have the comment ID encoded within the markup because you set the ID attribute of the div
element to the comment ID. So you can hang the JavaScript off that.
Upvotes: 1
Reputation: 68016
Pardon me for using jquery, but web development really sucks without it or similar library
For your first complaint (get current comment), javascript this
works fine for me.
onclick="my_function(this);"
and in js file
my_function = function(target) {
// clicked element passed in
// now, let's get comment element by class
var comment = $(target).parents('.comment');
}
As for second complaint... I never needed it often, but sometimes I include pieces of data in html for use by javascript. Extending previous example:
<div class="comment" comment_id="<%= comment.id %>"></div>
And in my_function
var comment_id = comment.attr('comment_id');
Upvotes: 0
Reputation: 167
I think it shold be done with "data-id" parameter as shown in this screencast http://railscasts.com/episodes/229-polling-for-changes
Upvotes: 2