ASP.NET MVC-как предотвратить двойной щелчок отправить с помощью jquery.утверждать.ненавязчивая Либ?

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

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

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

     jQuery('form').preventDoubleSubmit();

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

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

9 ответов


вы также можете использовать jQuery одно событие.

я обнаружил, что могу пройти мимо большинства охранников от двойных щелчков, дважды щелкнув быстро. Использование одного события-единственный верный способ убедиться, что событие запускается только один раз. Я не думаю, что этот метод будет работать "из коробки" с тегом ввода type=submit. Вместо этого вы можете просто использовать кнопку ввода type=или 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); });
   }
});

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

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 Одно Событие: http://api.jquery.com/one/


я решил его со следующим кодом:

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 новичок: объедините validate с кнопкой отправки hidding


на основе популярный ответ Райана П Я создал следующее общее решение, которое также работает с моей формой 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(... напрямую.


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

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 и viewmodel с [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');
})

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

в готовом документе я вызываю initFormsToPreventSimultaneousSubmits () для ввода всех форм на странице.

единственное, что нужно помнить, это то, что при использовании сообщения формы ajax необходимо вызвать initFormsToPreventSimultaneousSubmits ('#formId') на событии OnComplete Параметры AjaxOptions. Потому что в противном случае форма все равно будет помечена как отправляющая, когда она будет сделана. Когда используется "обычная" форма post, это не проблема.


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

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

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

 var criticalSection = false;

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