我有一张表格,我通过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特有的?
答案 0 :(得分:19)
在Rails 3及更高版本的视图中尝试disable_with
:
<%= f.submit "Save annotation", :data => {:disable_with => "Saving..."}, ... %>
对于Rails 2:
<%= f.submit "Save annotation", :disable_with => "Saving...", ... %>
答案 1 :(得分:2)
禁用该按钮应该可以正常工作。
只需在执行ajax-call的同一功能中禁用该按钮。
$("#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
});
答案 2 :(得分:1)
通过jQuery: 您可以执行以下操作来处理您想要的操作
$.ajax({
.....,
beforeSend: function (){ $('#your-button').attr('disabled', 'disabled'); },
success: function (){
// Here you can enable the button
}
});
希望这可以帮到你
答案 3 :(得分: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);
如果你喜欢它,我会把它添加为一个小插件〜 谢谢你的建议〜