Angularjs implements select drop-down box instances with search and filtering functions, and angularjsselect

Source: Internet
Author: User

Angularjs implements select drop-down box instances with search and filtering functions, and angularjsselect

I. background

For the select drop-down list, such as the Country selection function, so many countries around the world, the scroll bar has been pulling much effort, eyes also need to stare, tired! So, in order to optimize the user experience, it is very necessary to bring the search function to the drop-down box. We all know that jquery has such a plug-in, but we use Angularjs. We also hope to solve this problem elegantly by Using Bidirectional binding and instructions.

Analysis:

Target Add a new select-search attribute to the original <select ng-options = ""> tag to support the search function. If this attribute does not work, it does not affect the original select function.
Problem

1. In the selectSearch command, How can I obtain the data source in ng-options and the specified value (value of the option label) and text (text in the option label) Field names.

2. How can I filter data? Indicates whether to display the matching items each time, hide the non-matching items or repeatedly match from the data source, and regenerate the node.

Ideas

1. Refer to the ng-options command provided by angular to obtain the data source, value, and text field name.

In particular, only the normal format of ng-options = "obj. value as obj. text for obj in list" is supported, and those with groups are not supported at the moment.

2. regenerate the node. (Why is it so convenient !)

II. Specific implementation

1. Code Section

1.1 js Code (introduce jquery first, or an error will be reported)

/*** Drop-down box with filtering function * usage <select ngc-select-search name = "select1" ng-options = ""> * description [select must have name, ng-options attribute] */. directive ('ngcselectsearch', function ($ animate, $ compile, $ parse) {function parseOptions (optionsExp, element, scope) {// regular var NG_OPTIONS_REGEXP =/^ \ s * ([\ s \ S] +?) in ngOptions ?) (?: \ 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 expression error')} 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': idAr Ray }});} return {restrict: 'A', require: ['ngmodel'], priority: 100, replace: false, scope: true, template: '<div class = "chose-container">' + '<div class = "chose-single"> <span class = "j-view"> </span> <I class = "glyphicon-remove"> </I> </div> '+' <div class = "chose-drop chose-hide j-drop"> '+' <div class = "chose-search"> '+' <input class = "j-key" type = "text" autocomplete = "off"> '+' </div>' + '<Ul class = "chose-result">' + // '<li ng-repeat = "' + repeatTempl + '" data-id = "' + keyTempl + '" >{{ '+ valueTempl +' }}</li> '+' </ul> '+' </div> ', link: {pre: function selectSearchPreLink (scope, element, 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, element, attr, 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; parseOptions (attr. ngOptions, element, scope); var rs ={}; function setView () {var currentKey = ngModelCtrl. $ modelValue; if (isNaN (currentKey) |! CurrentKey) {currentKey = ''; choseNode. find ('. j-view: first '). text ('Please select'); 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 n Odes;} choseNode. on ('keyup ','. j-key', function () {// search the input box keyup and filter the list var value =$ (this) again ). 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 ()! = 'Select') {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 ('select '); return false ;}); $ (document ). on ("click", function () {$ ('. j-drop '). addClass ('chose-hide '); choseNode. find ('I '). addClass ('chose-hide '); return false ;});}}};})

1.2 css code (written in less mode, which is compiled below)

.chose-hide { position: absolute!important; top: -999em !important;}.chose-container { border: none!important; float: left; margin-right: 40px; padding: 0!important; position: relative;}.chose-container .chose-single { padding: 6px 12px; color: #333; width: 100%; border: 1px solid #eee; display: inline-block; height: 30px;}.chose-container .chose-single::after { content: ''; position: absolute; border-width: 6px 3px; border-style: solid; /* border-top-color: transparent; */ border-left-color: transparent; border-right-color: transparent; border-bottom-color: transparent; right: 8px; top: 12px;}.chose-container .chose-single i { width: 12px; float: right; right: 8px; font-size: 12px; height: 12px; background-color: #eee;}.chose-container .chose-drop { width: 195px; position: absolute; border: 1px solid #eee; z-index: 1000; background-color: #fff;}.chose-container .chose-search input[type='text'] { margin: 0; padding-left: 12px; width: 100%; height: 30px; border: 1px solid #ccc; float: none;}.chose-container .chose-result { max-height: 370px; overflow-y: scroll; overflow-x: hidden;}.chose-container .chose-result li { padding: 5px 12px; list-style-type: none;}.chose-container .chose-result li:hover { background-color: #e1e2e7;}

1.3 usage and effect

<Select ngc-select-search class = "common-select" ng-model = "aa. B "ng-options =" obj. countryId as obj. countryCnName for obj in vm. countries "name =" country "> <option value =" "> select </option> </select>

2. Detailed Description

The key point in the program is the parseOptions function, that is, question 1 in the previous analysis. ParseOptions is implemented by referring to the ng-options source code. It was originally intended to return an object that contains the data source, but during debugging, it is found that the data in the returned object of this function in the post function is null and the watch is not available. Therefore, use scope instead. options to store data.

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.