0

I would like to use flask in order to manipulate the values of properties of my HTML elements.

E.g. having the following HTML:

<html>
    <body>
        <progress id="result_bar" name="result_bar" max="100" value="50"> </progress>
    </body>
</html>

I would like to set the progress property "value" to 100 (i.e.100%).

Can someone help?

THX Lazloo

Lazloo Xp
  • 858
  • 1
  • 11
  • 36

2 Answers2

0

With Flask, directly not.
Flask is a light library to create web applications, not really good as a rich html parser.

But you can use Beautifulsoup to parse requests inside your Flask application.

Having your html, the following code does what you want.

from bs4 import BeautifulSoup

html = '<html><body><progress id="result_bar" name="result_bar" max="100" value="50"></progress></body></html>'

soup = BeautifulSoup(html, 'html.parser')
p = soup.find("progress")
p.attrs['value'] = "90"

print(p)
Evhz
  • 8,852
  • 9
  • 51
  • 69
0

You can make a view in Flask, then GET / POST to it from the frontend to retrieve or change the progress value. Here's a minimal example.

The first route is the root page which renders a template showing the progress bar itself and also a way to update the value. [Of course you could make the edit part a separate page, do a POST programmatically from JavaScript, etc.]

The second route is the /progress endpoint which has a view that can either retrieve or set values for progress and max. This view then stores the value in Flask's Sessions storage which uses a cookie on the client side.

app.py:

from flask import Flask, render_template, request, session

app = Flask(__name__)
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'  # (use random bytes)

def get_progress():
    DEFAULT_PROGRESS_VALUE = 0
    DEFAULT_PROGRESS_MAX = 100
    return {
        "value": session.get("progress_value", DEFAULT_PROGRESS_VALUE),
        "max": session.get("progress_max", DEFAULT_PROGRESS_MAX),
    }

def set_progress_value(val):
    if val is not None:
        session["progress_value"] = int(val)

def set_progress_max(val):
    if val is not None:
        session["progress_max"] = int(val)

@app.route("/")
def root():
    return render_template("index.html", **get_progress())

@app.route("/progress", methods=["GET", "POST"])
def progress():
    if request.method == "POST":
        set_progress_value(request.form.get("value"))
        set_progress_max(request.form.get("max"))
    return get_progress()

templates/index.html:

<!doctype html>
<html>
<body>

  <label for="result_bar">Progress:</label>
  <progress id="result_bar" max="{{ max }}" value="{{ value }}"></progress>

  <hr>

  <p>Update progress:</p>
  <form action="/progress" method="post">
    <input type="number" name="value" value="{{ value }}">
    <input type="number" name="max" value="{{ max }}">
    <input type="submit" value="Update">
  </form>

</body>
</html>

To run it:

flask run

You can then change the progress values using the form and reload / to see the change.

For more info, the Flask Quickstart is a good reference on the components used in this example.

Taylor D. Edmiston
  • 12,088
  • 6
  • 56
  • 76
  • It sees to work when I change the return of the progress function to: return render_template("index.html", **get_progress()). Otherwise, it displays the JSON, not the web page. However, using this workaround I change the URL to .../progress – Lazloo Xp Apr 17 '20 at 14:25
  • So I made /progress an API endpoint intentionally supporting both set (POST) and retrieve (GET). You are seeing the JSON value of the GET as expected. On the root page I render these values into the template. If you wanted to stay on the homepage (/), you could do an AJAX post to /progress and then reload the homepage client side. – Taylor D. Edmiston Apr 18 '20 at 14:48
  • Do you have a reference how to make a Ajax Post? Or is your Suggestion already a Ajax Post? – Lazloo Xp Apr 18 '20 at 15:59
  • Here's an example with jQuery - https://api.jquery.com/jQuery.post/ – Taylor D. Edmiston Apr 19 '20 at 13:57