我是flask
和Javascript
的新手。我要做的就是创建一个带有动态下拉列表的表单,获取选定的值并将其放入数据库中。
现在,我处于创建动态下拉列表的第一阶段。
这是我的python代码的一部分。
class Form(FlaskForm):
site = SelectField('Site', choices=[(' ', ' '), ('International', 'International'), ('Domestic', 'Domestic')])
location = SelectField('Location', choices=[])
city = SelectField('City', choices=[])
street = SelectField('Street', choices=[])
sub_street = SelectField('BuildingStreet', choices=[])
floor = SelectField('Floor', choices=[])
room = SelectField('Room', choices=[])
side = SelectField('Side', choices=[])
@app.route('/')
def basic():
return render_template('basic.html')
@app.route('/Welcome', methods=['GET', 'POST'])
def index():
form = Form()
location_choice_list = [(locations.id, locations.location) for locations in
Hostname.query.filter_by(site='International').all()]
form.location.choices = remove_duplicates.unique_list(location_choice_list)
city_choice_list = [(cities.id, cities.city) for cities in Hostname.query.filter_by(site='International').all()]
form.city.choices = remove_duplicates.unique_list(city_choice_list)
street_choice_list = [(streets.id, streets.street) for streets in
Hostname.query.filter_by(site='International').all()]
form.street.choices = remove_duplicates.unique_list(street_choice_list)
sub_street_choice_list = [(sub_streets.id, sub_streets.sub_street) for sub_streets in
Hostname.query.filter_by(site='International').all()]
form.sub_street.choices = remove_duplicates.unique_list(sub_street_choice_list)
floor_choice_list = [(floors.id, floors.floor) for floors in
Hostname.query.filter_by(site='International').all()]
form.floor.choices = remove_duplicates.unique_list(floor_choice_list)
room_choice_list = [(rooms.id, rooms.room) for rooms in Hostname.query.filter_by(site='International').all()]
form.room.choices = remove_duplicates.unique_list(room_choice_list)
side_choice_list = [(sides.id, sides.side) for sides in Hostname.query.filter_by(site='International').all()]
form.side.choices = remove_duplicates.unique_list(side_choice_list)
return render_template('index.html', form=form)
@app.route('/location/<site>')
def location(site):
print(site)
choice_list = Hostname.query.filter_by(site=site).all()
locationObjp = {'id': '', 'location': ''}
c = [{'id': ' ', 'location': ' '}]
for location in choice_list:
locationObj = {}
locationObj['id'] = location.location
locationObj['location'] = location.location
if locationObj['location'] != locationObjp['location']:
c.append(locationObj)
locationObjp = locationObj
else:
locationObjp = locationObj
return jsonify({'Location_Choice_list': c})
@app.route('/city/<location>')
def city(location):
print(location)
choice_list = Hostname.query.filter_by(location=location).all()
cityObjp = {'id': '', 'city': ''}
c = [{'id': ' ', 'city': ' '}]
for city in choice_list:
cityObj = {}
cityObj['id'] = city.city
cityObj['city'] = city.city
if cityObj['city'] != cityObjp['city']:
c.append(cityObj)
cityObjp = cityObj
else:
cityObjp = cityObj
return jsonify({'City_Chocie_list': c})
因此,首先我创建了一个包含所有用户可以从表单中选择的下拉菜单的类。除站点外,所有其他选择最初都填充有与“国际”相对应的选项。即与“国际”相对应的所有位置,与“国际”相对应的所有城市,依此类推。我使用了一个作为模块放置的小函数来删除数据库中无法避免的重复条目。最初,显示该窗体时,一切都会按预期工作。我没有放置basic.html文件,因为它只包含指向“ / Welcome”的链接。另外,我用作模块的remove_duplicates函数也没有问题。
这是我的HTML代码的一部分。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</head>
<body>
<form method="POST">
{{ form.hidden_tag() }}
{{ form.site.label }} {{ form.site }}
{{ form.location.label }} {{ form.location }}
{{ form.city.label }} {{ form.city }}
{{ form.street.label }} {{ form.street }}
{{ form.sub_street.label }} {{ form.sub_street }}
{{ form.floor.label }} {{ form.floor }}
{{ form.room.label }} {{ form.room }}
{{ form.side.label }} {{ form.side }}
<input type="submit">
</form>
<script>
var site_select = document.getElementById("site");
var location_select = document.getElementById("location");
console.log(site_select);
console.log(location_select);
site_select.onchange = function() {
site = site_select.value;
console.log(site);
fetch('/location/' + site).then(function(response) {
response.json().then(function(data) {
var optionHTML = '';
for (var location of data.Location_Choice_list) {
optionHTML += '<option value="' + location.id + '">' + location.location + '</option>';
}
location_select.innerHTML = optionHTML;
})
})
}
var city_select = document.getElementById("city");
location_select.onchange = function() {
location = location_select.value;
alert(location);
fetch('/city/' + location).then(function(response) {
response.json().then(function(data) {
var optionHTML = '';
for (var city of data.City_Choice_list) {
optionHTML += '<option value="' + city.id + '">' + city.city + '</option>';
}
city_select.innerHTML = optionHTML;
})
})
}
</script>
</body>
</html>
这是问题所在。如我们所见,有两条路线“ / location /”和“ / city /”。这两条路线将返回属于特定站点的位置和属于特定位置的城市的json化版本。 javascript会对这些URL进行提取,然后使用jsonified输出中的条目形成下一个下拉列表的select语句。现在,这里的第一个从属下拉列表(位置)在选择“站点”时按预期进行了完美更改。我刚刚编写了获取特定位置城市的确切功能。从代码中可以看出,站点和位置的onchange值是通过select语句的常规(.value)属性获得的。对于网站,选择后我得到正确的值。但是对于位置,在选择之后,返回的值(我已经提醒过)为“ http://127.0.0.1:5000/Welcome”,因此javascript在获取时会使用此值,这显然会导致404错误。
所以我不确定为什么第一个功能可以正常工作而第二个功能却不能正常工作。我想知道将位置值捕获为URL而不是选定值的原因。因为它是作为URL返回的,所以我在位置0收到了可怕的“未捕获(承诺)意外令牌<。我还尝试打印出初始site_select和location_select值,它们也很不错,没有任何错误。
为此,我已经在网上调查了很多帖子,但到目前为止没有任何工作,而且已经有一个星期了,出现了这个可怕的错误。
非常感谢您的帮助。
答案 0 :(得分:0)
您的location
变量与window.location
变量冲突,后者使用当前文档的网址-https://developer.mozilla.org/en-US/docs/Web/API/Window/location
var list = [{"id":" ","location":" "}, {"id":"CN0","location":"CN0"},{"id":"India","location":"India"},{"id":"Japan","location":"Japan"},{"id":"Honkong","location":"Honkong"},{"id":"GB0","location":"GB0"}];
const countries = document.querySelector('#countries');
let optionHTML = "";
list.forEach((obj) => {
optionHTML += '<option value="' + obj.id + '">' + obj.location + '</option>';
});
countries.innerHTML = optionHTML;
countries.addEventListener('change', function() {
location = this.value;
// alert(location);
alert(window.location === location);
});
<select name="" id="countries"></select>
请改为使用location
以外的其他变量,或者使用block-scoped
或let
使用const
的变量,这些变量不会被吊起并且不会与全局变量冲突。
var list = [{"id":" ","location":" "}, {"id":"CN0","location":"CN0"},{"id":"India","location":"India"},{"id":"Japan","location":"Japan"},{"id":"Honkong","location":"Honkong"},{"id":"GB0","location":"GB0"}];
const countries = document.querySelector('#countries');
let optionHTML = "";
list.forEach((obj) => {
optionHTML += '<option value="' + obj.id + '">' + obj.location + '</option>';
});
countries.innerHTML = optionHTML;
countries.addEventListener('change', function() {
let location = this.value;
console.log(location);
});
<select name="" id="countries"></select>