[前端開發] chosen實作多功能下拉選單

  • 1720
  • 0

利用chosen套件開發多功能下拉選單的技巧,同場加映JsFiddle分享

甚麼是chosen套件?

chosen是一個前端的Jquery 套件,可以很方便的開發多功能的下拉選單功能。舉凡查詢、多選、複選、預設浮水印等等功能都可透過簡單的設定方式就能獲得這些好處。

 

JsFiddle介紹

以往展示前端功能都必須先建立一個Web Application,然後把網站推到公開的網址上,才能與其他人分享。這樣其實是很不便利的,尤其是當團隊成員想要一起玩玩看你的功能,就必須要把原始碼下載到本機建立環境,才能夠進行測試,而修改後的成果要分享回來,又必須再更新網站。其中,不乏版本控管、網站更新等等瑣碎事項,但這些根本不是前端開發的一部分!

所以,假如有一個能夠線上即時編輯且能馬上看到結果,還可以提供簡單版控功能,並能快速分享的工具,那將會是前端工程師的一個大福音。恭喜,這個願望已經實現,JsFiddle這個線上編輯工具可以提供上述的功能。

JsFiddle網址

JsFiddle在使用上非常直覺,主要就是四個區塊在玩,可直接參考下圖,1號球放置Html Tag,2號球放置javaScript語法,3號球放置Css,在4號球看結果。

但大家都知道,前端開發現在沒人在寫純的JavaScript,一定是靠前端的Framework來做開發。JsFiddle預設只支援純的JavaScript,但要安裝Framework也相當容易,可以直接在2號球的齒輪點開,預設就有常用的Framework可選,可直接參考下圖。

另外一種方式就是透過CDN(Content Delivery Network)的方式下載,基本上常用的Framework直接在Google搜尋該Framework名稱後面加上CDN就可以找到。下圖是chosen套件的CDN範例,當然,如果真的找不到的話,也可以上傳到自己的雲端空間,供JsFiddle下載。

有了連結檔之後,有兩種方式可以引入,一種是直接寫在Html區塊。

<script src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>

另一種是透過JsFiddle的外部引用功能,將網址貼上後,點選+號,請直接參考下圖。

相關的資源安裝完畢後,就可以直接開發了,想要測試的話,直接按下上方的Run,就可以在Result區域看到結果。

如果要分享的話,就按下旁邊的Save,然後將網址複製下來貼給隊友,隊友就可以看到你的作品。存檔後的檔案Save按鈕會變成Update,之後做的任何更新,後面會自動帶版本號,可以做到簡單的版本控管效果,如下圖代表的是第3版。

剩下的功能就不多說了,都很直覺,只要了解起手式,後續的延伸只是一盤小菜。

 

透過chosen開發多功能下拉選單

使用者需求

  1. 下拉選單未被選取時,預設需有浮水印顯示指定文字(例如:請輸入單據編號)。
  2. 下拉選單被選取後,顯示資料的表格要迅速反應篩選結果。
  3. 使用者可透過輸入關鍵字,篩選下拉選單內的選項。
  4. 使用者輸入關鍵字過程,必須"即時"對下拉選單內的選項做篩選。
  5. 使用者可取消關鍵字。
  6. 搜尋結果如為空,需顯示指定文字(例如:查無結果)。

以上是常見關於下拉選單的使用者需求,如果要透過自行實作的方式,個人覺得3、4是比較刁的功能。但在chosen套件的威能下,這些功能應該不到5分鐘就能完成。

首先引用相關Framework,把環境準備起來

核心Framework下載位置

  • chosen.min.css : https://cdnjs.cloudflare.com/ajax/libs/chosen/1.5.1/chosen.min.css
  • chosen.jquery.min.js : https://cdnjs.cloudflare.com/ajax/libs/chosen/1.5.1/chosen.jquery.min.js
  • jquery-2.1.4.min.js : https://code.jquery.com/jquery-2.1.4.min.js
  • angular.min.js : https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js
  • angular-chosen.min.js : https://cdnjs.cloudflare.com/ajax/libs/angular-chosen-localytics/1.4.0/angular-chosen.min.js

輔助Framework下載位置 (bootstrap只是排版稍微用到,本範例不裝也可以) 

  • bootstrap.min.css : https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css
  • bootstrap.min.js : https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js

