简体   繁体   中英

Submit a Form in a Single Page Application using Flask Without Reloading

I am working on a single page Flask application in python. To change the content of the page, I simply call a javascript function that hides one div and reveals another.

One of these divs contains a form where a user may upload a file, which I run through a python script that parses data from the file.

The problem is that after executing the code, Flask seems to want me to redirect to a new page. I would prefer to return a trigger to simply run my javascript function.

The HTML form:

<form class='upload-form' id='upload-form' action="/upload" method='POST' enctype="multipart/form-data" onsubmit="return show_and_hide('load', 'upload')">
                            <input type="file" name='file' value="Browse...">
                            <input type="submit" value='Upload'>
                        </form>

The Javascript function:

var callFunction;
    function show_and_hide(div_in, div_out){
        var shower = document.getElementById(div_in);
        var hider = document.getElementById(div_out);

        var hider_items = hider.children;
        var i;
        for(i = 0; i < hider_items.length; i++){
            hider_items[i].style.animation = "hide 1s";
        }

        callFunction = setTimeout(change_div, 1000, div_in, div_out);

        var shower_items = shower.children;
        var n;
        for(n = 0; n < shower_items.length; n++){
            shower_items[n].style.animation = "show 1s";
        }
        return true;
    }

And the flask application (I do not actually have it returning ???):

@app.route('/upload', methods=['POST', 'GET'])
def upload_file():
        f = request.files['file']
        new_file_name = str(uuid.uuid1()) + '.zip'

        f.save(os.path.join('uploads/', new_file_name))
        path = 'uploads/' + new_file_name
        return ???

I appreciate any advice! Thank you!

You will need to use JavaScript to POST the files to Flask, since submitting a HTML form will always redirect you. Here's an example using AJAX How can I upload files asynchronously?

Flask needs all view functions (routes) to return a response to send to the client. You can reuturn an empty string and a 200 status to let Flask know you processed the request successfully.

@app.route('/upload', methods=['POST', 'GET'])
def upload_file():
        f = request.files['file']
        new_file_name = str(uuid.uuid1()) + '.zip'

        f.save(os.path.join('uploads/', new_file_name))
        path = 'uploads/' + new_file_name
        return '', 200

The solution I ended up using was a bit of an old one but it works very well. I redirect the form to an invisible iframe by adding a button to the form:

<input type="button" id="double-analysis-button" value='Correlate' style='width:250px' onclick="redirect('double-analysis-form', 'double-analysis-iframe', 'graph-loading', 'graph-display')">
                    <iframe class="uploader" id="double-analysis-iframe" name="double-analysis-iframe" src="" frameborder="0"></iframe>

and the javascript function:

function redirect(elemid, tgt, sh1, sh2){
        document.getElementById(elemid).target = tgt;
        document.getElementById(elemid).submit();

        var callFunction;
        callFunction = show_and_hide(sh1, sh2);
    }

The show_and_hide function is what I use to fade one div out and another div in.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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