【问题标题】:Seeking more elegant solution to preventDefault() dilemma寻求更优雅的解决方案来防止默认()困境
【发布时间】:2015-09-15 05:27:27
【问题描述】:

我有一个 jQuery 表单提交例程,它在 ERROR_CHECK.PHP 中有一个输入完整性检查,它依赖于传递给它的 GET 变量进行检查。如果传递给它的值格式不正确,则会出现一个警告框,解释错误以及如何纠正表单数据。需要弹出此警告框,直到表单数据不再格式错误,此时该数据用于重新填充页面上的数据。

因此,在 jQuery 例程中,我受制于我们的朋友 preventDefault(),并且我找到了一个可行但不优雅的解决方案。变量allowSubmit 被初始化为FALSE 并保持这种状态——preventDefault() 也有效——直到表单数据通过完整性检查,此时allowSubmit 切换到TRUE...但只有在提交格式正确的输入数据时发生。这意味着用户必须第二次提交表单,以便表单数据用于替换页面上的数据……当然,这不是解决方案(按两次提交按钮?)

但是,通过动态提交表单(此处,在将 allowSubmit 重置为 TRUE 后立即使用 $('#my_form').submit() statement),我再次提交了表单,从而允许用户一次提交格式正确的数据,如它应该是从一开始。

这显然是一个创可贴的解决方案,并不优雅。谁能看到一种更优雅的方式来构建它? (我正在使用由另一个开发人员设计的 jQuery,这发生在一个较长的自调用 JQuery 函数中,我必须按照自己的条件使用它,以免我不得不重新设计更大的所有其他部分它发生的函数。

这里是代码的提炼(带有自描述变量等),它的工作方式与描述的一样,虽然不像我想要的那样优雅:

var allowSubmit = false;
$('#my_form').on('submit', function(e) {
    if (!allowSubmit) { 
        e.preventDefault();
        // Check to see if input data is malformed:
        $.get('error_check.php', { new_element_name: $('#new_element_name').val() }, function(data) {
            if (data != 0) {
                alert("An Error Message that explains what's wrong with the form data");
            } else {
                allowSubmit = true;
                // The line below--an auto-submit--is needed so we don't have to press the submit button TWICE.
                // The variable allowSubmit is set to TRUE whenever the submitted form data is good, 
                // but the code suppressed by e.preventDefault() won't execute until the form is
                // submitted a second time...hence the need for this programmatic form submission here.
                // This allows the user to correct the errant form data, press the submit button ONCE and continue.
                $('#my_form').submit();
            }
        });
    }
    $('#element_name').val($('#new_element_name').val());
});

【问题讨论】:

    标签: javascript php jquery html forms


    【解决方案1】:

    您所做的没关系,您的其他选择可能是为通用按钮编写点击处理程序并在验证后通过该事件提交表单,然后您不需要 preventDefault 因为您不会阻止任何类型的提交动作。另一种解决方案可能是在验证后重新触发事件。

               $("button").click(function() {
                   $("#my_form").submit();
               });
               ...
                    allowSubmit = true;
                    // alternatively
                    jQuery( "body" ).trigger( e );
               ...
    

    【讨论】:

      【解决方案2】:

      您的回调解决方案似乎并不合理。我同意@scott-g 的观点,通用按钮单击事件处理程序可能是您最好的选择。一种更可测试的方式来编写您在这里的内容可能是:

      var formView = {
        $el: $('#my_form'),
        $field: $('#element_name'),
        $newField: $('#new_element_name'),
        $submitBtn: $('#btn-submit')
      }
      
      var handleSubmit = function() {
        var formData = formView.$field.val();
        remoteVerify(formData)
          .done(formView.$el.submit)
          .done(updateForm)
          .fail(handleVerificationError);
      };
      
      var remoteVerify = function(formData) {
        var deferred = $.Deferred();
        var url = 'error_check.php';
        var data = { new_element_name: formData };
        $.get(url, data)
          .done(handleRequest(deferred))
          .fail(handleRequestErr);
        return deferred;
      };
      
      var handleRequest = function(deferred) {
        return function (data, jqxhr) {
          if (data != 0) {
            deferred.reject(jqxhr, "An Error Message that explains what's wrong with the form data");
          } else {
            deferred.resolve(data);
          }
        }
      };
      
      var handleRequestErr = function() {
        // error handling
      }
      
      var updateForm = function () {
        formView.$field.val(formView.$newField.val());
      }
      
      var handleVerificationError = function (jqxhr, errMsg){
        alert(errMsg); 
      }
      
      formView.$submitBtn.on('click', handleSubmit)
      

      【讨论】:

        【解决方案3】:

        你可以尝试使用$.ajax 设置async: false (我不知道你的php返回了什么,所以我只是“假装”它是一个json数组/字符串,就像echo json_encode(array("response"=>$trueorfalse));一样):

        <script>
        $('#my_form').on('submit', function(e) {
                var valid_is    =   true;
                // Check to see if input data is malformed:
                $.ajax({
                        async: false,
                        url: 'error_check.php',
                        type: 'get',
                        data: { new_element_name: $('#new_element_name').val() },
                        success: function(response) {
                            var Valid   =   JSON.parse(response);
                            if(Valid.response != true) {
                                    alert("An Error Message that explains what's wrong with the form data");
                                    valid_is    =   false;
                                }
                        }
                });
        
                if(!valid_is)
                    e.preventDefault();
        
            $('#element_name').val($('#new_element_name').val());
        });
        </script>
        

        如果您使用async: false,它会按顺序运行脚本并等待执行脚本的其余部分,直到收到响应。 Scott G. 说你可以用你现有的东西做一些轻微的修改,所以我会先试试。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-04-28
          • 1970-01-01
          • 2017-08-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多