安裝完成後的外部資源引用列表如下圖所示。

再來,建立angular的module,此段程式碼填入到JsFiddle的JavaScript區。

//localytics.directives內定義angular chosen
angular.module('app', ['localytics.directives']);

angular.module('app')
    .controller('MainCtrl', function ($scope) {
    //準備簡單假資料
    $scope.myItemGroups=[{Key:'1',Value:'A'},{Key:'2',Value:'B'},{Key:'3',Value:'C'}]
});

接下來,撰寫呈現畫面的Html程式碼。

<div ng-app="app" ng-controller="MainCtrl">
    <select id="ApproveListSearch" class="form-control col-lg-12" 
        <!--支援chosen,此處用directive的方式實作-->
        chosen 
        <!--顯示浮水印 需求1 -->
        data-placeholder-text-single="'請輸入單據類別或代號...'"
        <!--提供篩選功能 並能即時比對下拉選單的內容 需求3 4-->
        ng-options="s.Key as s.Key + '-' +  s.Value  for s in myItemGroups" 
        <!--可取消關鍵字搜尋 需求5-->
        data-allow-single-deselect="true"
        <!--沒有資料時需顯示特定文字 需求6-->
        data-no-results-text="'沒有符合的資料..'"
        data-max-selected-options="1" >
   </select>
   
   <!--顯示假資料-->
   <div ng-repeat ="item in myItemGroups>
     {{item.Key}}
   </div>
</div>

這裡只有ng-optoins的設定內容需要說明,有點不直覺,他主要分成兩個區塊,從for來做切割,切割成兩部分

  1. "s.Key as s.Key + '-' +  s.Value "
  2. "for s in myItemGroups"

先看"for s in myItemGroups" 這段 s 是自定義的名稱 in 是關鍵字 myItemGroups是在scope裡定義的一組陣列(假資料),而s是我們上面定義的物件,裡面有兩個屬性,一個是Key,一個是Value;再來看"s.Key as s.Key + '-' +  s.Value",下拉選單都會有一 組Key、一組Value,Value是呈現給使用者看的,而Key是用來存在資料庫內或者傳回後端供Api使用。

所以講白話解釋"s.Key as s.Key + '-' +  s.Value"整段意思,我們拿s物件的Key屬性來當作下拉選單的Key,拿"s.Key + '-' +  s.Value"來當作下拉選單的Value,中間用關鍵字"as"串接。

以上的設定已經完成了六項需求中的五項,除了第二項需求 "下拉選單被選取後,顯示資料的表格要迅速反應篩選結果" 還未達成。這個需求必須靠ng-model的方式來實作,我們在選定下拉選單之後,下拉選單會把我們選定的值繫結到ng-model屬性中。最後只需要在資料呈現的地方下一個filter,並把filter的內容設定成ng-model所繫結的變數就可達成需求,直接參考下方程式碼片段。

   <select id="ApproveListSearch" class="form-control col-lg-12"  
        <!--以上略-->
        <!--設定 ng-model -->
        ng-model="ApproveListSearchWord">
   </select>


   <!--透過filter屬性 篩選ng-model繫結的值 -->
   <div ng-repeat ="item in myItemGroups | filter: ApproveListSearchWord">
     {{item.Key}}
   </div>

額外補充,使用chosen有個很奇怪的問題,就是下拉選單變動的時候,chosen不會自動更新,造成ng-model繫結的值跟使用者選的值不一樣。不過可以用ng內建$watch的方式來監控ng-model的值,如果有異動就請chosen更新就可以了,具體實作方式參考下面。

    $scope.$watch('ApproveListSearchWord', function (newValue, oldValue) {
        if (newValue !== oldValue) {
            $('#ApproveListSearch').trigger("chosen:updated");
        }
    }, true);

完整程式碼請參考這裡

 

結語

使用chosen套件可以很快速的開發多功能下拉選單,在前端的世界裡,似乎已經轉變成誰能快速利用現成的輪子來建造自己的功能的人才能勝出。

除此之外,JsFiddle是一個非常方便可以測試prototype的線上編輯器,也可以快速地分享及展示成果,是我們前端開發者的好朋友。