我在捕捉级联下拉的第二个下拉中的更改时遇到了一些麻烦。基本上我的设置是这样的:用户首先从第一个下拉菜单中选择一个ETF。在选择ETF时,更改函数检测选择,使用AJAX将其发送给Python,并根据ETF中的持有量填充第二个下拉列表(级联)。这部分工作完美。对于第二个下拉,我希望用户选择一个视觉,然后选择将被发送到Python,然后一个图形将产生。我还没有达到这一点,但我正试图只是闪烁一个消息,让我知道它正在工作,但由于某种原因,第二个更改功能不工作。
下面是HTML:
<body> id="body" name="body">
<div class="container">
<h1 align="center">Welcome to the Alpaca Pair Trading Application! </h1>
<div class="row">
<div class="col-md-6">
<label>Select ETF</label>
<select name="etfs" data-live-search="true" id="etfs" class="form-control" class="selectpicker" title="Select ETF">
{% for etf in etfs %}
<option value="{{etf}}">{{etf}}</option>
{% endfor %}
</select>
</div>
<div class="col-md-6">
<label>Select Visual</label>
<select name="visuals" data-live-search="true" id="visuals" class="form-control" class="selectpicker" title="Select Visual"> </select>
</div>
</div>
</div>
<br>
{% for message in get_flashed_messages() %}
<p> {{ message }} </p>
{% endfor %}
<br>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/js/bootstrap-select.min.js">
</script>
</body>
<script type="text/javascript">
$("#etfs").change(function() {
$.ajax({
type: "POST",
url: "{{ url_for('visuals') }}",
data: {
etf: $("#etfs").val()
},
success: function(data) {
var html = "";
for (var count = 0; count < data.length; count++) {
html += '<option value="' + data[count].id + '">' + data[count].visual + "</option>";
}
$("#visuals").html(html);
}
});
});
</script>
<script type="text/javascript">
$(document).on("change", "$visuals", function() {
$.ajax({
type: "POST",
url: "{{ url_for('graphs') }}",
data: {
visual: $("#visuals").val()
},
success: function(data) {
var html = "";
}
}
});
</script>
下面是python代码:
app=Flask(__name__)
@app.route("/")
def index():
etfs=['DIA','XLV','XLU','XLE','VNQ','GLD/SLV','QQQ','XLP','XLF']
return render_template("index.html", etfs=etfs)
@app.route("/visuals", methods=["POST","GET"])
def visuals():
etf_dict={'DIA':['UNH','GS','HD','MSFT','CRM'],'XLP':['PG','KO','PEP','WMT','COST'],
'XLV':['JNJ','UNH','PFE','ABT','ABBV'],'XLF':['BRK.B','JPM','BAC','WFC','C'],
'XLU':['NEE','DUK','SO','D','EXC'],'VNQ':['AMT','PLD','CCI','EQIX'],
'QQQ':['AAPL','MSFT','AMZN','GOOG','FB'],'XLE':['XOM','CVX','COP','MPC','SLB'],
'GLD/SLV':['GLD','SLV']}
if request.method == 'POST':
etf = request.form['etf']
holdings=etf_dict[etf]
options_list=[]
if etf=='GLD/SLV':
options_dict={}
options_dict['id']=etf
options_dict['visual']='GLD vs SLV'
options_list.append(options_dict)
else:
for i in holdings:
options_dict={}
options_dict['id']=etf
options_dict['visual']=i+' vs '+etf
options_list.append(options_dict)
options_list.append({'id':etf,
'visual': 'All Holdings vs ' +etf})
return jsonify(options_list)
@app.route("/graphs", methods=["POST","GET"])
def graphs():
print("inside graphs function")
if request.method == 'POST':
print("received post request from front end")
graph = request.form['visual']
flash("This worked! The graph chosen is" + graph)
return render_template("index.html")
if __name__ == "__main__":
app.run(debug=True)
这是web应用程序屏幕的样子。正如您所看到的,当我选择"XLE"时,它正确地更新了第二个下拉菜单,因此我知道更改功能对第一个下拉菜单工作正常。
Web App下拉列表
问题是当我在第二个下拉菜单中选择一个视觉效果时,另一个更改功能似乎没有运行..
我发现我应该使用一个表单标签来提交来自每个下拉列表的数据,而不是试图检测第二个下拉列表的变化。
这是更新后的HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Alpaca Pair Trading App</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/css/bootstrap-select.min.css">
<link rel="stylesheet" href={{url_for( 'static',filename='css/main.css' )}}>
</script>
</head>
<body>
<form action='/graphs' method='POST'>
<div class="container">
<h1 align="center">Welcome to the Alpaca Pair Trading Application! </h1>
<div class="row">
<div class="col-md-6">
<label>Select ETF</label>
<select name="etfs" data-live-search="true" id="etfs" class="form-control" class="selectpicker" title="Select ETF">
{% for etf in etfs %}
<option value="{{etf}}">{{etf}}</option>
{% endfor %}
</select>
</div>
<div class="col-md-6">
<label>Select Visual</label>
<select name="visuals" data-live-search="true" id="visuals" class="form-control" class="selectpicker" title="Select Visual"> </select>
</div>
</div>
</div>
<br>
<div class="container">
<div class="row">
<div class="col-md-4">
<input type="submit" name="next" value="Go" class="btn btn-primary">
</div>
</div>
</div>
</form>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/js/bootstrap-select.min.js">
</script>
<script type="text/javascript">
$("#etfs").change(function() {
$.ajax({
type: "POST",
url: "{{ url_for('visuals') }}",
data: {
etf: $("#etfs").val()
},
success: function(data) {
var html = "";
for (var count = 0; count < data.length; count++) {
html += '<option value="' + data[count].visual + '">' + data[count].visual + "</option>";
}
$("#visuals").html(html);
}
});
});
</script>
</body>
</html>