防止在Rails AJAX表单中提交双重提交

是)我有的:

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

 true ) do |f| %> ...  "btn btn-primary", :id => "annotation-submit-button" %>  

我想要的是:

我想防止双重提交。 由于表单仅在请求成功完成后消失,因此只要数据库尚未完成数据写入,用户就可以单击提交按钮。 显然,我不希望这样。

我尝试过的:

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

 :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特有的?

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

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

对于Rails 2:

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

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

只需在执行ajax-call的同一function中禁用该按钮即可。

 $("#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中断formubmit的执行。

 $("#annotation-submit-button").click(function(event) { // disable the button $(this).prop("disabled", "disabled"); // do not return false since this stops the event propagation }); 

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

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

希望这可以帮到你

所有,在审核了您的想法并在我的团队中进行讨论之后,我们得到了一个解

 (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); 

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