我目前有一个嵌套在do / end块中的表单,因此对于每个创建的对象,它都有自己的下拉菜单:
<% @shows.each do |show| %>
<%= form_for show, :url => show_record_path(:show_id => show.id), method: :post do |f| %>
<%= f.select :box_id, Box.all.collect { |p| [ p.box_number, p.id ] }, class: "show-radio-button", :include_blank => true %>
<%= f.submit "Record", data: { disable_with: "Please wait.." }, :disabled => true, class: "record-button" %>
<% end %>
这是我的jQuery,如果选择了下拉列表中的选项,则启用提交按钮:
$('#show_box_id').on('keyup change', function(){
if ($('#show_box_id').val() == '' ) {
$('.record-button').prop('disabled', true);
$(".record-button").css("background-color", "");
} else {
$('.record-button').prop('disabled', false);
$(".record-button").css("background-color", "#008C00");
}
});
问题是jQuery只能在do / end块中创建的第一个对象上工作(所以如果我从下拉列表中选择一些不在第一个对象中的东西,没有任何反应),如果我从下拉列表中选择一些东西在第一个对象中,然后jQuery在所有这些对象上运行。
如何才能使jQuery代码在单独创建的每个对象上运行而对其他对象没有影响?
答案 0 :(得分:1)
我认为发生的事情是你依赖于表单助手生成的默认id来与JQuery选择器一起使用。这很令人困惑,因为所有元素都具有相同的ID ......并且ID应该是页面唯一的。您的标记将无效,JQuery可能会表现得很奇怪,假设一个唯一的ID,所以只能击中第一个。
如果我能看到生成的标记,我可以更加确定。
您的处理程序作用于所有表单共享的类,因此将对所有表单执行操作。
有些事情:
<%= f.select :box_id, Box.all.collect { |p| [ p.box_number, p.id ] }, class: "show-radio-button", id: "show_box_id_#{show.id}", :include_blank => true %>
将修复ID。然后在JS中你可以尝试类似的东西:
$('.show_radio_button').on('keyup change', function(e){
var $this = $(this);
var $form = $this.closest('form');
var $button = $form.find(".record_button");
if ($this.val() == '' ) {
$button.prop('disabled', true);
$button.css("background-color", "");
} else {
$button.prop('disabled', false);
$button.css("background-color", "#008C00");
}
});
进行一次JQuery选择器查找并将其存储在局部变量中比执行它更有效。此外,如果处理共享类的元素,则需要具体确定要定位的元素。因此,'$ this'(点击元素)用于对最近的表单进行“最近”的查找(查找树)。然后,这用于找到您感兴趣的按钮。
您可以通过巧妙地使用具有id号的类或索引来避免一些查找并因此节省处理器周期,或者您可以在select标记中使用data-xxx属性来告诉JS确切要查找的内容...