Flask’s form validation error handling in Javascript by omclick event

So, there is a file uploading form.

forms.py

from flask_wtf import FlaskForm 

class Form(FlaskForm):
    file = FileField('File',
                     validators=[FileRequired(msg),
                                 FileAllowed(ext, msg),
                                 FileSize(max_, min_, msg)])    
    upload = SubmitField('Upload')

upload.html

<form method="POST" enctype="multipart/form-data">
  {{ form.hidden_tag() }}
  {{ form.file(class="form-control", id="file") }}
  <div id="error" data-error="{{ form.file.errors[0] }}"></div> <!-- * -->
  {{ form.upload(class="btn btn-outline-secondary", id="upload") }}
</form>
  • Here I’m tryimg to store validatiom error text so that it could be reacheble from JS function.
    I need it, because I want to show error message in nice-looking Bootstrap toast element which recquires initialize in JS.
script.js

let fu = document.querySelector('#upload');

fu.addEventListener('click', (ev) => {
    let el = document.querySelector('#error');
    if (el.dataset.error) {
        // Show error message and do nothing else
        let toast = document.querySelector('.toast');
        document.querySelector('.toast-body').innerText = el.dataset.error;
        bootstrap.Toast.getOrCreateInstance(toast).show(); // initialize
    }
    // Let Flask do its job
});

Obviously, when I press upload button and JS function fires immediately. There is still no information about errors occured (if any), because validation on the server side hasn’t happened yet.

Also I tried to solve problem with websockets:

Python

@app.route('/upload', methods=['GET', 'POST'])
def upload():
    form = Form()

    if request.method == 'POST':
        if not form.validate():
            socketio.emit('err', {'error': form.file.errors[0]})
    # ...

JS

const ws = io();
ws.on('err', (ev) => (
    // let error = ev.error;
    // Yhe same logic
));

But recieved Invalid frame header error on the client side.

Finally I got what I wanted. With a lot of code and repeating AJAX-requests calls.
I’m sure there is much more elegant solutiom. Probably I miss something.
Thanks.