Pause form submission for validation

2019-01-28 00:28发布

问题:

I have some form, which uploads file in an iframe. I'd like to hold it's submission until I'll check if it's valid with ajax. How can I do this ? My code pauses the submission and returns validation result (currently just a dummy function which returns 'result': 'true') but then the 'submit' action is not performed. Also Is it normal that it takes ~2s to show response data after getting response 200 status ?

Here's my html:

<div id="message" style="background:black; width:400px; height:80px; display:none; color:white;">
</div>
<h1>Submit</h1>
<form action="{{upload_url}}" target="upload_target" method="POST" id="file_upload_form" enctype="multipart/form-data">
    {% render_upload_data upload_data %}
    <table>{{ form }}</table>    
    <p>
        <input type="hidden" maxlength="64" name="myfileid" value="{{ myfileid }}" >
    </p>
    <p>
        <input type="submit" id="file_upload_submit" value="Submit" />
    </p>
    <iframe id="upload_target" name="upload_target" src="" style="width:0;height:0;border:0px solid #fff;"></iframe>
</form>

Js:

$(function() {

    $('#file_upload_submit').click(function(e){
        e.preventDefault();
        var fileUploadForm = document.getElementById('file_upload_form');

        $.ajax({
            type: "POST",
            url: '/artifact/upload/check-form/',
            data: 'foo=bar',
            dataType: "json",
            success: function(data){
                if(data['result'] == "true"){
                    $("#message").show();
                    $("#message").fadeIn(400).html('<span>'+data["message"]+'</span>');
                    setTimeout(function(){
                        $("#message").fadeOut("slow", function () {
                            $("#message").hide();
                        });
                    }, 1500);
                     $('#file_upload_form').attr('target','upload_target').submit(function(){
                        alert('Handler for .submit() called.');
                        return false;
                    });
                }
                else{
                    $("#message").show();
                    $("#message").fadeIn(400).html('<span">'+data["message"]+'</span>');
                    setTimeout(function(){
                        $("#message").fadeOut("slow", function () {
                            $("#message").hide();
                        });
                    }, 1500);                    
                    return false;
                }
            }
        });
        return false;        
    });

});    

</script>

and link: http://ntt.vipserv.org/artifact/


EDIT

With the code below I'm able to perform validation, then when it's result is positive form is submitted. Now if I hardcode target for form, my alert is not shown and I'm pretty sure that the upload is not performed (unfortunately list of uploads is refreshed each 8h sa I'll know if it worked in some time). If target is not specified, file is uploaded with redirect so the whole 'submit' event listener is ommitted.

<script>  
    $('#fake_upload_submit').click(function(e){
        e.preventDefault();

        var fileUploadForm = document.getElementById('file_upload_form');
        fileUploadForm.addEventListener("submit", function() {
            alert("sent in iframe");
            fileUploadForm.target = 'upload_target';
        }, false);       

        $.ajax({
            type: "POST",
            url: '/artifact/upload/check-form/',
            data: 'foo=bar',
            dataType: "json",
            success: function(data){
                if(data['result'] == "true"){
                    $("#message").show();
                    $("#message").fadeIn(400).html('<span>'+data["message"]+'</span>');
                    setTimeout(function(){
                        $("#message").fadeOut("slow", function () {
                            $("#message").hide();
                        });
                    }, 1500);

                    fileUploadForm.submit();

                }
                else{
                    $("#message").show();
                    $("#message").fadeIn(400).html('<span">Response false</span>');
                    setTimeout(function(){
                        $("#message").fadeOut("slow", function () {
                            $("#message").hide();
                        });
                    }, 1500);                    
                    return false;
                }
            }
        });
        return false;        
    });   
</script>

html:

<div id="message" style="background:black; width:400px; height:80px; display:none; color:white;">
</div>
<h1>Submit</h1>
<form action="{{upload_url}}" method="POST" target="" id="file_upload_form" enctype="multipart/form-data">
    {% render_upload_data upload_data %}
    <table>{{ form }}</table>    
    <p>
        <input type="hidden" maxlength="64" name="myfileid" value="{{ myfileid }}" >
    </p>
    <p>
        <input type="submit" style="display:none" id="true_upload_submit" value="Submit" />
    </p>    
    <iframe id="upload_target" name="upload_target" src="" style="width:0;height:0;border:0px solid #fff;"></iframe>
</form>
    <p>
        <input type="submit" id="fake_upload_submit" value="Submit" />
    </p>

回答1:

After the validation you register a new submit event handler, but there is nothing that submits the form, so you would have to click the button again to get it submitted.

You can just submit the form instead of adding a submit handler:

$('#file_upload_form').attr('target','upload_target').submit();


回答2:

I'm thinking that you might be over thinking the submission of the form, but I might also be reading this wrong. I may also not have all of the facts. Would it not be better to just submit the form via the ajax call and return the result of the submission (validation failed or succeeded)?

Pseudo code:

jQuery:

var formData = data;
ajax(formData);

Form Processing:

if(valid) {
  submit(formData);
  return true;
} else {
  return false;
}

I can provide real code if needed.



回答3:

It would likely be easiest for you (if possibly more annoying for your users) if you used synchronous XHR instead of asynchronous.

Alternatively, intercept the form submission using JavaScript and submit it using XHR iff the server-side validation succeeds.



回答4:

How about avoiding the problem altogether, having a hidden submit button to submit the form and have a visible button that starts validation and if it's ok then it performs a click on the proper hidden submit button ?



回答5:

Guffa is correct. I believe the following change will make the first script work. Change

                     $('#file_upload_form').attr('target','upload_target').submit(function(){
                        alert('Handler for .submit() called.');
                        return false;
                    });

to

                     $('#file_upload_form').attr('target','upload_target').submit();

It's your debugging that has broken the submission. If you want to keep the debugging, change the code to:

                     $('#file_upload_form').attr('target','upload_target').submit(function(){
                        alert('Handler for .submit() called.');
                        return true;
                    }).submit();

You must call submit() on its own to trigger the submission event. If the submit function returns false, it will not continue, so you must have it return true instead.

This is the third version of this question that you've posted. I agree with others that you may be addressing your problem in a way that is overcomplicated. This is a case where you may want to avoid JavaScript altogether and go for a straightforward HTML post. Is there a compelling reason why this is not an option?