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-lookingBootstrap 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.