Подтвердить что ты не робот

ASP.NET MVC - Как предотвратить двойной клик submit с jquery.validate.unobtrusive lib?

Мне нужно избегать поведения отправки двойного клика. Я использую проверку клиента с ненавязчивой библиотекой. У меня есть следующий код для избежания двойного клика:

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

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

     jQuery('form').preventDoubleSubmit();

К сожалению, если в моей форме есть допустимые поля (например, обязательное поле), код выше все еще запущен, следовательно, даже если я исправлю ошибки в форме, я не смогу их отправить еще раз.

Как я могу запустить код двойного щелчка после успешной проверки валидации?

4b9b3361

Ответ 1

Я решил его с помощью следующего кода:

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. (вы можете использовать дополнительное скрытое поле для их зарядки перед отправкой)

что он, надеюсь, поможет

Родриго

EDIT: Благодаря этим сообщениям: jquery newbie: объединить проверку с кнопкой hidding submit

Ответ 2

Вы также можете использовать событие JQuery One.

Я обнаружил, что могу пройти мимо большинства охранников от двойных щелчков, дважды щелкнув быстро. Использование одного события - единственный верный способ удостовериться, что событие запускается только один раз. Я не думаю, что этот метод будет работать "из коробки" с тегом type = submit. Вместо этого вы можете просто использовать кнопку типа ввода = или JQueryUI.button().

$("#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); });
   }
});

Очевидно, вы могли бы добавить здесь код отключения, если хотите дать отзыв пользователю, что кнопка больше не работает. Одним из замечательных побочных эффектов использования события One является то, что на самом деле вам не нужно отключать кнопку, вы можете использовать собственный стиль.

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 One: http://api.jquery.com/one/

Ответ 3

Основываясь на популярном ответе Ryan P, я создал следующее общее решение, которое также работает с моей формой ajax.

украсьте свою собственную кнопку отправки следующим классом:

<button type="button" class="one-click-submit-button">Submit</button>

Добавьте в свой файл javascript следующее:

function OneClickSubmitButton() {
    $('.one-click-submit-button').each(function () {
        var $theButton = $(this);
        var $theForm = $theButton.closest('form');

        //hide the button and submit the form
        function tieButtonToForm() {
            $theButton.one('click', function () {
                $theButton.hide();
                $theForm.submit();
            });
        }

        tieButtonToForm();

        // This handler will re-wire the event when the form is invalid.
        $theForm.submit(function (event) {
            if (!$(this).valid()) {
                $theButton.show();
                event.preventDefault();
                tieButtonToForm();
            }
        });
    });
}

OneClickSubmitButton();

так как это форма 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').each(... напрямую.

Ответ 4

Почему бы просто не использовать:

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

Ответ 5

У меня есть форма, которая использует ненавязчивую проверку MVC3 и модель представления с [RemoteAttribute]. Мне кажется, что событие отправки формы только срабатывает после того, как все проверки прошли. В настоящее время я использую это и, похоже, работает:

<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');
})

;

Я установил точки останова как для метода действия проверки удаленных атрибутов, так и для метода действия HttpPost. При нажатии кнопки "Отправить" первый раз ударяет точку останова по методу действия проверки. В этот момент кнопка все еще включена. Я могу щелкнуть его несколько раз, и после возобновления метода проверки HttpPost попадает только один раз. Когда HttpPost нажата, кнопка отправки отключена.

Обновление

Правильно ты Алекс. Таким образом, обновленная версия выше будет выглядеть так:

$('form').on('submit', function() {
    $(this).find('input[type="submit"][data-app-disable-on-submit="true"]')
                .attr('disabled', 'disabled');
})

Ответ 6

Я использую другой подход к этому. Не подключайте событие клика к кнопке, а отправляйте событие формы. Работает как очарование, чтобы предотвратить множественные одновременные представления форм.

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, вы должны вызвать initFormsToPreventSimultaneousSubmits ('# formId') в событии OnComplete параметров AjaxOptions. Потому что иначе форма будет по-прежнему отмечена как отправка, когда она будет выполнена. Когда используется "нормальная" почта формы, это не проблема.

Ответ 7

Расширяет ответы Alex и Ryan P для учета ситуаций, когда проверка 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();
        });
    });
};

Ответ 8

 $('form').submit(function () {
 $('input[type="submit"]', this).attr('disabled', 'disabled');
   });

Ответ 9

Мне удалось исправить аналогичную проблему с несколькими строками кода. Я предпочитаю это, если вы не хотите "предупреждать" пользователя о том, что они дважды щелкнули и просто молча игнорировали второй щелчок.

Я только что сделал глобальную переменную javascript, которую я переключил, когда моя функция выполнялась во время критического раздела. Это продолжало последующие вызовы функций от повторного выполнения одного и того же раздела.

 var criticalSection = false;

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