Flask实现级联下拉菜单的完美方案

最近在做一个项目的时候有两个下拉框,需要先选择\color{red}{歌手}再选择\color{red}{歌曲},有一个级联的关系,就想填地区的时候先省份再城市一样,实现的效果如下图所示

级联菜单效果图

为了实现这个目的,我们需要用到Ajax
贴一点菜鸟教程上面的Ajax的介绍

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

如果单独写Ajax是比较繁琐的,可以自行百度,好在JQuery库中已经集成了Ajax的库函数,JQuery对Ajax的封装介绍

jQuery 提供多个与 AJAX 有关的方法。

  • 通过 jQuery AJAX 方法,您能够使用 HTTP Get 和 HTTP Post 从远程服务器上请求文本、HTML、XML 或 JSON - 同时您能够把这些外部数据直接载入网页的被选元素中。
  • 提示:如果没有 jQuery,AJAX 编程还是有些难度的。
  • 编写常规的 AJAX 代码并不容易,因为不同的浏览器对 AJAX 的实现并不相同。这意味着您必须编写额外的代码对浏览器进行测试。不过,jQuery 团队为我们解决了这个难题,我们只需要一行简单的代码,就可以实现 AJAX 功能。

下面我们开始编写函数处理

为了实现这个效果,流程有几个步骤:

  1. 编写好第一个下拉菜单(我这里第一个下拉菜单也是从后台获取的),和第二个菜单的空表
  2. 使用HTML 事件属性中的onchange监测到点击了第一个下拉菜单,转到处理函数
  3. 处理函数使用Ajax发送HTTP请求,向后端请求数据
  4. 使用JavaScript清空下一个列表的选项,并重写
1. 首先写第一个下拉菜单和第二个空的下拉惨淡:

第一个下拉菜单前端代码如下

<div >
    <form>
        <label>请选择一位音乐人:</label>
        <select name="singer_selection" id="singer_selection"
                onchange="changefield('singer_selection',song_selection,'/changeselectfield/')">
            {% for singer_name in singer_name_list %}
                <option value="{{ singer_name }}"> {{ singer_name }} </option>
            {% endfor %}
        </select>
    </form>
</div>

注意这一句

<select name="singer_selection" id="singer_selection"
                onchange="changefield('singer_selection',song_selection,'/changeselectfield/')">

changefield()函数我们下面编写,这个的意思就是如果监测到有变动,那么就触发这个函数
<option value="{{ singer_name }}"> {{ singer_name }} </option>这个option的内容也是从后端获取的,这个语法大家可以自行百度,如果不需要这样可以直接写死。

效果如下


音乐人候选框

下面我们写第二个选择框,不过这个选择框是空的

<div class="am-u-lg-3 am-u-md-3 am-u-sm-3 am-u-sm-offset-3">
    <form class="am-form">
        <label for="zhekou"> 请选择歌曲</label>
        <select name="song_selection" id="song_selection">
             {# 这里空着 等待获取后端返回的数据再写 #}
        </select>
        <br>
    </form>
</div>
2. 编写触发函数
<script>
    function changefield(choose, id, url) {
        var data;
        var select = document.getElementById(choose);
        $(id).html(""); //每次重新选择当前列表框,就清空下一级列表框。
        for (i = 0; i < select.length; i++) {
            if (select[i].selected) { //判断被选中项
                Name = select[i].text;
                data = {
                    "name": Name
                };
                $.post({ //发起ajax请求
                    url: url,
                    type: "POST",
                    data: JSON.stringify(data),
                    {#dataType:'json'#}
                    contentType: "application/json; charset=UTF-8",
                    success: function (data) {
                        {#console.log(data.length);#}
                        if (data) {
                            $("<option selected='selected' disabled='disabled'  style='display: none' value=''></option> ").appendTo(id);
                            for (i = 0; i < data.length; i++) {
                                $("<option value='" + data[i] + "'>" + data[i] + "</option>").appendTo(id);
                            }
                        } else {
                            alert('error')
                        }
                    }
                });
            }
        }
    }
</script>

函数三个参数

  • choose是第一个选择框的ID
  • id是第二个需要更改的选择框的id
  • url是前端的处理函数的url

阅读代码,

  1. var select = document.getElementById(choose);获得选择的选项
  2. 清空下一个列表框$(id).html("");
  3. 发起HTTP请求$.post({ //发起ajax请求 })
  4. 如果成功返回到了数据,就开始写下一个列表
    • $("<option selected='selected' disabled='disabled' style='display: none' value=''></option> ").appendTo(id);
      这一行是为了让默认为空,如果没有这一行的话候选框就会默认选择第一个,有了这一行在保证没有多出来一个空白选项的情况下让默认为空,因为我需要选择第二个歌曲的时候还要触发其他的事件,如果默认是第一个而且用户也想选择第一个的话,就监测不到改变了,没有这个需求可以注释这一行
    • 我们这里前端返回的是一个list,所以使用for (i = 0; i < data.length; i++)循环遍历返回的列表,列表的内容是字符串
    • $("<option value='" + data[i] + "'>" + data[i] + "</option>").appendTo(id);
      注意看这里还要一个知识点,这里的data[i]的外围有两个引号'" + data[i] + "',这里是因为我的数据中含有空格,比如'等你下课 DJ版' 因为HTML默认语法是以空格为分隔的,这里的value会默认识别成'等你下课''DJ版'会当成另一个参数而报错,在加一个引号就可以避免这个情况,我也不知道为啥
3. 后端获取数据函数
@app.route('/changeselectfield/', methods=['GET', 'POST'])
def changeselectfield():
    if request.method == "POST":
        data = request.get_json()
        name = data['name']
        song = singer2song[name]
        return jsonify(song)
    else:
        return {}

这个就比较简单了,从前端拿到请求的歌手名之后,然后还给一个list,比如选择了周杰伦,返回的变量song这个list就是['稻香','晴天','等你下课']这个格式


到此为止 我们已经大功告成
这篇文章参考了
FLASK使用AJAX进行访问数据库异步加载下拉框

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 【精时力学习日志】 本训练营:2021年100天精时力营·乘法 今日主题:3-5 日常的动态冥想 学习日期:202...
    谷小面阅读 186评论 0 0
  • 忍不住给自己也泡了一罐子酒 上次给朋友泡了酒之后 寻思要不要给自己也整一罐子 纠结了老半天 最后还是安排上了 这次...
    小小农人阅读 150评论 0 0
  • 讨厌:这两天特讨厌老马,七十六岁的人了,为老不尊,每天晚饭后总爱叫我家先生给他打电话,先生说"不打,求求你啦"无非...
    ee1d4fbde42d海阔天阅读 199评论 1 1
  • 戒掉刷朋友圈的习惯,做好自己的的事情,看书看书看书
    艾雪的简书阅读 110评论 0 0

友情链接更多精彩内容