I built a flask app that is supposed to show a dataframe after it goes through a filter. For that, I have created a form using Flask-WTF to ask for a specific filter, and then apply it. I need to make the dataframe result appear when the form is submitted. So I have set the visibility of the dataframe result as hidden and have added an event onclick {{ form.submit(onclick="showResult()") }}. But when I click on the submit button, the result briefly appears and then disappears when the form is done loading. Here is the code:
server.py
def get_df():
df = pd.DataFrame({'A': [0, 1, 2, 3, 4],
'B': [5, 6, 7, 8, 9],
'C': ['a', 'b', 'c', 'd', 'e']})
return df
@app.route('/', methods=("POST", "GET"))
def index():
df_result = get_df()
form = NameForm()
message = ""
if form.validate_on_submit():
name = form.name.data
df_result = df_result.loc[df_result['C']==name]
message = 'your input is ' + name
return render_template('index.html', tables=[df_result.to_html(classes='data', header="true")], form=form, message=message)
index.html
{% extends 'layout.html' %}
{% block content %}
<form method=post>
{{ form.csrf_token }}
{{ form.name }}
{{ form.submit(onclick="showResult()") }}
</form>
<p class="pt-5"><strong>{{ message }}</strong></p>
<div id="result" style="visibility:hidden;">
{% for table in tables %}
{{ table|safe }}
{% endfor %}
</div>
{% endblock %}
javascript.js
function showResult()
{
document.getElementById('result').style.visibility = 'visible'
}
Could you please help figure out why the visibility style on the javascript does not persist?
Your form doesn't have an action attribute so not sure where your form is being submitted for processing.
A form submit reloads the page. What your current code is doing is to first make the dataframe visible, then submit the form which forces the page to reload and so your dataframe is back to being invisible.
The solution is to make an asynchronous call to submit your form i.e when user clicks to submit your form, intercept the submit action and block the default submit, then using your asynchronous code submit the form, process the returned result, then make the dataframe visible. Sample code you can build on
function showResult(e){
// Stop the default form submission
e.preventdefault()
// Make a POST request to your server sending the form
fetch("/",{ method: "POST", body: new FormData(document.querySelector('form')})
.then(function(result) { // This is the response from the server
return result.json();
})
.then(function(data){
// Process the returned data
......
// Make your frame visible
document.getElementById('result').style.visibility = 'visible'
})
}