【发布时间】:2011-02-07 19:17:13
【问题描述】:
由于不耐烦的用户多次单击提交按钮,我的数据库中不断出现重复条目。
我用谷歌搜索和搜索,找到了一些脚本,但似乎都不够。
如何使用 javascript 或者最好是 jQuery 来防止这些重复条目的出现?
提前谢谢!
【问题讨论】:
标签: javascript jquery html forms
由于不耐烦的用户多次单击提交按钮,我的数据库中不断出现重复条目。
我用谷歌搜索和搜索,找到了一些脚本,但似乎都不够。
如何使用 javascript 或者最好是 jQuery 来防止这些重复条目的出现?
提前谢谢!
【问题讨论】:
标签: javascript jquery html forms
如何禁用提交按钮?我就是做这个的。它工作正常。
$('form').submit(function(){
$('input[type=submit]', this).attr('disabled', 'disabled');
});
免责声明:
这仅在用户浏览器上启用 javascript 时有效。如果提交的数据很重要(比如信用卡购买),那么将我的解决方案视为第一道防线。但是对于许多用例,禁用提交按钮将提供足够的预防。
我会先实现这个仅限 javascript 的解决方案。然后跟踪仍有多少重复记录被创建。如果它为零(或低到不关心),那么你就完成了。如果它对您来说太高,那么对现有记录实施后端数据库检查。
【讨论】:
这应该可以解决问题:
$("form").submit(function() {
$(":submit", this).attr("disabled", "disabled");
});
没有 JQuery?
或者,您可以从 db 进行检查以检查记录是否已存在,如果存在,则不要插入新记录。
【讨论】:
我见过使用的一种技术是为每个打开的表单分配一个唯一的 ID,并根据 ID 只接受每个表单的一次提交。
这也意味着您可以检查人们根本不费心提交的次数,并且您可以检查提交是否真正来自您的表单,方法是检查它是否具有您的服务器创建的 ID。
我知道您要求使用 javascript 解决方案,但如果我需要稳健性,我个人会同时做这两个。
【讨论】:
防止重复发布并不像禁用提交按钮那么简单。还有其他元素可以提交:
使用 jQuery 数据容器将是我的选择。这是一个例子:
$('#someForm').submit(function(){
$this = $(this);
/** prevent double posting */
if ($this.data().isSubmitted) {
return false;
}
/** do some processing */
/** mark the form as processed, so we will not process it again */
$this.data().isSubmitted = true;
return true;
});
【讨论】:
这是我用来避免双击问题的一些 jQuery。它只允许单击提交按钮。
$(document).ready(function() {
$("#submit").on('click', function() {
});
});
【讨论】:
我不确定您使用的是什么语言/框架,或者它是否只是纯 HTML。但是在我编写的 Rails 应用程序中,我在表单按钮 disable_with 上传递了一个数据属性,该属性可防止在事务处理过程中多次单击该按钮。
这是 ERB 的样子。
<%= f.button "Log In", class: 'btn btn-large btn-block btn-primary', data: {disable_with: "<i class='icon-spinner'></i>Logging In..."} %>
【讨论】:
这是我在https://github.com/liberapay/liberapay.com/pull/875 中想到的:
$('form').on('submit', function (e) {
var $form = $(this);
// Check that the form hasn't already been submitted
if ($form.data('js-submit-disable')) {
e.preventDefault();
return false;
}
// Prevent submitting again
$form.data('js-submit-disable', true);
// Set a timer to disable inputs for visual feedback
var $inputs = $form.find(':not(:disabled)');
setTimeout(function () { $inputs.prop('disabled', true); }, 100);
// Unlock if the user comes back to the page
$(window).on('focus pageshow', function () {
$form.data('js-submit-disable', false);
$inputs.prop('disabled', false);
});
});
【讨论】:
here 描述的方法的问题是,如果您使用的是 javascript 验证框架并且验证失败,您将无法在不刷新页面的情况下更正并重新提交表单。
要解决这个问题,您需要插入验证框架的成功事件,然后才将提交控件设置为禁用。使用Parsley,您可以使用以下代码插入表单验证事件:
$.listen('parsley:form:validated', function(e){
if (e.validationResult) {
/* Validation has passed, prevent double form submissions */
$('button[type=submit]').attr('disabled', 'disabled');
}
});
【讨论】:
如果您正在使用客户端验证,并且希望在数据无效时允许额外的提交尝试,您可以仅在表单内容未更改时才允许提交:
var submittedFormContent = null;
$('#myForm').submit(function (e) {
var newFormContent = $(this).serialize();
if (submittedFormContent === newFormContent)
e.preventDefault(true);
else
submittedFormContent = newFormContent;
});
【讨论】:
在How to prevent form resubmission when page is refreshed (F5 / CTRL+R)找到并解决了问题:
<script>
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
</script>
【讨论】:
这就是我为解决问题所做的。
我通过添加 setTimeout 两次禁用了该按钮:
-第一次是让JS表单字段验证工作;
-第二次是启用按钮以防万一在您的后端进行任何验证,这可能会返回错误,因此用户将希望在编辑他的数据后再次尝试提交表单。
$(document).ready(function(){
$('button[type=submit]').on("click", function(){
setTimeout(function () {
$('button[type=submit]').prop('disabled', true);
}, 0);
setTimeout(function () {
$('button[type=submit]').prop('disabled', false);
}, 1000);
});
});
【讨论】: