[英]How do I implement dynamic dependent change of dropdown select options, using Python, Flask and SQLite3?
Good day.再会。 I'm really new to programming (3 month's), and i'm trying to add last feature for my course final project.我真的是编程新手(3 个月),我正在尝试为我的课程期末项目添加最后一个功能。 In my html page, i have 5 select containers, first container has data from tuple object in my app.py, and rest 4 options data is coming fom sqlite3 database query. In my html page, i have 5 select containers, first container has data from tuple object in my app.py, and rest 4 options data is coming fom sqlite3 database query. I want this options to be dependent of each other, no matter what option will be selected first by user.我希望这些选项相互依赖,无论用户首先选择哪个选项。 To give you more of an idea what I am talking about, all options are tied to weapon type (this is a web-app for managing inventory for an online game), this "type" column is present in each table used in query, and represented as "1" for ranged weapons, "2" for melee weapons and "0" for both types.为了让您更了解我在说什么,所有选项都与武器类型相关联(这是一个用于管理在线游戏库存的网络应用程序),此“类型”列存在于查询中使用的每个表中,远程武器用“1”表示,近战武器用“2”表示,两种类型都用“0”表示。 So how I understand it, I need to make a json request after one option is being selected, and return it with new query result back to html in order to process new data with javascript?那么我如何理解它,我需要在选择一个选项后发出 json 请求,并将其与新查询结果一起返回给 html 以便使用 javascript 处理新数据? But what next, when new option will be selected and reduce variants... i'm totally lost here, since my javascript experience is only with bootstrap (copy/paste)... I hope I explained everything clearly, and would really appreciate some example how to do it. But what next, when new option will be selected and reduce variants... i'm totally lost here, since my javascript experience is only with bootstrap (copy/paste)... I hope I explained everything clearly, and would really appreciate一些例子如何做到这一点。 Thank you for your time.感谢您的时间。
My python code:我的 python 代码:
@app.route("/add", methods=["GET", "POST"])
@login_required
def add():
# assigning user_id to session
user_id = session["user_id"]
# this will be used for future dynamic change feature
weapon_type = ("-1", "1")
if request.method == "POST":
# assigning user's input
wtype = request.form.get("wtype")
wname = request.form.get("wname")
main_p = request.form.get("main_p")
major_p = request.form.get("major_p")
minor_p = request.form.get("minor_p")
# check if input fields are blank or not valid
if not wtype or wtype not in weapon_type:
return apology("Invalid type")
if not wname:
return apology("Invalid type")
if not main_p:
return apology("Invalid type")
# adding new weapon into users_weapons table
db.execute("INSERT INTO user_weapons (user_id, weapon_id, main_id, major_id, minor_id) VALUES(?, ?, ?, ?, ?)", user_id, wname, main_p, major_p, minor_p)
return redirect("/inventory")
else:
# adding options for select forms
weapons = db.execute("SELECT id, name FROM weapons")
mains = db.execute("SELECT id, name FROM mainp")
majors = db.execute("SELECT id, description FROM majorp")
minors = db.execute("SELECT id, description FROM minorp")
return render_template("add.html", weapons=weapons, mains=mains, majors=majors, minors=minors)
My html code:我的 html 代码:
{% block main %}
<form action="/add" method="post">
<div class="form-group">
<select class="form-control col-md-4 bg-dark text-success" name="wtype">
<option disabled selected>Weapon Type</option>
<option value="-1">Melee</option>
<option value="1">Ranged</option>
</select>
<br>
<br>
<select class="form-control col-md-4 bg-dark text-success" name="wname">
<option disabled selected>Weapon Name</option>
{% for weapon in weapons %}
<option value="{{ weapon["id"] }}"> {{ weapon["name"] }} </option>
{% endfor %}
</select>
<br>
<br>
<select class="form-control col-md-4 bg-dark text-success" name="main_p">
<option disabled selected>Main Prefix *</option>
{% for main in mains %}
<option value="{{ main["id"] }}"> {{ main["name"] }} </option>
{% endfor %}
</select>
<br>
<br>
<select class="form-control col-md-4 bg-dark text-success" name="major_p">
<option disabled selected>Major Prefix **</option>
{% for major in majors %}
<option value="{{ major["id"] }}"> {{ major["description"] }} </option>
{% endfor %}
</select>
<br>
<br>
<select class="form-control col-md-4 bg-dark text-success" name="minor_p">
<option disabled selected>Minor Prefix ***</option>
{% for minor in minors %}
<option value="{{ minor["id"] }}"> {{ minor["description"] }} </option>
{% endfor %}
</select>
</div>
<br>
<button class="btn btn-outline-dark btn-lg" type="submit">Add Item</button>
</form>
{% endblock %}
So with help of my friend (shout out to Scraelos: :) , we were able to solve this problem using Jsonify feature of Flask, and Jquery.所以在我朋友的帮助下(向 Scraelos 大喊::) ,我们能够使用 Flask 和 Jquery 的 Jsonify 功能解决这个问题。 It's a little bit different approach than I wanted to implement at first, but it suites general purpose of my web-app better.这与我最初想要实现的方法有点不同,但它更适合我的网络应用程序的一般用途。
(by doing this, i was able to remove the need to populate select options through GET method of "/add" route) (通过这样做,我能够消除通过“/add”路由的 GET 方法填充 select 选项的需要)
python code: python 代码:
@app.route("/options")
@login_required
def options():
wtype = request.args.get('wtype')
weapons = db.execute("SELECT id, name FROM weapons WHERE type = ?", wtype)
mains = db.execute("SELECT id, name FROM mainp WHERE type = ? OR type = 0", wtype)
majors = db.execute("SELECT id, description FROM majorp WHERE type = ? OR type = 0", wtype)
minors = db.execute("SELECT id, description FROM minorp WHERE type = ? OR type = 0", wtype)
return jsonify(weapons=weapons, mains=mains, majors=majors, minors=minors)
javascript code: javascript 代码:
$(document).ready(function() {
// first we hide opions 2-5 and button
$('#wname').hide();
$('#main_p').hide();
$('#major_p').hide();
$('#minor_p').hide();
$('#submitbtn').hide();
// when 1st available option is changed, we get JSON from "/options"
$('#wtype').change(function(){
$.getJSON('/options', {
wtype: $('#wtype').val()
// if request successful process data
}).done(function(data) {
// remeber selected options for later use
mainp=$('#main_p').val();
majorp=$('#major_p').val();
minorp=$('#minor_p').val();
// empty options for now...
$('#wname').empty();
$('#main_p').empty();
$('#major_p').empty();
$('#minor_p').empty();
// appending placeholder options
$('#wname').append($('<option disabled selected>Weapon Name</option>'));
$('#main_p').append($('<option disabled selected>Main Prefix ☆</option>'));
$('#major_p').append($('<option disabled selected>Major Prefix ☆☆</option>'));
$('#minor_p').append($('<option disabled selected>Minor Prefix ☆☆☆</option>'));
// appending real options available for chosen type trough itteration
$.each(data.weapons, function(key, val) {
$('#wname').append($('<option>').text(val.name).attr('value', val.id));
});
$.each(data.mains, function(key, val) {
$('#main_p').append($('<option>').text(val.name).attr('value', val.id));
});
$.each(data.majors, function(key, val) {
$('#major_p').append($('<option>').text(val.description).attr('value', val.id));
});
$.each(data.minors, function(key, val) {
$('#minor_p').append($('<option>').text(val.description).attr('value', val.id));
});
// after all new options were added to selection, this "if" condition checks if previously saved option is in new options list
if ($("#main_p option[value="+mainp+"]").length > 0){
// if true, select this option
$('#main_p').val(mainp).change();
}
if ($("#major_p option[value="+majorp+"]").length > 0){
$('#major_p').val(majorp).change();
}
if ($("#minor_p option[value="+minorp+"]").length > 0){
$('#minor_p').val(minorp).change();
}
// make select options and button fadeIn from "hide"
$('#wname').fadeIn();
$('#main_p').fadeIn();
$('#major_p').fadeIn();
$('#minor_p').fadeIn();
$('#submitbtn').fadeIn();
})
});
});
and HTML after all lookes like this:和 HTML 毕竟看起来像这样:
{% extends "layout.html" %}
{% block title %}
Add
{% endblock %}
{% block main %}
<form action="/add" method="post">
<div class="form-group">
<select class="form-control col-md-4 bg-dark text-success" name="wtype" id="wtype">
<option disabled selected>Weapon Type</option>
<option value="-1">Melee</option>
<option value="1">Ranged</option>
</select>
<br>
<br>
<select class="form-control col-md-4 bg-dark text-success" name="wname" id="wname">
<!-- I was able to remove below syntax, by performing table select population through Jquery code in fetch.js
<option disabled selected>Weapon Name</option>
{% for weapon in weapons %}
<option value="{{ weapon["id"] }}"> {{ weapon["name"] }} </option>
{% endfor %}
-->
</select>
<br>
<br>
<select class="form-control col-md-4 bg-dark text-success" name="main_p" id="main_p"></select>
<br>
<br>
<select class="form-control col-md-4 bg-dark text-success" name="major_p" id="major_p"></select>
<br>
<br>
<select class="form-control col-md-4 bg-dark text-success" name="minor_p" id="minor_p"></select>
</div>
<br>
<button class="btn btn-outline-dark btn-lg" type="submit" id="submitbtn">Add Item</button>
</form>
<script src="/static/fetch.js"></script>
{% endblock %}
Maybe someone will find this solution useful.也许有人会发现这个解决方案很有用。 Peace: :)和平: :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.