8

是)我有的:

我有一个通过 AJAX 提交的表单。

<%= form_for([@map, @annotation], :remote => true ) do |f| %>
   ...
   <%= f.submit "Save annotation", :class => "btn btn-primary", :id => "annotation-submit-button" %>
<% end %>

我想要的是:

我想防止重复提交。由于表单只有在请求成功完成后才会消失,所以只要数据库还没有完成数据写入,用户就可以点击提交按钮。我不想那样,很明显。

我试过的:

我尝试将它添加到提交按钮本身 - 但它不起作用。该按钮被禁用,但没有数据发送。

:onclick => "this.disabled = true"

我还尝试将单击处理程序添加到提交按钮。这与之前的效果相同。实际上没有数据发送到控制器,但按钮被禁用。

$("#annotation-submit-button").click(function(event) {
  $(this).attr("disabled", "disabled");
  return false;
});

也试过同样没有返回false。禁用按钮后没有任何反应。

$("#annotation-submit-button").click(function(event) {
  $(this).prop("disabled", "disabled");
});

我开始认为这是特定于 Rails 的东西?

4

4 回答 4

20

disable_with在 Rails 3 及更高版本中尝试这样的视图:

<%= f.submit "Save annotation", :data => {:disable_with => "Saving..."}, ... %>

对于 Rails 2:

<%= f.submit "Save annotation", :disable_with => "Saving...", ... %>
于 2012-07-16T14:20:35.960 回答
2

禁用按钮应该可以正常工作。

只需禁用执行 ajax 调用的同一功能中的按钮即可。

$("#annotation-submit-button").click(function(event) {
  // do ajax call
  $.ajax(...);
  // disable the button
  $(this).prop("disabled", true);
  // prevent the standard action
  return false;
});

但是,从 jQuery 1.6 开始,您应该prop()使用attr().

编辑:

在回复您的评论时,请尝试省略,return false;这样您就不会中断通过 Rails 执行表单提交。

$("#annotation-submit-button").click(function(event) {
  // disable the button
  $(this).prop("disabled", "disabled");
  // do not return false since this stops the event propagation
});
于 2012-07-16T13:57:15.097 回答
1

通过 jQuery:您可以执行以下操作来处理您想要的操作

$.ajax({
  .....,
  beforeSend: function (){ $('#your-button').attr('disabled', 'disabled'); },
  success: function (){ 
    // Here you can enable the button
  }
});

希望这可以帮助你

于 2012-07-16T14:01:53.877 回答
0

所有人,在回顾了您的想法并在我的团队中交谈后,我们得到了解决方案:

(function ($) {
  /**
   * 使用:
   *   在jquery的ajax方法中加入参数:beforeSend
   *   例如:beforeSend: function(){return $.preventMultipleAjax(event, 5000)}
   *
   * @param event
   * @param delay_duration
   * @returns {boolean}
   */
  $.preventMultipleAjax = function (event, delay_duration) {
    delay_duration = delay_duration || 3000;
    var target = $(event.target);
    var last_click_time_stamp = target.attr("_ajax_send_time_stamp") || 0;
    var time_duration = last_click_time_stamp ? event.timeStamp - last_click_time_stamp : 0;
    //console.debug("preventMultipleAjax", last_click_time_stamp, time_duration);
    if (time_duration && time_duration < delay_duration) {
      return false;
    } else {
      //console.debug("skip preventMultipleAjax~");
      target.attr("_ajax_send_time_stamp", event.timeStamp);
      return true;
    }
  };

  /**
   * 防止按钮重复点击。
   * NOTICE: #1 需要在作用点之前调用此方法 #2 stopImmediatePropagation 会阻止后面的所有事件包括事件冒泡
   * @delay_duration 两次点击的间隔时间
   */
  $.fn.preventMultipleClick = function (delay_duration) {
    delay_duration = delay_duration || 3000;
    var last_click_time_stamp = 0;
    var time_duration = 0;
    $(this).bind('click', function (event) {
      time_duration = last_click_time_stamp ? event.timeStamp - last_click_time_stamp : 0;
      //console.debug("preventMultipleClick", last_click_time_stamp, time_duration);
      if (time_duration && time_duration < delay_duration) {
        event.stopImmediatePropagation();
      } else {
        //console.debug("skip preventMultipleClick~");
        last_click_time_stamp = event.timeStamp;
      }
    });
  };
})(jQuery);

如果你喜欢我会添加它作为一个小插件~谢谢你的建议~

于 2013-11-23T11:44:20.910 回答