1

I have an HTML form which makes a POST request to my flask app and the flask app returns a string. I want to display the string on the same HTML page.

index.html

<iframe name="frame" class="hidden"></iframe>
<form action="/upload" target="frame" method="POST">
    <input type="text" name="text" />
    <button type="submit">Submit</button>
</form>
<p id="text"></p>

Note: The hidden <iframe> is kept as the target so that the page doesn't redirect.

app.py

from flask import Flask, request, render_template

app = Flask(__name__)

@app.route('/')
def my_form():
    return render_template('index.html')

@app.route('/upload', methods=['POST'])
def my_form_post():
    text = request.form['text']
    processed_text = text.upper()
    # Some internal stuff with processed text
    return processed_text

I want to display processed_text in the <p id="text"></p>

I am new to flask. How do I do that?

1 Answer 1

3

You might want to learn how HTML reads variables using jinja2. The code you're looking for should be. I also added an if example so you can check the syntax for that too:

index.html

<iframe name="frame" class="hidden"></iframe>
<form action="/upload" target="frame" method="POST">
    <input type="text" name="text" />
    <button type="submit">Submit</button>
</form>
{% if processed_text %}
<p id="text">{{ processed_text }}</p>
{% endif %}

That way, what's inside {{ }} will be looking for a variable. However, that alone is not enough. When you return from a route you can use the same template for different routes, so rendering the same template in upload and passing it the processed_text variable will make your page display the text properly. Note that you shouldn't be using variables in your templates if you don't pass them a value from your app or you might get errors. In this case, since the line containing <p id="text">{{ processed_text }}</p> won't even load unless that variable is defined you shouldn't have a problem, but keep that in mind.

app.py

from flask import Flask, request, render_template

app = Flask(__name__)

@app.route('/')
def my_form():
    return render_template('index.html')

@app.route('/upload', methods=['POST'])
def my_form_post():
    text = request.form['text']
    processed_text = text.upper()
    # Some internal stuff with processed text
    return render_template('index.html', processed_text=processed_text)

EDIT: As mentioned in the comments and something I didn't notice when answering was, when you target the iframe in your form you're not stopping the page to reload but rather having it load again inside the frame. Flask's routes aren't the best way to deal with this problem, so you can just remove your upload route and do the text uploading entirely from your HTML file by modifying it like this. I also took out the frame since it was no longer necessary:

<head>
    <script>
    document.addEventListener('DOMContentLoaded', () => {
        document.querySelector('#upload').onsubmit = () => {
            const text = document.querySelector('#input').value;
            document.querySelector('#text').innerHTML = text.toUpperCase(text);
            return false;
        };
    });
    </script>
</head>
<body>
    <form id="upload">
        <input type=text id="input">
        <button type="submit">Submit</button>
    </form>
    <p id="text"></p>
</body>
Sign up to request clarification or add additional context in comments.

5 Comments

This doesn't work, because the index.html is rendered at /upload and i want the processed_text to appear in the same / endpoint without any reload. Is that possible?
If you want it to appear without the page reloading, then what you want is to learn how to use sockets and you'll need to do that in a JavaScript file rather than your app.py.
i made some changes and did return render_template('index.html', processed_text=processed_text) on the / endpoint. but still the processed_text doesn't appear even after reloading.
Just reproduced the code. It does appear but the whole page is loading inside of the frame rather than just the desired output. I'll have a look and edit the post if I solve this.
Thanks a lot. Please do so.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.