【问题标题】:Disabling Rails form_for submit button in a do/end block在 do/end 块中禁用 Rails form_for 提交按钮
【发布时间】:2014-08-11 21:53:20
【问题描述】:

我目前有一个嵌套在 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 代码在每个单独创建的对象上工作而不影响其他对象?

【问题讨论】:

    标签: javascript jquery ruby-on-rails forms


    【解决方案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 确切地查找什么...

    【讨论】:

    • var disabled = $this.val() == ''; $button.prop('禁用', 禁用); $button.css("background-color", disabled ? "" : "#008C00"); - 消除丑陋的 ifs 运动为您带来。
    • 我尝试在第一行 jQuery 中使用 $('.show_radio_button') 但由于某种原因,除非我将其保留为 $('#show_box_id'),否则它不起作用。如果我确实使用了 $('.show_radio_button'),它确实会阻止其他人点亮,但如果我在不是第一个对象的对象上使用表单,jQuery 仍然不会做任何事情。
    • 好吧,我想我差不多明白了,我使用了你的代码,但将 标签更改为 true %> - 所以我添加了一个 {}上课前。现在唯一不起作用的是 :include_blank => true
    • 知道了 - 只需在上课前将空白放入空的 {} 中。非常感谢您的帮助!
    • 没问题!乐意效劳。此外,您可以在控制器中执行一次Box.all.collect { |p| [ p.box_number, p.id ] },然后将其传递到实例变量中,而不是在模板中多次查找数据库。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多