From e19149fea1fab7945564ac48735d50e99c062853 Mon Sep 17 00:00:00 2001 From: nathan Date: Wed, 16 Apr 2014 15:01:29 -0700 Subject: [PATCH 1/5] resize the popup list to fit inside the user's browser, scroll the ul --- src/multiselect.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/multiselect.js b/src/multiselect.js index 5585734..21ec55c 100644 --- a/src/multiselect.js +++ b/src/multiselect.js @@ -237,6 +237,16 @@ angular.module('ui.multiselect', []) scope.isVisible = false; + resize = function() { + var $ul = element.find('ul') + , margin = 50 + , top = $ul.position().top + , maxHeight = $(window).innerHeight(); + if (($ul.height() + top) > maxHeight) { + $ul.css({height: (maxHeight - top - margin), overflow: 'scroll'}); + } + } + scope.toggleSelect = function () { if (element.hasClass('open')) { element.removeClass('open'); @@ -244,6 +254,7 @@ angular.module('ui.multiselect', []) } else { element.addClass('open'); $document.bind('click', clickHandler); + resize(); scope.focus(); } }; From 0ad306304e12cea5dcb982e5192d557147d53cf9 Mon Sep 17 00:00:00 2001 From: nathan Date: Wed, 16 Apr 2014 15:20:06 -0700 Subject: [PATCH 2/5] keep the multiselect open until a click event outside the popup --- src/multiselect.js | 45 ++++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/src/multiselect.js b/src/multiselect.js index 21ec55c..8eab01d 100644 --- a/src/multiselect.js +++ b/src/multiselect.js @@ -236,48 +236,43 @@ angular.module('ui.multiselect', []) link: function (scope, element, attrs) { scope.isVisible = false; - - resize = function() { - var $ul = element.find('ul') - , margin = 50 - , top = $ul.position().top - , maxHeight = $(window).innerHeight(); - if (($ul.height() + top) > maxHeight) { - $ul.css({height: (maxHeight - top - margin), overflow: 'scroll'}); - } - } + scope.eventHandlerIsBound = false; scope.toggleSelect = function () { if (element.hasClass('open')) { element.removeClass('open'); - $document.unbind('click', clickHandler); } else { element.addClass('open'); - $document.bind('click', clickHandler); - resize(); + scope.bindEventHandler(); + scope.resize(); scope.focus(); } }; - function clickHandler(event) { - if (elementMatchesAnyInArray(event.target, element.find(event.target.tagName))) + scope.bindEventHandler = function() { + if (scope.eventHandlerIsBound) { return; - element.removeClass('open'); - $document.unbind('click', clickHandler); - scope.$apply(); + } + element.find('ul *').bind('click', function() { + event.stopPropagation(); + }); + scope.eventHandlerIsBound = true; + } + + scope.resize = function() { + var $ul = element.find('ul') + , margin = 50 + , top = $ul.position().top + , maxHeight = $(window).innerHeight(); + if (($ul.height() + top) > maxHeight) { + $ul.css({height: (maxHeight - top - margin), overflow: 'scroll'}); + } } scope.focus = function focus(){ var searchBox = element.find('input')[0]; searchBox.focus(); } - - var elementMatchesAnyInArray = function (element, elementArray) { - for (var i = 0; i < elementArray.length; i++) - if (element == elementArray[i]) - return true; - return false; - } } } }]); From 14de4d7ba1cd50f4671a82a10cbf05eef12a4572 Mon Sep 17 00:00:00 2001 From: nathan Date: Wed, 16 Apr 2014 15:44:26 -0700 Subject: [PATCH 3/5] pass the multiple option to the popup and close the popup in single selection mode after a selection is made --- src/multiselect.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/multiselect.js b/src/multiselect.js index 8eab01d..c4aaa90 100644 --- a/src/multiselect.js +++ b/src/multiselect.js @@ -50,7 +50,7 @@ angular.module('ui.multiselect', []) scope.$destroy(); }); - var popUpEl = angular.element(''); + var popUpEl = angular.element(''); //required validator if (attrs.required || attrs.ngRequired) { @@ -237,6 +237,7 @@ angular.module('ui.multiselect', []) scope.isVisible = false; scope.eventHandlerIsBound = false; + scope.multiple = attrs.multiple ? true : false; scope.toggleSelect = function () { if (element.hasClass('open')) { @@ -253,8 +254,10 @@ angular.module('ui.multiselect', []) if (scope.eventHandlerIsBound) { return; } - element.find('ul *').bind('click', function() { - event.stopPropagation(); + element.find('ul, ul *').bind('click', function(event) { + if (scope.multiple || 'A' != event.target.tagName) { + event.stopPropagation(); + } }); scope.eventHandlerIsBound = true; } From 49420b7aa03feea69621c5e12597da7e78e5ca3a Mon Sep 17 00:00:00 2001 From: nathan Date: Wed, 16 Apr 2014 15:56:12 -0700 Subject: [PATCH 4/5] readme --- README.md | 59 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 18f0ae4..8408a0a 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,55 @@ -angular-multiselect -=================== +# A Native AngularJS multiselect directive -Native AngularJS multiselect directive - Work in progress. Contributions welcome! -Example: http://plnkr.co/edit/LPGYIf?p=preview +#### index.html +```html + + + + + + + -License -======= -The MIT License + +
+ {{selectedCar}} +
+ + + +``` + + +#### app.js +```js +var app = angular.module('plunker', ['ui.multiselect']); + +app.controller('MainCtrl', function($scope) { + $scope.cars = [{id:1, name: 'Audi'}, {id:2, name: 'BMW'}, {id:3, name: 'Honda'}]; + $scope.selectedCar = []; +}); +``` + + +#### After selecting 'Audi' and 'Honda', the model will look like: +``` + $scope.selectedCar = [1, 3]; +``` + + +#### Change options to `car.name for car in cars` for a data model like: +``` + $scope.selectedCar = [{id:1, name: 'Audi'}, {id:3, name: 'Honda'}]; +``` + +#### Changing options to `car.id for car in cars` will change the options labels in the UI: +`'Audi', 'BMW', 'Honda'` -> `'1', '2', '3'` + + +## Example +http://plnkr.co/edit/LPGYIf?p=preview + +## License + +MIT From 87ce487ee6103bb9deb9093fdcf6d8999dc58413 Mon Sep 17 00:00:00 2001 From: nathan Date: Wed, 16 Apr 2014 17:03:05 -0700 Subject: [PATCH 5/5] allow peeps to click on any elements w/in a link tag --- src/multiselect.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/multiselect.js b/src/multiselect.js index c4aaa90..5bac9fb 100644 --- a/src/multiselect.js +++ b/src/multiselect.js @@ -255,9 +255,23 @@ angular.module('ui.multiselect', []) return; } element.find('ul, ul *').bind('click', function(event) { - if (scope.multiple || 'A' != event.target.tagName) { + if ((scope.multiple && 'A' == event.target.tagName) || (!scope.multiple && 'A' != event.target.tagName)) { event.stopPropagation(); } + else { + var inSelection = false + , aTags = element.find('a'); + for (var i = 0; i < aTags.length; i++) { + if ($(event.target).parents('a:first')[0] == aTags[i]) { + inSelection = true; + break; + } + } + if (scope.multiple && inSelection) { + $(event.target).parents('a').click(); + event.stopPropagation(); + } + } }); scope.eventHandlerIsBound = true; }