Angularjs实现带查找筛选功能的select下拉框示例代码

前端之家收集整理的这篇文章主要介绍了Angularjs实现带查找筛选功能的select下拉框示例代码前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

对于select的下拉列表,像国家选择这样的功能,全世界那么多国家,一直拉滚动条多辛苦,眼睛也要盯着找,累!所以为优化用户体验,带查找功能的下拉框是非常非常有必要的。都知道jquery里有这样的插件,但我们用的是Angularjs,更希望用双向绑定,指令的方式优雅地解决这个问题。

分析

我们的目标是在原来的function parseOptions(optionsExp,element,scope) {
// ngOptions里的正则
var NG_OPTIONS_REGEXP = /^\s([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?(?:\s+disable\s+when\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w])|(?:(\s([\$\w][\$\w])\s,\s([\$\w][\$\w])\s)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/;

 var match = optionsExp.match(NG_OPTIONS_REGEXP);
 if (!(match)) {
   console.log('ng-options 表达式有误')
 }
 var valueName = match[5] || match[7];
 var keyName = match[6];
 var displayFn = $parse(match[2]);
 var keyFn = $parse(match[1]);
 var valuesFn = $parse(match[8]);

 var labelArray = [],idArray = [],optionValues = [];
 scope.$watch(match[8],function(newValue,oldValue) {
   if (newValue && newValue.length > 0) {
     optionValues = valuesFn(scope) || [];
     labelArray = [];
     idArray = []
     for (var index = 0,l = optionValues.length; index < l; index++) {
       var it = optionValues[index];
       if (match[2] && match[1]) {
         var localIt = {};
         localIt[valueName] = it;
         var label = displayFn(scope,localIt);
         var dataId = keyFn(scope,localIt);
         labelArray.push(label);
         idArray.push(dataId);
       }
     }

     scope.options = {
       'optionValues': optionValues,'labelArray': labelArray,'idArray': idArray
     }
   }
 });

}
return {
restrict: 'A',require: ['ngModel'],priority: 100,replace: false,scope: true,template: '<div class="chose-container">' +
'<div class="chose-single"><span class="j-view"><i class="glyphicon glyphicon-remove">

' +
'<div class="chose-drop chose-hide j-drop">' +
'<div class="chose-search">' +
'<input class="j-key" type="text" autocomplete="off">' +
'
' +
'<ul class="chose-result">' +
// '
  • {{'+ valueTempl+'}}
  • '+
    '' +
    '
    ' +
    '
    ',link: {
    pre: function selectSearchPreLink(scope,attr,ctrls) {

         var tmplNode = $(this.template).first();
    
         var modelName = attr.ngModel,name = attr.name? attr.name:('def'+Date.now());
         tmplNode.attr('id',name + '_chosecontianer');
    
         $animate.enter(tmplNode,element.parent(),element);
       },post: function selectSearchPostLink(scope,ctrls) {
         var choseNode = element.next(); //$('#'+attr.name +'_chosecontianer');
         choseNode.addClass(attr.class);
         element.addClass('chose-hide');
         // 当前选中项
         var ngModelCtrl = ctrls[0];
         if (!ngModelCtrl || !attr.name) return;
    
         par<a href="https://www.jb51.cc/tag/SEO/" title="SEO">SEO</a>ptions(attr.ngOptions,scope);
         var rs = {};
    
         function setView() {
           var currentKey = ngModelCtrl.$modelValue;
           if (isNaN(currentKey) || !currentKey) {
             currentKey = '';
             choseNode.find('.j-view:first').text('请选择');
             choseNode.find('i').addClass('chose-hide');
           }
           if ((currentKey + '').length > 0) {
             for (var i = 0,l = rs.idArray.length; i < l; i++) {
               if (rs.idArray[i] == currentKey) {
                 choseNode.find('.j-view:first').text(rs.labelArray[i]);
                 choseNode.find('i').removeClass('chose-hide');
                 break;
               }
             }
           }
         }
    
         function setViewAndData() {
           if (!scope.options) {
             return;
           }
           rs = scope.options;
           setView();
         }
         scope.$watchCollection('options',setViewAndData);
         scope.$watch(attr.ngModel,setView);
    
    
         function getListNodes(value) {
           var nodes = [];
           value = $.trim(value);
           for (var i = 0,l = rs.labelArray.length; i < l; i++) {
             if (rs.labelArray[i].indexOf(value) > -1) {
               nodes.push($('<li>').data('id',rs.idArray[i]).text(rs.labelArray[i]))
             }
           }
           return nodes;
    
         }
         choseNode.on('keyup','.j-key',function() {
           // <a href="https://www.jb51.cc/tag/sousuo/" target="_blank" class="keywords">搜索</a>输入框keyup,重新筛选列表
           var value = $(this).val();
           choseNode.find('ul:first').empty().append(getListNodes(value));
           return false;
         }).on('click',function() {
           choseNode.find('.j-drop').removeClass('chose-hide');
           if (choseNode.find('.j-view:first').text() != '请选择') {
             choseNode.find('i').removeClass('chose-hide');
           }
           choseNode.find('ul:first').empty().append(getListNodes(choseNode.find('.j-key').val()));
           return false;
         }).on('click','ul>li',function() {
           var _this = $(this);
           ngModelCtrl.$setViewValue(_this.data('id'));
           ngModelCtrl.$render();
           choseNode.find('.j-drop').addClass('chose-hide');
           return false;
    
         }).on('click','i',function() {
           ngModelCtrl.$setViewValue('');
           ngModelCtrl.$render();
           choseNode.find('.j-view:first').text('请选择');
           return false;
    
         });
         $(document).on("click",function() {
           $('.j-drop').addClass('chose-hide');
           choseNode.find('i').addClass('chose-hide');
           return false;
         });
    
       }
     }

    };
    })

    1.2 css代码(用less写的,以下是编译后的)

    使用及效果

    详细说明

    程序中的关键点是parSEOptions函数,即前面分析里的问题1。parSEOptions是参考ng-options的源码实现的,原来是想返回一个对象,这个对象里包含了数据源,但是在调试时,发现post函数中该函数返回对象里的数据为空,watch不到,所以改为用scope.options来存数据。

    总结

    以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

    原文链接:https://www.f2er.com/js/45427.html

    猜你在找的JavaScript相关文章