У меня есть форма, на которой я выполняю некоторую пользовательскую проверку. Это блок JavaScript, который обрабатывает окончательную проверку перед отправкой формы:

$('.enquiry-form-container form').submit(function (e) {
        e.preventDefault();
        var invalid = false;
        var isblank = false;
        //Loop through each input and check if valid or empty
        $('.validate').each(function () {
            if ($(this).hasClass('invalid')) {
                isInValid($(this));
                invalid = true;
            } else {
                //Any fields are blank
                if ($(this).val() === "") {
                    $(this).addClass('blank');
                    isblank = true;
                } else {
                    $(this).addClass('valid');
                    isValid($(this));
                    $(this).removeClass('blank empty');
                }
            }
        });

        if (!invalid & !isblank){ //SEND
            $(this).find(":submit").prop("disabled", true); //Prevent submit to prevent duplicate submissions
            $(this).submit();
        } else { //DONT SEND

        }
    });

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

Uncaught RangeError: Maximum call stack size exceeded(…)

Я понимаю, что это может произойти по ряду причин, обычно это бесконечный цикл. Кто-нибудь может увидеть, где я иду не так в приведенном выше коде? Вызывает ли функция .submit() метод submit() снова ... Если это так, как я могу решить эту проблему и отправить форму, если она проверяется?

Просто для полной ясности, вот мои функции isInValid() и isValid(). Они используются для добавления или удаления соответствующих классов, поэтому я могу по-разному стилизовать вводы в зависимости от ввода.

//VALID INPUT
    function isValid(input) {
        input.addClass('valid');
        input.removeClass('invalid empty blank');
        input.parent().parent().next('.hint').css('visibility', 'hidden');
    }
    //INVALID INPUT 
    function isInValid(input) {
        input.addClass('invalid');
        input.removeClass('valid empty blank');
        input.parent().parent().next('.hint').css('visibility', 'visible');
    }
0
Javacadabra 13 Дек 2016 в 17:57

3 ответа

Лучший ответ

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

Смотрите комментарии ниже для подробностей:

$('.enquiry-form-container form').submit(function (e) {
        var invalid = false;
        var isblank = false;
        // Loop through each input and check if valid or empty
        $('.validate').each(function () {
            if ($(this).hasClass('invalid')) {
                isInValid($(this));
                invalid = true;
                e.preventDefault();
                return;
            } else {
                // Any fields are blank
                if ($(this).val() === "") {
                    $(this).addClass('blank');
                    isblank = true;
                    e.preventDefault();
                    return;
                } else {
                    $(this).addClass('valid');
                    isValid($(this));
                    $(this).removeClass('blank empty');
                }
            }
        });

        // If we've gotten this far, the form is good and will be submitted.   

        // No need for an if/then/else here because you've already trapped 
        // the conditions that would prevent the form from being submitted
        // above.

        // Prevent submit to prevent duplicate submissions
        $(this).find(":submit").prop("disabled", true); 
    });

Это также хорошая идея, чтобы отделить ваш код проверки в его собственную функцию, так что переработанный пример будет:

$('.enquiry-form-container form').submit(function (e) {
  // You only need to worry about cancelling the form's submission
  // if the form is invalid:
  if (!validate()) {
    e.preventDefault();
    return;
  }

  // If it is valid, you don't need to interfere in that process, but
  // you can certainly do other "valid" operations:

  // Prevent submit from being clicked to prevent duplicate submissions
  $(this).find(":submit").prop("disabled", true);  
});

function validate() {
  // This function doesn't worry about cancelling the form's submission. 
  // Its only job is to check the elements, style them according to 
  // their validity (and, in a perfect world, the styling would be off-
  // loaded to anther function as well) and return whether the form is 
  // valid or not.

  var invalid = false;
  var isblank = false;

  // Loop through each input and check if valid or empty
  $('.validate').each(function () {
    if ($(this).hasClass('invalid')) {
      isInValid($(this));
      invalid = true;   
    } else {
      // Any fields are blank
      if ($(this).val() === "") {
        $(this).addClass('blank');
          isblank = true;
      } else {
        $(this).addClass('valid');
        isValid($(this));
        $(this).removeClass('blank empty');
      }
    }
  });

  // If invalid or isblank is true, there was a problem and false
  // should be returned from the function
  return !invalid || !isblank;
}
5
Scott Marcus 30 Дек 2017 в 00:58

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

$('.enquiry-form-container form').submit(function (e) {
    // remove the e.preventDefault();
    var invalid = false;
    var isblank = false;
    //Loop through each input and check if valid or empty
    $('.validate').each(function () {
        if ($(this).hasClass('invalid')) {
            isInValid($(this));
            invalid = true;
        } else {
            //Any fields are blank
            if ($(this).val() === "") {
                $(this).addClass('blank');
                isblank = true;
            } else {
                $(this).addClass('valid');
                isValid($(this));
                $(this).removeClass('blank empty');
            }
        }
    });

    if (!invalid & !isblank){ //SEND
        $(this).find(":submit").prop("disabled", true); //Prevent submit to prevent duplicate submissions
        //$(this).submit(); // this should be removed
    } else { //DONT SEND
           e.preventDefault();
    }
});
1
Hakan Fıstık 11 Мар 2018 в 08:12

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

$('.enquiry-form-container form').submit(function (e) {
        e.preventDefault();
        var invalid = false;
        var isblank = false;
        //Loop through each input and check if valid or empty
        $('.validate').each(function () {
            if ($(this).hasClass('invalid')) {
                isInValid($(this));
                invalid = true;
            } else {
                //Any fields are blank
                if ($(this).val() === "") {
                    $(this).addClass('blank');
                    isblank = true;
                } else {
                    $(this).addClass('valid');
                    isValid($(this));
                    $(this).removeClass('blank empty');
                }
            }
        });
        if (!invalid & !isblank){ //SEND
            $(this).find(":submit").prop("disabled", true); //Prevent submit to prevent duplicate submissions
            return true;
        } else { //DONT SEND
            return false;
        }        
    });
1
Hakan Fıstık 13 Дек 2016 в 15:42