1. 程式人生 > >select2 如何自定義提示資訊-布布扣-bubuko.com

select2 如何自定義提示資訊-布布扣-bubuko.com

標籤:color   dom   layui   href   預設事件   替換   each   ase   options   

  最近專案中使用到了select2來美化和豐富下拉框的功能,這款外掛功能豐富,使用簡單,可以對已經生成的select標籤進行改造,也可以對json資料直接生成下拉列表,包括一些檢索功能,非同步載入功能等,能夠很大程度的滿足視覺和互動的要求。是開發過程中不可多得的一款利器。

官方文件是英文文件且是以問答形式展示他的可配置項的,可能作者會覺得這樣做比較有趣,但是對於渣渣英語的我來說,肯定是一種煎熬, 現在和大家分享一下在開發過程中的一些問題:

一、使用篇

1.根據官方文件的提示配置了placeholder卻不起作用;

  1.1  你需要在select標籤中放置一個空的option標籤,用來做placeholder文字的儲存容器;

  1.2  你要在select標籤上新增一個屬性“data-placeholder=‘ 你要提示的placeholder  ‘”

  1.3  最後才是在select2 的配置項中加入配置項"placeholder: ‘請選擇‘,"

  而文件中卻沒有提到這些東西,小小的一個功能藏這麼多貓膩,真是心塞;

技術分享
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <link rel="stylesheet" href="bower_components/select2/dist/css/select2.css">
    </head>
    <body>
       <select data-tags="true" data-placeholder="請選擇" >
           <option></option>
           <option value="1">1111</option>
           <option value="2">2222</option>
           <option value="3">3333</option>
           <option value="4">4444</option>
       </select>

    </body>
    <script src="bower_components/jquery/dist/jquery.min.js"></script>
    <script src="bower_components/select2/dist/js/select2.min.js"></script>
    <script>
        $("select").select2({
          placeholder: "請選擇",
          allowClear: 0,
          minimumResultsForSearch: Infinity,
          width:200
        });
    </script>
</html>
View Code

2. 取消下拉框的檢索功能;

  配置項為 { minimumResultsForSearch: Infinity, }

