Bob
Bob

Reputation: 37

How can I pass a value from a drop down list to another page in flask

I want to have a page where an option is selected from a drop down list that is passed to the next page. The error I receive is "UnboundLocalError: local variable 'currentuser' referenced before assignment". I'm not sure how to update the variable globally when an option is selected from the drop down list or how to access the global variable locally in the next page function. I am new to python and flask, any help would be greatly appreciated!

app.py

from flask import Flask, render_template
import sqlite3
app = Flask(__name__) 

@app.route('/selectusername')
def selectusername_page():
    # connect to database and populate userlist
    conn = sqlite3.connect('users.db')
    c = conn.cursor()
    c.execute("SELECT * FROM users")
    userlist = c.fetchall()
    conn.close()
    return render_template('selectusername.html', userlist=userlist)

@app.route('/showusername')
def showusername_page():
    currentuser=currentuser
    return render_template('showusername.html', currentuser=currentuser)

if __name__ == '__main__':
    app.run(debug=True)

selectusername.html

<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<body>
    <button onclick="window.location.href = 'showusername';">Continue</button>
        <h1>Select User</h1>
<select id="currentuser">
{% for user in userlist %}
  <option value="{{user[0]}}">{{user[0]}}</option>
{% endfor %}
</select>
</body>
</html>

showusername.html

<h1>Hello {{ currentuser }}</h1>

Upvotes: 1

Views: 3805

Answers (1)

furas
furas

Reputation: 142879

If you use

<form action="/showusername"> 

and button without JavaScript and you use name="currentuser" in <select>

<select name="currentuser">

then it can send selected value in url

/showusername?currentuser=selected_name

and you can get it in showusername using request.args

currentuser = request.args.get("currentuser")

To hide name from url you would have to use POST method - so you have to set

<form action="/showusername" method="POST"> 

and in flask

@app.route('/showusername', methods=['POST', 'GET'])

and then you get it using request.form instead of request.args

currentuser = request.form.get("currentuser")

Full running example

from flask import Flask, render_template, render_template_string, request

app = Flask(__name__) 

@app.route('/selectusername')
def selectusername_page():

    userlist = [['James'], ['Adam'], ['Mark']]

    return render_template_string('''<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<body>
<form action="/showusername">
    <button>Continue</button>
        <h1>Select User</h1>
<select id="currentuser" name="currentuser">
{% for user in userlist %}
  <option value="{{user[0]}}">{{user[0]}}</option>
{% endfor %}
</select>
</form>
</body>
</html>''', userlist=userlist)

@app.route('/showusername', methods=['POST', 'GET'])
def showusername_page():
    print('args:', request.args)
    print('form:', request.form)

    #currentuser = request.args.get("currentuser")
    currentuser = request.form.get("currentuser")

    return render_template_string('''<h1>Hello {{ currentuser }}</h1>''', currentuser=currentuser)

if __name__ == '__main__':
    app.run(debug=True)

If you want to use JavaScript in button then you would have to use JavaScript to get selected value and add it to url like

 window.location.href = 'showusername?currentuser=selected_name'

so it is more complicated and I don't put code in JavaScript. Maybe someone else will show this.

Upvotes: 2

Related Questions