Flask實(shí)現(xiàn)級(jí)聯(lián)下拉菜單的完美方案

最近在做一個(gè)項(xiàng)目的時(shí)候有兩個(gè)下拉框,需要先選擇\color{red}{歌手}再選擇\color{red}{歌曲},有一個(gè)級(jí)聯(lián)的關(guān)系,就想填地區(qū)的時(shí)候先省份再城市一樣,實(shí)現(xiàn)的效果如下圖所示

級(jí)聯(lián)菜單效果圖

為了實(shí)現(xiàn)這個(gè)目的,我們需要用到Ajax
貼一點(diǎn)菜鳥教程上面的Ajax的介紹

AJAX = Asynchronous JavaScript and XML(異步的 JavaScript 和 XML)。
AJAX 不是新的編程語(yǔ)言,而是一種使用現(xiàn)有標(biāo)準(zhǔn)的新方法。
AJAX 最大的優(yōu)點(diǎn)是在不重新加載整個(gè)頁(yè)面的情況下,可以與服務(wù)器交換數(shù)據(jù)并更新部分網(wǎng)頁(yè)內(nèi)容。
AJAX 不需要任何瀏覽器插件,但需要用戶允許JavaScript在瀏覽器上執(zhí)行。

如果單獨(dú)寫Ajax是比較繁瑣的,可以自行百度,好在JQuery庫(kù)中已經(jīng)集成了Ajax的庫(kù)函數(shù),JQuery對(duì)Ajax的封裝介紹

jQuery 提供多個(gè)與 AJAX 有關(guān)的方法。

  • 通過(guò) jQuery AJAX 方法,您能夠使用 HTTP Get 和 HTTP Post 從遠(yuǎn)程服務(wù)器上請(qǐng)求文本、HTML、XML 或 JSON - 同時(shí)您能夠把這些外部數(shù)據(jù)直接載入網(wǎng)頁(yè)的被選元素中。
  • 提示:如果沒有 jQuery,AJAX 編程還是有些難度的。
  • 編寫常規(guī)的 AJAX 代碼并不容易,因?yàn)椴煌臑g覽器對(duì) AJAX 的實(shí)現(xiàn)并不相同。這意味著您必須編寫額外的代碼對(duì)瀏覽器進(jìn)行測(cè)試。不過(guò),jQuery 團(tuán)隊(duì)為我們解決了這個(gè)難題,我們只需要一行簡(jiǎn)單的代碼,就可以實(shí)現(xiàn) AJAX 功能。

下面我們開始編寫函數(shù)處理

為了實(shí)現(xiàn)這個(gè)效果,流程有幾個(gè)步驟:

  1. 編寫好第一個(gè)下拉菜單(我這里第一個(gè)下拉菜單也是從后臺(tái)獲取的),和第二個(gè)菜單的空表
  2. 使用HTML 事件屬性中的onchange監(jiān)測(cè)到點(diǎn)擊了第一個(gè)下拉菜單,轉(zhuǎn)到處理函數(shù)
  3. 處理函數(shù)使用Ajax發(fā)送HTTP請(qǐng)求,向后端請(qǐng)求數(shù)據(jù)
  4. 使用JavaScript清空下一個(gè)列表的選項(xiàng),并重寫
1. 首先寫第一個(gè)下拉菜單和第二個(gè)空的下拉慘淡:

第一個(gè)下拉菜單前端代碼如下

<div >
    <form>
        <label>請(qǐng)選擇一位音樂(lè)人:</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()函數(shù)我們下面編寫,這個(gè)的意思就是如果監(jiān)測(cè)到有變動(dòng),那么就觸發(fā)這個(gè)函數(shù)
<option value="{{ singer_name }}"> {{ singer_name }} </option>這個(gè)option的內(nèi)容也是從后端獲取的,這個(gè)語(yǔ)法大家可以自行百度,如果不需要這樣可以直接寫死。

效果如下


音樂(lè)人候選框

下面我們寫第二個(gè)選擇框,不過(guò)這個(gè)選擇框是空的

