2014-09-03 140 views
4

我想阻止多个表单提交,但我需要将提交元素的值发布回服务器(以便我知道用户单击了哪个按钮)。禁用表单提交按钮,但发布按钮值

大多数互联网关于抑制多个表单提交的智慧似乎涉及在表单提交期间禁用提交按钮。这可以防止第二次点击该按钮,还可以防止发布该值。

我发现了隐藏提交按钮的JS代码的几个例子,它允许发布它们的值。但是这些例子都用一些“正在处理...”的消息来代替(现在隐藏的)按钮。我真的很想要一个解决方案,向用户显示禁用的按钮,但仍然发布按钮值。

我应该补充一点,我更喜欢一种可以在大多数窗体中使用的标准HTML工作的解决方案。没有神奇的IFrames,隐藏的字段,ID或类名等。我想要一个JS函数,我可以将其隐藏在一个库中,并引用所有现有的表单来启用这种新行为。

(我有一个解决方案,我将发布作为一个答案,但我不得不问遵守的SO禅的问题。)

+0

可以使用http://jsfiddle.net您创建的代码的演示和分享?这将会更有帮助! – UID 2014-09-03 18:28:19

+0

只是出于好奇,为什么你需要知道哪个**提交**按钮被首先点击?通常,每个表单只有一个提交按钮。例如,你有多个_actions_采用相同的参数,并且不想设置几个相同的表单? – Kiruse 2014-09-03 18:46:50

+1

我通常至少有两个按钮:“确定”和“取消”。有时候,我可能还会有类似于“ 2014-09-03 18:52:06

回答

6

这里是(另一个)回答如何的问题以防止用户多次点击表单提交按钮。该解决方案显示该按钮已被禁用。

在封面下,它创建一个禁用的按钮来显示给用户,并隐藏实际的按钮,以便发布其值。我也移动隐藏的按钮,以便额外的元素不会搞乱CSS选择器。

另请注意检查无效表单域。如果您省略此检查,并且表单验证失败,那么用户就会收到一个未发布的表单(因为客户端验证失败),但这些按钮被禁用。

// Disables buttons when form is submitted 
$('form').submit(function() { 
    // Bail out if the form contains validation errors 
    if ($.validator && !$(this).valid()) return; 

    var form = $(this); 
    $(this).find('input[type="submit"], button[type="submit"]').each(function (index) { 
     // Create a disabled clone of the submit button 
     $(this).clone(false).removeAttr('id').prop('disabled', true).insertBefore($(this)); 

     // Hide the actual submit button and move it to the beginning of the form 
     $(this).hide(); 
     form.prepend($(this)); 
    }); 
}); 
0

这里有几个选项:

1.您可以创建一个隐藏的输入和动态表单提交任何的onClick或onHover选项上述按钮之前改变它的值:

2。您可以创建一个隐藏的iframe,它是该表单的目标。点击提交按钮后,您可以取消提交事件,获取所有数据,然后通过iframe以编程方式发送。

+1

回复#1,我想我应该在OP中明确声明,我想要一个不涉及额外(隐藏)表单域或幻数或类值的解决方案。 – 2014-09-03 18:38:49

2

因为除了单击提交按钮之外,您可以通过其他方式提交表单,所以最好将侦听器添加到表单的提交事件中,而不是提交按钮上的单击事件。这个jQuery事件监听器应该能够处理任何形式的表单并防止它被多次提交。

$('form').on('submit', function(e) { 
    if (!$(this).data('submitted')) { 
     $(this).data('submitted', true); 
    } 
    else { 
     e.preventDefault(); 
    } 
}); 

要禁用,您可以添加一些CSS,使形式照看残疾然后添加在表单提交的类名形式的样子。

$('form').on('submit', function(e) { 
    if (!$(this).data('submitted')) { 
     $(this).data('submitted', true).addClass('disabled'); 
    } 
    else { 
     e.preventDefault(); 
    } 
}); 
1

您可以模拟禁用的外观行为。例如。如果你有这样的按钮:

<input id="btn" type="button" onclick="disableMe(this)" value="Submit" /> 

你可以这样定义

.disabled { 
    backround-color:grey; 
    color:darkgrey; 
} 

和JS这样

function disableMe(btn) { 
    btn.className = "disabled"; 
    btn.onclick = function(){return false} 
} 

会发生什么CSS - 首先点击按钮会变成灰色(通过应用CSS)和onclick事件将更改为“返回false”,以阻止将来的点击操作。该按钮将显示并且作为禁用,但不会,因此它不会阻止按钮提交。

0

我想通过双击提交按钮或按两次Enter键来阻止用户导致多个表单提交。我喜欢这个解决方案,因为它不需要隐藏表单域或隐藏提交按钮。

两个关键点是:

  1. 返回真/被点击了假的而不是使用e.preventDefault()和form.submit(),因为form.submit()不知道哪个按钮因此无法传递按钮名称/值。

  2. 禁用按钮pointer-events: none;而不是disabled="disabled",因为disabled属性不会发送按钮名称/值。我相信Internet Explorer 10或以下版本不支持pointer-events: none;

的JavaScript/jQuery代码:

var form_selector = 'form', 
    button_selector = 'button, input[type=submit], input[type=button], input[type=reset]', 
    deactivated_classname = 'state-submitting', 
    deactivated_class = '.'+'state-submitting'; 

// Capture the submit event so it will handle both the 
// enter key and clicking the submit button. 
$(document).on('submit', form_selector, function(e) { 
    var form = e.target, 
     buttons = $(form).find(button_selector); 

    // Returns, because the form is already being submitted by a previous attempt. 
    if($(form).find(deactivated_class).length > 0 ) return false; 

    disableButtons(buttons); 

    // Safari (version 11) bugfix: Safari needs a timeout or it won't 
    // show the deactivated styles. 
    setTimeout(function() { 
    // Must use return true, because using form.submit(), won't pass the button value. 
    return true; 
    }, 50); 
}); 

function disableButtons(buttons) { 
    // Disables all buttons in the form. 
    $(buttons).each(function(index, elem) { 
    $(elem).addClass(deactivated_classname); 
    }); 
} 

对于AJAX的形式,你会想返回响应后重新启用按钮。

$(document).on('ajax:complete', form_selector, function(e) { 
    var form = e.target, 
     buttons = $(form).find(button_selector); 

    enableButtons(buttons); 
}); 

function enableButtons(buttons) { 
    $(buttons).each(function(index, elem) { 
    $(elem).removeClass(deactivated_classname); 
    }); 
} 

CSS:

// The button is disabled while it is submitting. 
.state-submitting { 
    // Turns off hover and click events. Not supported in IE 10 and below. 
    pointer-events: none; 
    opacity: 0.5; 
}