This is a Flask question.
I have a dropdown and a button. I wish to press the button and send the current value of the dropdown back to a python function. This python function will do some stuff and determine the further contents of the page.
If I redirect to a new page, I don't need to use any ajax and the selected value is being passed back to the python function fine.
If I don't redirect but instead try to render the selected value on the same page (this is my requirement), as far as I can tell from other posts on this site I have to use Ajax to call the python function, but it's not capturing the selected value.
Please also note the restriction that the page shouldn't rerender.
I'm really at a loss here as I don't understand the difference between the two situations. Any help would be much appreciated. I have decent experience with python but Flask and html are very much new to me.
See code below:
setup.py:
from app import app
# Data for initialisation of setup page
@app.route("/setup", methods=["GET", "POST"])
def create_models_dropdown():
# Gets used to create the dropdown
model_ids = list(range(1, 11))
return render_template ("setup.html", ids=model_ids)
# Further data to be added on button click
@app.route('/test', methods=["GET", "POST"])
def test():
###
# Debugging
print(request.form)
# When redirecting to a new page, this gives ImmutableMultiDict([('id_options', '5')]) (or whatever value is selected)
# So the data is being returned
# When staying on the same page (using the ajax script), this gives ImmutableMultiDict([]) so the dropdown value is not being returned
###
model_id = request.form.get("id_options") # succeeds/fails as per comments above
# Do something with the model_id
return jsonify(result=(model_id or -1) * 2)
setup.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charset="UTF-8" />
<title>Wut</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
integrity="sha384-1q8mTJOASx8j1Au a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous" />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js">
var $SCRIPT_ROOT = "";
</script>
</head>
<body>
<!--
action="{{ url_for('test') }}" will render the new page and work as expected
if i take it out, the result of running the script below will instead render
-->
<form action="{{ url_for('test') }}" method="post">
<select name="id_options" width="300px">
{% for id in ids %}
<option value="{{ id }}" SELECTED>{{ id }}</option>
{% endfor %}
</select>
<button class="get_result" type="button">Same page</button>
<button class="get_result">New page</button>
</form>
<div class="result"></div>
</body>
<script>
// This works in the sense that it calls the function
$(document).on('click', '.get_result', function () {
// Debugging
// This was another attempt to get the value from the dropdown and pass it back which also didn't work
// var model_id = $("#id_options").val();
// console.log(model_id)
//
$.ajax({
url: "/test",
type: "get",
// data: { model_id: model_id },
success: function (response) {
$(".result").html('<h1>' response.result.toString() '</h1>');
},
});
});
</script>
</html>
CodePudding user response:
Your select doesn't have an id only a name. So your jquery which is using
id
i.e.#
is incorrect. Addid="id_options"
to yourselect
element.To get the selected value,
model_id = document.getElementById("id_options").value;
or
model_id = $("#id_options").find("option:selected").val();
- In your Ajax code, you are not submitting a form which means you can't use
request.form
. Instead tryrequest.values.get("model_id", None)