开发者问题收集

表格提交

2016-12-13
157

我有一个表单,正在对其实施一些自定义验证。这是处理表单提交前最终检查的 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');
    }
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;
}
Scott Marcus
2016-12-13

我认为您的主要问题是从 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;
        }        
    });
Raghav Patel
2016-12-13

我认为您的主要问题是从提交句柄内部调用 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();
    }
});
Hakan Fıstık
2016-12-13