二、改造篇

 一.下拉框選擇過程中彈框確認

  該類事件可以理解為在select2物件在操作的各個階段的鉤子函式,當然官方為我們配置相應的介面,允許我們在開啟,關閉,選前,選中,選後等時間階段來處理我們配置的回撥函式;

  這類事件(點選檢視)可以通過在on繫結在select2例項上,一般性的功能可以在回撥函式中處理;

            $("select").select2({
                placeholder: ‘請選擇‘
            }).on("select2:selecting",function(e){
                 alert(" 我選中了 ")
            });

  現在有一個棘手的問題,我需要在選中的一瞬間進行彈框提示,然後不允許select2的其他事件繼續向執行,然後經過彈框確認後再繼續向下執行,此時彈框不能做出任何改變;

  首先在點選模態框的過程中,不能讓select下拉框關閉:

  我們需要進行2步驟操作:

  1.1 在彈框出來後,除了點選“確認”和“取消”按鈕,點選其他地方不能關閉下拉框;

  select2會在其建構函式BaseSelection的原型上定義關閉方法,關閉方法中使用自定義的事件關聯到對應id的盒子上,我們可以在這個方法中來阻斷關閉操作;

  BaseSelection.prototype._attachCloseHandler = function (container) {
    var self = this;
    $(document.body).on(‘mousedown.select2.‘ + container.id, function (e) {
      var $target = $(e.target);

      var $select = $target.closest(‘.select2‘);

      var $all = $(‘.select2.select2-container--open‘);

      $all.each(function () {
        var $this = $(this);
        if (this == $select[0]) {
          return;
        }
        var $element = $this.data(‘element‘);
        //在模態框存在的條件下,禁止使用select2的關閉功能(這裡可以根據你使用的類來靈活操作)
        var mask = $(".layui-layer-shade");
        if(mask.length == 0){
          $element.select2(‘close‘);
        }
      });
    });
  };

  

  1.2 在選擇select2框下的內容時,不能立即執行回撥函式,回撥函式必須放在“確認”按鈕點選後處理;

               通常在最初程式設計的時候,正確的做法應該是把後續函式設計在layer的確認回撥函式中,我本來不打算使用select2外掛,但是產品的世界你懂得,變化是隨時隨地發生的。

    最初的函式是通過監控select標籤的change狀態來鏈式觸發的,這一點很重要,如果想把目標回撥函式放到select2的鉤子函式中,會直接執行,不符合我們彈框進行確認取消的目的;

    如何實現本地的這種非同步操作?其實我們需要使用一箇中間函式,讓這個函式去觸發select標籤的change事件。

 var selectWebNamer = $(".selectWebName").select2({
                myMsg:‘無可配置網站‘,    //此處不是select的配置項後面解說
                placeholder: ‘請選擇‘
            }).on("select2:selecting",function(e){
                if(data.siteList.length==0){
                    return  false;
                }
                if(!that.status.canChange){
                    that._confirmChange(e, that._queryParam,this);    
                }
            });

      第一件事情:阻止預設事件  event.preventDefault();  我們的非同步函式我們自己來控制,select2取消你自作主張的行為;

       此時繫結在select2:selecting 事件上的函式會去調起彈框視窗;

    that._queryParam 是中間函式,這個函式會在確認按鈕後執行;下一步會觸發真正的select標籤change事件;

    而event事件是select2包裝後的事件,這個包裝好的事件可以讓我們跟蹤到真正需要點選的select 標籤;所以在 that._queryParam 中需要帶入這個event物件;

    在確認或取消點選的一瞬間select2的下拉框要關閉,所以此時通過指正傳入這個select2物件也是有必要的;

  _confirmChange:function(event,callback,$this){
            var that = this;
            event.preventDefault();
            $(".layui-layer-shade").remove();
            layer.closeAll();
            layer.open({
                   type: 1,
                   title: ‘返回‘,
                   area: [‘500px‘, ‘270px‘],
                   btn: [ ‘確認‘,‘取消‘],
                   closeBtn: 2,
                   content: $(‘#changeMsg‘), 
                   btn1: function (index) {
                       layer.closeAll();
                       if(callback){
                           callback(event);
                           $($this).select2(‘close‘);
                           that.status.canChange = true;
                       }
                   },
                   btn2: function (index) {
                       layer.close(index);
                       $($this).select2(‘close‘);
                   }
               });
           //}
        },

    event物件中包含了我們現在操作的dom物件,和當前選中的option上的值;

     jquery 如何選中 select中某個option?,用的不多,可能大家都忘記了吧。

    此時,我們的change事件被觸發了,就和我們手動點選了option 一樣,後續的程式碼可以順利執行了。

  _queryParam:function(event){
            if(!event){
                return false;
            }
            var target = event.currentTarget;
            var name  = event.params.args.data.text;
            $(target).val(name).trigger("change");
        },

 

二、如何修改select2的提示資訊

    採用select2例項化後如果後臺沒有給我們返回資料的話,select2會友好的在下拉框處提示“No Result Is Fonud”(貌似是這樣)

    然後,可愛的互動妹妹說,不行,我不要看英文,我不認識。。。。。 好吧,你贏。

    檢查了一下,好像沒有這個提示資訊配置api,於是我就邪惡的找到引入檔案中的select2.min.js    ctrl+R(“No Result Is Fonud” --------" 別瞎拉了,後臺沒返回")

    ok  懶得改,就這樣。

    過了一會兒互動妹妹不幹了,怎麼都是“別瞎拉了,後臺沒返回”,我要的是“呵呵,我不想給你返回 ”,“ 返回過程中被恐龍吃掉了 ”,“你太醜了,不給你看”。。。。。。。

    好吧好吧,我給你配置成你想說啥說啥還不行嗎。

    看了一下文件,作者一看就是高手提供了10來種語言的提示資訊,原來人家本來就有中文版的“別瞎拉了,你後臺沒返回”,還有英文版的“don`t  blind pull la , then didn‘t give us ”,還有日文版的“ 雅蠛蝶雅蠛蝶” ,可恨的是zh-CH.js和zh-TW.js  是分別簡體和繁體的,丫的,搞事情。

    如果沒有要求提示不一樣的內容,直接在配置項中設定language就可以使用對應的語言;

    如果想要提示不應的內容,需要手動改造一下,讓它去替換。

    我們找到與結果相關的Result模組,並找到其原型上的append方法;

    我們在option上使用的欄位是myMsg ,來配置本下拉框的無內容提示,

    原來的提示條件最好給他保留 如果我沒有配置myMsg欄位那你就按照你原來的處理,如果我有配置myMsg欄位,你就要按照我的來。

      if( data.results == null || data.results.length === 0)&& !myMsg)  {   你原來怎麼處理就怎麼處理  }

         else if((data.results == null || data.results.length === 0)&& !!myMsg){   在result:message 時間的引數中加入我們的資訊  }

  Results.prototype.append = function (data) {
    this.hideLoading();
    var myMsg = this.options.options.myMsg;   //獲取提示文字
    var $options = [];
    if ((data.results == null || data.results.length === 0)&& !myMsg) {   //按你的來
      if (this.$results.children().length === 0) {
        this.trigger(‘results:message‘, {
          message: ‘noResults‘
        });
      }
      return;
    }else if((data.results == null || data.results.length === 0)&& !!myMsg){   //按我的來
      if (this.$results.children().length === 0) {
        this.trigger(‘results:message‘, {
          message: ‘noResults‘,
          myMessage:myMsg
        });
      }
      return;
    }

    data.results = this.sort(data.results);

    for (var d = 0; d < data.results.length; d++) {
      var item = data.results[d];

      var $option = this.option(item);

      $options.push($option);
    }

    this.$results.append($options);
  };

  然後順藤摸瓜,從results:message事件上摸到展示displayMessage方法上,然後我們判斷一下 “myMessage” 帶過來了沒有,如果帶過來了,那就用我們的提示

  Results.prototype.displayMessage = function (params) {
    var escapeMarkup = this.options.get(‘escapeMarkup‘);
    this.clear();
    this.hideLoading();
    var $message = $(
      ‘<li role="treeitem" aria-live="assertive"‘ +
      ‘ class="select2-results__option"></li>‘
    );

    var message = this.options.get(‘translations‘).get(params.message);
    $message.append(
      escapeMarkup(
        params.myMessage? params.myMessage:message(params.args)    //決定用我們的提示還是它自己的提示。
      )
    );

    $message[0].className += ‘ select2-results__message‘;

    this.$results.append($message);
  };

 

  ok 至此,互動妹子的需求都實現了,select2的本次改造也結束了。

 

select2 如何自定義提示資訊

標籤:color   dom   layui   href   預設事件   替換   each   ase   options   

原文:http://www.cnblogs.com/wuhaozhou/p/7449661.html

 var selectWebNamer = $(".selectWebName").select2({
                myMsg:‘無可配置網站‘,    //此處不是select的配置項後面解說
                placeholder: ‘請選擇‘
            }).on("select2:selecting",function(e){
                if(data.siteList.length==0){
                    return  false;
                }
                if(!that.status.canChange){
                    that._confirmChange(e, that._queryParam,this);    
                }
            });
  Results.prototype.append = function (data) {
    this.hideLoading();
    var myMsg = this.options.options.myMsg;   //獲取提示文字
    var $options = [];
    if ((data.results == null || data.results.length === 0)&& !myMsg) {   //按你的來
      if (this.$results.children().length === 0) {
        this.trigger(‘results:message‘, {
          message: ‘noResults‘
        });
      }
      return;
    }else if((data.results == null || data.results.length === 0)&& !!myMsg){   //按我的來
      if (this.$results.children().length === 0) {
        this.trigger(‘results:message‘, {
          message: ‘noResults‘,
          myMessage:myMsg
        });
      }
      return;
    }

    data.results = this.sort(data.results);

    for (var d = 0; d < data.results.length; d++) {
      var item = data.results[d];

      var $option = this.option(item);

      $options.push($option);
    }

    this.$results.append($options);
  };

  然後順藤摸瓜,從results:message事件上摸到展示displayMessage方法上,然後我們判斷一下 “myMessage” 帶過來了沒有,如果帶過來了,那就用我們的提示

  Results.prototype.displayMessage = function (params) {
    var escapeMarkup = this.options.get(‘escapeMarkup‘);
    this.clear();
    this.hideLoading();
    var $message = $(
      ‘<li role="treeitem" aria-live="assertive"‘ +
      ‘ class="select2-results__option"></li>‘
    );

    var message = this.options.get(‘translations‘).get(params.message);
    $message.append(
      escapeMarkup(
        params.myMessage? params.myMessage:message(params.args)    //決定用我們的提示還是它自己的提示。
      )
    );

    $message[0].className += ‘ select2-results__message‘;

    this.$results.append($message);
  };

         else if((data.results == null || data.results.length === 0)&& !!myMsg){   在result:message 時間的引數中加入我們的資訊  }

      if( data.results == null || data.results.length === 0)&& !myMsg)  {   你原來怎麼處理就怎麼處理  }

    原來的提示條件最好給他保留 如果我沒有配置myMsg欄位那你就按照你原來的處理,如果我有配置myMsg欄位,你就要按照我的來。

    我們在option上使用的欄位是myMsg ,來配置本下拉框的無內容提示,

    我們找到與結果相關的Result模組,並找到其原型上的append方法;

    如果想要提示不應的內容,需要手動改造一下,讓它去替換。

    如果沒有要求提示不一樣的內容,直接在配置項中設定language就可以使用對應的語言;

    看了一下文件,作者一看就是高手提供了10來種語言的提示資訊,原來人家本來就有中文版的“別瞎拉了,你後臺沒返回”,還有英文版的“don`t  blind pull la , then didn‘t give us ”,還有日文版的“ 雅蠛蝶雅蠛蝶” ,可恨的是zh-CH.js和zh-TW.js  是分別簡體和繁體的,丫的,搞事情。

二、如何修改select2的提示資訊

    採用select2例項化後如果後臺沒有給我們返回資料的話,select2會友好的在下拉框處提示“No Result Is Fonud”(貌似是這樣)

  _queryParam:function(event){
            if(!event){
                return false;
            }
            var target = event.currentTarget;
            var name  = event.params.args.data.text;
            $(target).val(name).trigger("change");
        },

    此時,我們的change事件被觸發了,就和我們手動點選了option 一樣,後續的程式碼可以順利執行了。

     jquery 如何選中 select中某個option?,用的不多,可能大家都忘記了吧。

    event物件中包含了我們現在操作的dom物件,和當前選中的option上的值;

  _confirmChange:function(event,callback,$this){
            var that = this;
            event.preventDefault();
            $(".layui-layer-shade").remove();
            layer.closeAll();
            layer.open({
                   type: 1,
                   title: ‘返回‘,
                   area: [‘500px‘, ‘270px‘],
                   btn: [ ‘確認‘,‘取消‘],
                   closeBtn: 2,
                   content: $(‘#changeMsg‘), 
                   btn1: function (index) {
                       layer.closeAll();
                       if(callback){
                           callback(event);
                           $($this).select2(‘close‘);
                           that.status.canChange = true;
                       }
                   },
                   btn2: function (index) {
                       layer.close(index);
                       $($this).select2(‘close‘);
                   }
               });
           //}
        },

    在確認或取消點選的一瞬間select2的下拉框要關閉,所以此時通過指正傳入這個select2物件也是有必要的;

    而event事件是select2包裝後的事件,這個包裝好的事件可以讓我們跟蹤到真正需要點選的select 標籤;所以在 that._queryParam 中需要帶入這個event物件;

    that._queryParam 是中間函式,這個函式會在確認按鈕後執行;下一步會觸發真正的select標籤change事件;

       此時繫結在select2:selecting 事件上的函式會去調起彈框視窗;

      第一件事情:阻止預設事件  event.preventDefault();  我們的非同步函式我們自己來控制,select2取消你自作主張的行為;

    如何實現本地的這種非同步操作?其實我們需要使用一箇中間函式,讓這個函式去觸發select標籤的change事件。

    最初的函式是通過監控select標籤的change狀態來鏈式觸發的,這一點很重要,如果想把目標回撥函式放到select2的鉤子函式中,會直接執行,不符合我們彈框進行確認取消的目的;

               通常在最初程式設計的時候,正確的做法應該是把後續函式設計在layer的確認回撥函式中,我本來不打算使用select2外掛,但是產品的世界你懂得,變化是隨時隨地發生的。

  1.2 在選擇select2框下的內容時,不能立即執行回撥函式,回撥函式必須放在“確認”按鈕點選後處理;

  BaseSelection.prototype._attachCloseHandler = function (container) {
    var self = this;
    $(document.body).on(‘mousedown.select2.‘ + container.id, function (e) {
      var $target = $(e.target);

      var $select = $target.closest(‘.select2‘);

      var $all = $(‘.select2.select2-container--open‘);

      $all.each(function () {
        var $this = $(this);
        if (this == $select[0]) {
          return;
        }
        var $element = $this.data(‘element‘);
        //在模態框存在的條件下,禁止使用select2的關閉功能(這裡可以根據你使用的類來靈活操作)
        var mask = $(".layui-layer-shade");
        if(mask.length == 0){
          $element.select2(‘close‘);
        }
      });
    });
  };

  select2會在其建構函式BaseSelection的原型上定義關閉方法,關閉方法中使用自定義的事件關聯到對應id的盒子上,我們可以在這個方法中來阻斷關閉操作;

  1.1 在彈框出來後,除了點選“確認”和“取消”按鈕,點選其他地方不能關閉下拉框;

  我們需要進行2步驟操作:

  首先在點選模態框的過程中,不能讓select下拉框關閉:

  現在有一個棘手的問題,我需要在選中的一瞬間進行彈框提示,然後不允許select2的其他事件繼續向執行,然後經過彈框確認後再繼續向下執行,此時彈框不能做出任何改變;

            $("select").select2({
                placeholder: ‘請選擇‘
            }).on("select2:selecting",function(e){
                 alert(" 我選中了 ")
            });

  這類事件(點選檢視)可以通過在on繫結在select2例項上,一般性的功能可以在回撥函式中處理;

  該類事件可以理解為在select2物件在操作的各個階段的鉤子函式,當然官方為我們配置相應的介面,允許我們在開啟,關閉,選前,選中,選後等時間階段來處理我們配置的回撥函式;

 一.下拉框選擇過程中彈框確認