<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"> 請(qǐng)選擇歌曲</label>
        <select name="song_selection" id="song_selection">
             {# 這里空著 等待獲取后端返回的數(shù)據(jù)再寫 #}
        </select>
        <br>
    </form>
</div>
2. 編寫觸發(fā)函數(shù)
<script>
    function changefield(choose, id, url) {
        var data;
        var select = document.getElementById(choose);
        $(id).html(""); //每次重新選擇當(dāng)前列表框,就清空下一級(jí)列表框。
        for (i = 0; i < select.length; i++) {
            if (select[i].selected) { //判斷被選中項(xiàng)
                Name = select[i].text;
                data = {
                    "name": Name
                };
                $.post({ //發(fā)起ajax請(qǐng)求
                    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>

函數(shù)三個(gè)參數(shù)

  • choose是第一個(gè)選擇框的ID
  • id是第二個(gè)需要更改的選擇框的id
  • url是前端的處理函數(shù)的url

閱讀代碼,

  1. var select = document.getElementById(choose);獲得選擇的選項(xiàng)
  2. 清空下一個(gè)列表框$(id).html("");
  3. 發(fā)起HTTP請(qǐng)求$.post({ //發(fā)起ajax請(qǐng)求 })
  4. 如果成功返回到了數(shù)據(jù),就開始寫下一個(gè)列表
    • $("<option selected='selected' disabled='disabled' style='display: none' value=''></option> ").appendTo(id);
      這一行是為了讓默認(rèn)為空,如果沒有這一行的話候選框就會(huì)默認(rèn)選擇第一個(gè),有了這一行在保證沒有多出來(lái)一個(gè)空白選項(xiàng)的情況下讓默認(rèn)為空,因?yàn)槲倚枰x擇第二個(gè)歌曲的時(shí)候還要觸發(fā)其他的事件,如果默認(rèn)是第一個(gè)而且用戶也想選擇第一個(gè)的話,就監(jiān)測(cè)不到改變了,沒有這個(gè)需求可以注釋這一行
    • 我們這里前端返回的是一個(gè)list,所以使用for (i = 0; i < data.length; i++)循環(huán)遍歷返回的列表,列表的內(nèi)容是字符串
    • $("<option value='" + data[i] + "'>" + data[i] + "</option>").appendTo(id);
      注意看這里還要一個(gè)知識(shí)點(diǎn),這里的data[i]的外圍有兩個(gè)引號(hào)'" + data[i] + "',這里是因?yàn)槲业臄?shù)據(jù)中含有空格,比如'等你下課 DJ版' 因?yàn)镠TML默認(rèn)語(yǔ)法是以空格為分隔的,這里的value會(huì)默認(rèn)識(shí)別成'等你下課''DJ版'會(huì)當(dāng)成另一個(gè)參數(shù)而報(bào)錯(cuò),在加一個(gè)引號(hào)就可以避免這個(gè)情況,我也不知道為啥
3. 后端獲取數(shù)據(jù)函數(shù)
@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 {}

這個(gè)就比較簡(jiǎn)單了,從前端拿到請(qǐng)求的歌手名之后,然后還給一個(gè)list,比如選擇了周杰倫,返回的變量song這個(gè)list就是['稻香','晴天','等你下課']這個(gè)格式


到此為止 我們已經(jīng)大功告成
這篇文章參考了
FLASK使用AJAX進(jìn)行訪問(wèn)數(shù)據(jù)庫(kù)異步加載下拉框

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 【精時(shí)力學(xué)習(xí)日志】 本訓(xùn)練營(yíng):2021年100天精時(shí)力營(yíng)·乘法 今日主題:3-5 日常的動(dòng)態(tài)冥想 學(xué)習(xí)日期:202...
    谷小面閱讀 186評(píng)論 0 0
  • 忍不住給自己也泡了一罐子酒 上次給朋友泡了酒之后 尋思要不要給自己也整一罐子 糾結(jié)了老半天 最后還是安排上了 這次...
    小小農(nóng)人閱讀 150評(píng)論 0 0
  • 討厭:這兩天特討厭老馬,七十六歲的人了,為老不尊,每天晚飯后總愛叫我家先生給他打電話,先生說(shuō)"不打,求求你啦"無(wú)非...
    ee1d4fbde42d海闊天閱讀 199評(píng)論 1 1
  • 戒掉刷朋友圈的習(xí)慣,做好自己的的事情,看書看書看書
    艾雪的簡(jiǎn)書閱讀 110評(píng)論 0 0

友情鏈接更多精彩內(nèi)容