Asp.net mvc 3 ASP.NET MVC-如何使用jquery.validate.unobtrusive lib防止双击提交?

Asp.net mvc 3 ASP.NET MVC-如何使用jquery.validate.unobtrusive lib防止双击提交?,asp.net-mvc-3,double-submit-prevention,unobtrusive,Asp.net Mvc 3,Double Submit Prevention,Unobtrusive,我需要避免双击提交行为。我正在使用客户端验证和不引人注目的库。我有以下避免双重clic的代码: jQuery.fn.preventDoubleSubmit = function () { var alreadySubmitted = false; return jQuery(this).submit(function () { if (alreadySubmitted) return false;

我需要避免双击提交行为。我正在使用客户端验证和不引人注目的库。我有以下避免双重clic的代码:

jQuery.fn.preventDoubleSubmit = function () {
         var alreadySubmitted = false;
         return jQuery(this).submit(function () {

             if (alreadySubmitted)
                 return false;
             else {
                 alreadySubmitted = true;
             }
         });
     };

     jQuery('form').preventDoubleSubmit();
不幸的是,如果我的表单有一些有效的字段(例如,必填字段),上面的代码仍然会被触发,因此,即使我更正了表单上的任何错误,我也无法再次提交它


验证成功完成后,如何激发双击代码?

我用以下代码解决了这个问题:

var tryNumber = 0;
 jQuery('input[type=submit]').click(function (event) {
     var self = $(this);

     if (self.closest('form').valid()) {
         if (tryNumber > 0) {
             tryNumber++;
             alert('Your form has been already submited. wait please');
             return false;
         }
         else {
             tryNumber++;
         }
     };
 });
注意:您还可以更换:

return false;
行,用于:

self.attr('disabled', true);
但是,如果您在控制器上使用提交按钮的名称作为额外的逻辑,它们将作为null发送。(您可以在提交之前使用其他隐藏字段对其收费)

就这样,希望有帮助

罗德里戈

编辑:感谢这些帖子:
您也可以使用

我发现,通过快速双击,我可以通过大多数防止双击的措施。使用一个事件是确保事件只触发一次的唯一正确方法。我认为这种技术在输入类型为submit标记的情况下“开箱即用”是行不通的。相反,您可以简单地使用输入类型=按钮或

$("#submitButton").one("click", function(event) {
   $('#theForm').submit();
});
如果需要根据验证错误(或其他情况)重新连接事件,我建议您为事件处理程序创建一个函数。该函数在本例中不是必需的,因为事件处理程序所做的只是提交表单,但在更复杂的场景中,您可能希望避免重复

function submitClick(event) {
   $('#theForm').submit();
}

$("#submitButton").one('click', function(event) {
   submitClick(event);
});

// This handler will re-wire the event when the form is invalid.
$('#theForm').submit(function(event) {
   if (!$(this).valid()) {
      event.preventDefault();
      $('#submitButton').one('click', function(event) { submitClick(event); });
   }
});
如果您想向用户反馈按钮不再工作,您显然可以在此处添加禁用代码。使用“一个事件”的一个重大副作用是,您实际上不必禁用按钮,您可以使用自己的样式

function submitClick(event) {
   $('#submitButton').addClass('disabledButton');
   $('#theForm').submit();
}

$("#submitButton").one('click', function(event) {
   submitClick(event);
});

// This handler will re-wire the event when the form is invalid.
$('#theForm').submit(function(event) {
   if (!$(this).valid()) {
      event.preventDefault();
      $('#submitButton').one('click', function(event) { submitClick(event); });
      $('#submitButton').removeClass('disabledButton');
   }
});
JQuery一个事件:

为什么不使用:

function disableButtons() {
    var form = $(this);
    var btns = $("input:submit", form);

    if (!form.valid()) {
        // allow user to correct validation errors and re-submit
        btns.removeAttr("disabled");
    } else {
        btns.attr("disabled", "disabled");
    }
}
要禁用按钮并使用以下命令激活它:

$("form").bind("submit", disableButtons);

我有一个使用MVC3不引人注目的验证的表单,还有一个带有[RemoteAttribute]的viewmodel。 在我看来,表单的提交事件只有在通过所有验证后才会触发。我目前正在使用它,它似乎很有效:

<input type="submit" value="Submit the Form" 
    data-app-disable-on-submit="true" />

$('form').live('submit', function() {
    $(this).find('input[type="submit"][data-app-disable-on-submit="true"]')
                .attr('disabled', 'disabled');
})
基于此,我创建了以下通用解决方案,该解决方案也适用于我的ajax表单

使用以下类装饰自定义提交按钮:

<button type="button" class="one-click-submit-button">Submit</button>
由于这是一个ajax表单,如果服务器验证失败,我们希望重新加载处理程序

function MyForm_OnSuccess() {
    if (true if your form passed validation logic) {
        //do something since your form submitted successfully
    } else { //validation failed on server
        OneClickSubmitButton(); //reinitialize the button logic
    }
}
显然,如果您没有ajax表单,您可以省略整个
OneClickSubmitButton
功能业务并运行
$('.one click submit button')。每个(…
)都直接运行。

将答案扩展到可能缺少jQuery验证以及单个表单中存在多个提交按钮的情况

oneClickSubmitButton = function () {
    $('input[type=submit], button[type=submit], input[type=image]').each(function () {
        var $theButton = $(this);
        var $theForm = $theButton.closest('form');

        //hide the button and submit the form
        function tieButtonToForm() {
            $theButton.one('click', function () {
                $theButton.addClass('ui-state-disabled');
            });
        }

        tieButtonToForm();

        $theForm.submit(function (event) {
            // Only proceed for the clicked button
            if (!$theButton.hasClass("ui-state-disabled"))
                return;

            // If jQuery Validation is not present or the form is valid, the form is valid
            if (!$theForm.valid || $theForm.valid())
                return;

            // Re-wire the event
            $theButton.removeClass('ui-state-disabled');
            event.preventDefault();
            tieButtonToForm();
        });
    });
};

我使用了一种不同的方法。不是连接到按钮的点击事件,而是连接到表单的提交事件。它的作用就像一个符咒,可以防止多个表单同时提交

function initFormsToPreventSimultaneousSubmits(selector) {
    if (!selector) {
        selector = 'form'; // No selector supplied, apply to all forms on the page
    }

    // Make sure all forms that conform to selector are marked as not submitting
    $(selector).each(function()
    {
        var $form = $(this);
        $form.data('submitting', false);
    });

    // Attach to submit event of all forms that conform to selector
    $(selector).off('submit').on('submit', function (e) {
        var $form = $(this);

        if (!$form.valid || $form.valid()) { // Make sure to only process when the form is valid or jquery validation is not used
            if ($form.data('submitting')) {
                // form is already submitting. Classic case of double click on one of the submit buttons of the form. Stop the submit
                e.preventDefault();
                return false;
            } else {
                // All ok, mark the form as submitting and let the form perform the submit
                $form.data('submitting', true);
                return true;
            }
        }
    });
}
在文档就绪时,我调用initFormsToPreventSimultaneousSubmits()初始化页面上的所有表单


唯一需要记住的是,当您使用ajax表单post时,调用initFormsToPreventSimultaneousSubmits(“#formId”)在AjaxOptions设置的OnComplete事件上。否则,表单完成后仍将标记为提交。当使用“正常”表单帖子时,这不是问题。

我可以用几行代码修复类似问题。如果您不想“提醒”,我更喜欢这样对用户来说,他们双击了,只是默默地忽略了第二次单击

我刚刚创建了一个全局javascript变量,当我的函数在一个关键部分执行时,我会对该变量进行切换。这样可以防止后续函数调用重新执行同一部分

 var criticalSection = false;

 SomeOnClickEventFired = function () {
      if (!criticalSection)
      {
            criticalSection = true;
            //Ajax Time
            criticalSection = false;
      }
 }

太好了!感谢您提供的信息,该行为将在此基础上完成。我尝试了javascript代码,但在$(this).valid()函数中出现错误。它表示对象$(this)没有有效的()函数.
.live
已被弃用,在本例中被
.on
.submit
替换。无论如何,它对我不起作用。是
$theForm.submit()真的需要?表单将提交。我把它删除了,它看起来很好。这个解决方案对我起作用。今天的可访问性标准,你也可以考虑包括<代码> .Atr(“咏叹调忙碌”,“true”);< /代码>这是最通用的,它工作得很好。谢谢。
 $('form').submit(function () {
 $('input[type="submit"]', this).attr('disabled', 'disabled');
   });
function initFormsToPreventSimultaneousSubmits(selector) {
    if (!selector) {
        selector = 'form'; // No selector supplied, apply to all forms on the page
    }

    // Make sure all forms that conform to selector are marked as not submitting
    $(selector).each(function()
    {
        var $form = $(this);
        $form.data('submitting', false);
    });

    // Attach to submit event of all forms that conform to selector
    $(selector).off('submit').on('submit', function (e) {
        var $form = $(this);

        if (!$form.valid || $form.valid()) { // Make sure to only process when the form is valid or jquery validation is not used
            if ($form.data('submitting')) {
                // form is already submitting. Classic case of double click on one of the submit buttons of the form. Stop the submit
                e.preventDefault();
                return false;
            } else {
                // All ok, mark the form as submitting and let the form perform the submit
                $form.data('submitting', true);
                return true;
            }
        }
    });
}
 var criticalSection = false;

 SomeOnClickEventFired = function () {
      if (!criticalSection)
      {
            criticalSection = true;
            //Ajax Time
            criticalSection = false;
      }
 }