所以,我正在设计一个html表单,它有两个输入字段。
html模板代码:
<form role="form" action="/cities/" method="get" autocomplete="on">
<label for="#input1"><strong>Country:</strong></label>
<input id="#input1" type="text" name="country">
<label for="#input2"><strong>State:</strong></label>
<input id="#input2" type="text" name="state">
<input type="submit" value="Go!">
</form>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/jquery-ui.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
url: '/autocomplete',
type: 'GET',
}
}).done(function (data) {
$('#input1').autocomplete({
source: data,
minLength: 2,
});
});
}
</script>
Flask应用程序具有以下路径:
@app.route('/autocomplete/', methods=['GET'])
def autocomplete():
country = request.args.get('country')
state = request.args.get('state')
if country:
results = countries_to_states(country)
elif state:
results = state_to_countries(state)
return json.dumps(results)
这样做的目的是:
如果用户输入部分国家/地区名称,请在#input1字段中自动填充国家/地区名称。用户从自动填充中选择国家/地区后,会使用此国家/地区数据过滤并返回自动填充#input2的可能状态值。 类似地,反之亦然,当用户首先将数据输入#input2字段时。
路由代码有点不完整,但假设过滤在那里发生了很好。 我坚持的是使用这个工作所需的ajax,js代码。 很多代码都是从其他SO答案中粘合在一起的,但它主要是因为我是JS的新手。
有什么想法吗?谢谢!
答案 0 :(得分:1)
问题是Flask的默认内容类型是text/html
- 并且jQuery会嗅探返回数据的内容类型(如果我没记错的话)来弄清楚如果你处理它的方法不要指定从服务器获取的数据类型。这意味着您的JSON数据将作为字符串传递给autocomplete
,而不是JavaScript对象。
Python方面的修复是使用jsonify
来传回数据 - 这将导致返回正确的application/json
Content-Type
标头。由于jsonify
不支持顶级数组,因此您需要将数据传回对象:
return jsonify(data=results)
在JavaScript方面,您将需要使用the function version of the source
option来提取数据并将其移交给jQuery UI:
function handleAutoComplete(request, resultCallback) {
// Explicitly tell jQuery we expect JSON back
$.getJSON("/autocomplete?country=" + encodeURIComponent(request.term))
// Handle successful responses *and* failures
// to ensure the widget maintains the correct state
.then(function(result) { resultCallback(result.data); })
.fail(function(err) { resultCallback(); });
}
$('#input1').autocomplete({
source: handleAutoComplete,
minLength: 2
});