简体   繁体   English

寻求更优雅的解决方案来防止Default()困境

[英]Seeking more elegant solution to preventDefault() dilemma

I have a jQuery form-submission routine that has an input integrity check in ERROR_CHECK.PHP that relies on GET variables passed to it for inspection. 我有一个jQuery表单提交例程,该例程在ERROR_CHECK.PHP中具有输入完整性检查,该检查依赖于传递给它的GET变量进行检查。 If the values passed to it are malformed, then an alert box appears that explains the error and how the form data should be remedied. 如果传递给它的值格式错误,则会出现一个警告框,说明错误以及应如何纠正表单数据。 This alert box will need to pop up until the form data is no longer malformed, at which point that data is used for repopulating data on the page. 将需要弹出此警报框,直到表单数据不再格式错误为止,此时该数据将用于重新填充页面上的数据。

Thus, in the jQuery routine I'm at the mercy of our friend preventDefault() , and I have found a solution that does work, but not elegantly. 因此,在jQuery例程中,我受我们的朋友preventDefault()的摆布,并且我找到了一个可行的解决方案,但效果并不理想。 The variable allowSubmit is initialized as FALSE and remains that way—with preventDefault() also in effect—until the form data passes the integrity check, at which point allowSubmit switches to TRUE ...but that only happens with the submission of the correctly-formed input data. 变量allowSubmit初始化为FALSE并保持这种方式-并同时生效了preventDefault() ,直到表单数据通过完整性检查为止,此时allowSubmit切换为TRUE ...,但这仅在提交正确的代码后才发生-形成的输入数据。 This means the user must submit the form a SECOND TIME in order for the form data to be used to replace data on the page...and that, of course, is not a solution (press the submit button twice?) 这意味着用户必须提交表单第二秒,以便表单数据可用于替换页面上的数据...这当然不是解决方案(按两次提交按钮?)

However, by dynamically submitting the form (here, with the $('#my_form').submit() statement) immediately after resetting allowSubmit to TRUE , I've submitted the form again, thereby allowing the user to submit correctly-formatted data ONCE, as it should be from the get-go. 但是,通过在将allowSubmit重置为TRUE之后立即动态提交表单(在这里,使用$('#my_form').submit() statement) ,我再次提交了表单,从而允许用户提交格式正确的数据一次,应该从一开始就做。

This is obviously a band-aid solution and not elegant. 显然,这是一个创可贴解决方案,并不优雅。 Can anyone see a more elegant way to structure this? 谁能看到一种更优雅的方式来构造它? (I'm working with jQuery fashioned by another developer, and this occurs in the midst of a longer self-calling JQuery function, and I have to work with it on its own terms, lest I have to refashion all other parts of the larger function in which it occurs. (我正在使用由另一位开发人员开发的jQuery,并且这种情况发生在更长的自调用JQuery函数之中,并且我必须按自己的意愿使用它,以免不得不重新修改较大部分的所有其他部分。它发生的功能。

Here's a distillation of the code (with self-describing variables, etc.), which works as described, although not as elegantly as I'd like: 这是对代码的精炼(带有自描述变量等),它的工作原理与所描述的一样,尽管不如我所希望的那样优雅:

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

What you are doing is okay, your other options might be to write a click handler for a generic button and submit the form through that event after validation, then you wont need to preventDefault as you won't be preventing any kind of submit action. 您正在执行的操作还可以,您的其他选择可能是为通用按钮编写一个点击处理程序,并在验证后通过该事件提交表单,然后您将需要preventDefault,因为您将不会阻止任何形式的提交动作。 Another solution might be to re-trigger the event after validation. 另一个解决方案可能是在验证后重新触发事件。

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

You could try using an async: false setting using $.ajax (I don't know what your php is returning, so I am just "pretending" it's a json array/string like so echo json_encode(array("response"=>$trueorfalse)); ): 您可以尝试使用async: false $.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>

If you use async: false it runs the script in order and waits to execute the rest of the script until after it receives a response. 如果使用async: false它将按顺序运行脚本,并等待执行脚本的其余部分,直到收到响应为止。 Scott G. says you can do it with what you have with some slight modifications so I would try that first. Scott G.说您可以对现有的东西做一些细微的修改,所以我会先尝试一下。

The callback solution you have doesn't seem unreasonable. 您拥有的回调解决方案似乎并不合理。 I agree with @scott-g that a generic button click event handler would probably be your best bet. 我同意@ scott-g的观点,通用按钮单击事件处理程序可能是最好的选择。 A more testable way to write what you have here may be: 一种更可测试的方式来编写您的内容可能是:

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM