In my Rails 4 app I have this event listener:
$('.remove-tag-button').on('click', function () {
$.ajax({
type: "POST",
data: {id: <%= @item.id %>, tag: $(this).data("tag-name")},
url: "/remove_tag"
});
});
in three places and I'm wondering if there's a way to refactor.
I have an items controller with some actions including show
, add_tag
, and remove_tag
.
def show @item= Item.find_by_id(params[:id]) end def add_tag (omitted for brevity) respond_to do |format| format.js end def remove_tag (omitted for brevity) respond_to do |format| format.js end
My show.html.erb
has a form with a button to remove tags (class="remove-tag-button"
) that the event listener is referring to. I have the listener inside script tags at the bottom of my show.html.erb
(inside a $(document).ready()
) and also inside my add_tag.js.erb
and remove_tag.js.erb
.
show.html.erb
<div id="taglist">
<%= render partial: 'items/tag_list', locals: {item: @item} %>
</div>
<form action="<%= add_tag_path %>" method="post" id="custom-tag" class="input-group" autocomplete="off" data-remote="true">
<%= text_field_tag :tag, nil, placeholder: 'Add tag', class: "form-control typeahead", id: 'add-tag' %>
<span class="input-group-btn">
<%= submit_tag 'Add', id: "add-button", class: "btn btn-default" %>
</span>
</form>
<script>
$(document).ready(function(){
$('.remove-tag-button').on('click', function () {
$.ajax({
type: "POST",
data: {id: <%= @item.id %>, tag: $(this).data("tag-name")},
url: "/remove_tag"
});
});
});
</script>
add_tag.js.erb
$("#taglist").html('<%= escape_javascript(render partial: "items/tag_list", locals: {item: @item}) %>');
$('.remove-tag-button').on('click', function () {
$.ajax({
type: "POST",
data: {id: <%= @item.id %>, tag: $(this).data("tag-name")},
url: "/remove_tag"
});
});
remove_tag.js.erb
$("#taglist").html('<%= escape_javascript(render partial: "items/tag_list", locals: {item: @item}) %>');
$('.remove-tag-button').on('click', function () {
$.ajax({
type: "POST",
data: {id: <%= @item.id %>, tag: $(this).data("tag-name")},
url: "/remove_tag"
});
});
items/_tag_list.html.erb
<% item.all_tags_list.each do |t| %>
<span class="tag-container">
<%= link_to t, tag_path(t), class: "item-tag" %>
<% if item.tags_from(current_user).include?(t) %>
<span>
<%= link_to "×", '', class: "remove-tag-button", :'data-tag-name' => t, remote: true %>
</span>
<% end %>
</span>
<% end %>
I have 3 instances of this code because a user needs to be able to add and remove tags through AJAX requests while on the page. So it listens when the page loads, then I need it to still be listening after a user has added and/or removed a tag (both which are done through AJAX).
This seems sloppy. I'm wondering if theres a better way to do it.