added working on dynamic sharing
This commit is contained in:
		
							parent
							
								
									5cc01ded59
								
							
						
					
					
						commit
						5978ac30ff
					
				| @ -632,3 +632,47 @@ h2.ssb-title { | |||||||
| .folder-actions-list li { | .folder-actions-list li { | ||||||
|   padding: 5px 0px; |   padding: 5px 0px; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | multiselect { | ||||||
|  |     display:block; | ||||||
|  | } | ||||||
|  | multiselect .btn { | ||||||
|  |     width: 100%; | ||||||
|  |     background-color: #FFF; | ||||||
|  | } | ||||||
|  | multiselect .btn.error{ | ||||||
|  |     border: 1px solid #da4f49 !important; | ||||||
|  | } | ||||||
|  | multiselect .dropdown-menu { | ||||||
|  |     max-height: 300px; | ||||||
|  |     overflow-y: auto; | ||||||
|  | } | ||||||
|  | multiselect .dropdown-menu { | ||||||
|  |     width: 100%; | ||||||
|  |     box-sizing: border-box; | ||||||
|  |     padding: 2px; | ||||||
|  | } | ||||||
|  | multiselect .dropdown-menu > li > a { | ||||||
|  |     padding: 3px 10px; | ||||||
|  |     cursor:pointer; | ||||||
|  | } | ||||||
|  | .icon-ok:before { | ||||||
|  |   content: "\f00c"; | ||||||
|  |   font-family: FontAwesome; | ||||||
|  |   font-style: normal; | ||||||
|  |   font-weight: normal; | ||||||
|  |   text-decoration: inherit; | ||||||
|  |   color: #000; | ||||||
|  |   font-size: 14px; | ||||||
|  | } | ||||||
|  | .icon-remove:before { | ||||||
|  |   content: "\f00d"; | ||||||
|  |   font-family: FontAwesome; | ||||||
|  |   font-style: normal; | ||||||
|  |   font-weight: normal; | ||||||
|  |   text-decoration: inherit; | ||||||
|  |   color: #000; | ||||||
|  |   font-size: 14px; | ||||||
|  | } | ||||||
|  | |||||||
| @ -34,6 +34,7 @@ | |||||||
|     <script src="/js/lib/angular/angular-local-storage.js" charset="utf-8"></script> |     <script src="/js/lib/angular/angular-local-storage.js" charset="utf-8"></script> | ||||||
|     <script src="/js/lib/angular/angular-ui-router.min.js" charset="utf-8"></script> |     <script src="/js/lib/angular/angular-ui-router.min.js" charset="utf-8"></script> | ||||||
|     <script src="/js/lib/angular/angucomplete-alt.min.js" charset="utf-8"></script> |     <script src="/js/lib/angular/angucomplete-alt.min.js" charset="utf-8"></script> | ||||||
|  |     <script src="/js/lib/angular/multiselect-dropdown.js" charset="utf-8"></script> | ||||||
|     <script src="/js/lib/ez-file-tree/ez-file-tree.min.js" charset="utf-8"></script> |     <script src="/js/lib/ez-file-tree/ez-file-tree.min.js" charset="utf-8"></script> | ||||||
|     <script src="/js/lib/ez-file-tree/ez-object2array.min.js" charset="utf-8"></script> |     <script src="/js/lib/ez-file-tree/ez-object2array.min.js" charset="utf-8"></script> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ | |||||||
| var angular = window.angular; | var angular = window.angular; | ||||||
| var OAUTH3 = window.OAUTH3; | var OAUTH3 = window.OAUTH3; | ||||||
| 
 | 
 | ||||||
| var app = window.app = angular.module('launchpad', ['oauth3.org', 'ui.router', 'LocalStorageModule', 'angucomplete-alt', 'ez.fileTree']); | var app = window.app = angular.module('launchpad', ['oauth3.org', 'ui.router', 'LocalStorageModule', 'angucomplete-alt', 'ez.fileTree', 'ui.multiselect']); | ||||||
| 
 | 
 | ||||||
| app.directive('daplieFileChange', function () { | app.directive('daplieFileChange', function () { | ||||||
|   return { |   return { | ||||||
|  | |||||||
| @ -523,6 +523,12 @@ app.controller('websiteCtrl', [ | |||||||
| 
 | 
 | ||||||
|   vm.Shares = {}; |   vm.Shares = {}; | ||||||
|   vm.Shares.invite = function (r) { |   vm.Shares.invite = function (r) { | ||||||
|  |     if (vm.copiedShareMode === undefined) { | ||||||
|  |       r.shareMode = ''; | ||||||
|  |     } else { | ||||||
|  |       r.shareMode = vm.copiedShareMode; | ||||||
|  |     } | ||||||
|  |     r.sharePath = vm.autoPopulateWebPath; | ||||||
|     var pkg = Auth.oauth3.pkg('www@daplie.com'); |     var pkg = Auth.oauth3.pkg('www@daplie.com'); | ||||||
|     return pkg.invite({ |     return pkg.invite({ | ||||||
|       comment: r.shareEmail |       comment: r.shareEmail | ||||||
| @ -652,6 +658,22 @@ app.controller('websiteCtrl', [ | |||||||
|     } |     } | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|  |   $scope.$watch('selectedAccess', function (selectedAccess) { | ||||||
|  |     if (selectedAccess.length !== 0) { | ||||||
|  |       vm.accessLevelArry = []; | ||||||
|  |       vm.prettyAccessArray = []; | ||||||
|  |       selectedAccess.forEach(function(letter) { | ||||||
|  |         vm.prettyAccessArray.push(letter.name); | ||||||
|  |         vm.accessLevelArry.push(letter.value); | ||||||
|  |       }); | ||||||
|  |       vm.prettyShareMode = vm.prettyAccessArray.join(", "); | ||||||
|  |       vm.copiedShareMode = vm.accessLevelArry.join(","); | ||||||
|  |     } | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   $scope.selectedAccess = []; | ||||||
|  |   $scope.accessLevel = [{ name: 'Read', value: 'r' }, { name: 'Write', value: 'w' }, { name: 'Invite', value: 'x' }]; | ||||||
|  | 
 | ||||||
|   $scope.localDomainSearch = function(str, domain) { |   $scope.localDomainSearch = function(str, domain) { | ||||||
|     var matches = []; |     var matches = []; | ||||||
|     domain.forEach(function(domain) { |     domain.forEach(function(domain) { | ||||||
| @ -695,6 +717,7 @@ app.controller('websiteCtrl', [ | |||||||
|       vm.displayFileTree = false; |       vm.displayFileTree = false; | ||||||
|       vm.websiteTiles = false; |       vm.websiteTiles = false; | ||||||
|       vm.showBackBtn = false; |       vm.showBackBtn = false; | ||||||
|  |       vm.autoPopulateWebPath = ''; | ||||||
|     }, 150); |     }, 150); | ||||||
|   }; |   }; | ||||||
| }]); | }]); | ||||||
| @ -744,5 +767,5 @@ app.filter('stringify', function() { | |||||||
| app.filter('capitalize', function() { | app.filter('capitalize', function() { | ||||||
|     return function(input) { |     return function(input) { | ||||||
|       return (!!input) ? input.charAt(0).toUpperCase() + input.substr(1).toLowerCase() : ''; |       return (!!input) ? input.charAt(0).toUpperCase() + input.substr(1).toLowerCase() : ''; | ||||||
|     } |     }; | ||||||
| }); | }); | ||||||
|  | |||||||
							
								
								
									
										262
									
								
								js/lib/angular/multiselect-dropdown.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										262
									
								
								js/lib/angular/multiselect-dropdown.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,262 @@ | |||||||
|  | angular.module('ui.multiselect', []) | ||||||
|  | 
 | ||||||
|  | //from bootstrap-ui typeahead parser
 | ||||||
|  | .factory('optionParser', ['$parse', function ($parse) { | ||||||
|  | 
 | ||||||
|  |   var TYPEAHEAD_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+(.*)$/; | ||||||
|  | 
 | ||||||
|  |   return { | ||||||
|  |     parse: function (input) { | ||||||
|  | 
 | ||||||
|  |       var match = input.match(TYPEAHEAD_REGEXP), modelMapper, viewMapper, source; | ||||||
|  |       if (!match) { | ||||||
|  |         throw new Error( | ||||||
|  |           "Expected typeahead specification in form of '_modelValue_ (as _label_)? for _item_ in _collection_'" + | ||||||
|  |           " but got '" + input + "'."); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return { | ||||||
|  |           itemName: match[3], | ||||||
|  |           source: $parse(match[4]), | ||||||
|  |           viewMapper: $parse(match[2] || match[1]), | ||||||
|  |           modelMapper: $parse(match[1]) | ||||||
|  |         }; | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |   }]) | ||||||
|  | 
 | ||||||
|  |   .directive('multiselect', ['$parse', '$document', '$compile', 'optionParser', | ||||||
|  | 
 | ||||||
|  |   function ($parse, $document, $compile, optionParser) { | ||||||
|  |     return { | ||||||
|  |       restrict: 'E', | ||||||
|  |       require: 'ngModel', | ||||||
|  |       link: function (originalScope, element, attrs, modelCtrl) { | ||||||
|  | 
 | ||||||
|  |         var exp = attrs.options, | ||||||
|  |         parsedResult = optionParser.parse(exp), | ||||||
|  |         isMultiple = attrs.multiple ? true : false, | ||||||
|  |         required = false, | ||||||
|  |         scope = originalScope.$new(), | ||||||
|  |         changeHandler = attrs.change || anguler.noop; | ||||||
|  | 
 | ||||||
|  |         scope.items = []; | ||||||
|  |         scope.header = 'Select'; | ||||||
|  |         scope.multiple = isMultiple; | ||||||
|  |         scope.disabled = false; | ||||||
|  | 
 | ||||||
|  |         originalScope.$on('$destroy', function () { | ||||||
|  |           scope.$destroy(); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         var popUpEl = angular.element('<multiselect-popup></multiselect-popup>'); | ||||||
|  | 
 | ||||||
|  |         //required validator
 | ||||||
|  |         if (attrs.required || attrs.ngRequired) { | ||||||
|  |           required = true; | ||||||
|  |         } | ||||||
|  |         attrs.$observe('required', function(newVal) { | ||||||
|  |           required = newVal; | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         //watch disabled state
 | ||||||
|  |         scope.$watch(function () { | ||||||
|  |           return $parse(attrs.disabled)(originalScope); | ||||||
|  |         }, function (newVal) { | ||||||
|  |           scope.disabled = newVal; | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         //watch single/multiple state for dynamically change single to multiple
 | ||||||
|  |         scope.$watch(function () { | ||||||
|  |           return $parse(attrs.multiple)(originalScope); | ||||||
|  |         }, function (newVal) { | ||||||
|  |           isMultiple = newVal || false; | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         //watch option changes for options that are populated dynamically
 | ||||||
|  |         scope.$watch(function () { | ||||||
|  |           return parsedResult.source(originalScope); | ||||||
|  |         }, function (newVal) { | ||||||
|  |           if (angular.isDefined(newVal)) | ||||||
|  |           parseModel(); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         //watch model change
 | ||||||
|  |         scope.$watch(function () { | ||||||
|  |           return modelCtrl.$modelValue; | ||||||
|  |         }, function (newVal, oldVal) { | ||||||
|  |           //when directive initialize, newVal usually undefined. Also, if model value already set in the controller
 | ||||||
|  |           //for preselected list then we need to mark checked in our scope item. But we don't want to do this every time
 | ||||||
|  |           //model changes. We need to do this only if it is done outside directive scope, from controller, for example.
 | ||||||
|  |           if (angular.isDefined(newVal)) { | ||||||
|  |             markChecked(newVal); | ||||||
|  |             scope.$eval(changeHandler); | ||||||
|  |           } | ||||||
|  |           getHeaderText(); | ||||||
|  |           modelCtrl.$setValidity('required', scope.valid()); | ||||||
|  |         }, true); | ||||||
|  | 
 | ||||||
|  |         function parseModel() { | ||||||
|  |           scope.items.length = 0; | ||||||
|  |           var model = parsedResult.source(originalScope); | ||||||
|  |           for (var i = 0; i < model.length; i++) { | ||||||
|  |             var local = {}; | ||||||
|  |             local[parsedResult.itemName] = model[i]; | ||||||
|  |             scope.items.push({ | ||||||
|  |               label: parsedResult.viewMapper(local), | ||||||
|  |               model: model[i], | ||||||
|  |               checked: false | ||||||
|  |             }); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         parseModel(); | ||||||
|  | 
 | ||||||
|  |         element.append($compile(popUpEl)(scope)); | ||||||
|  | 
 | ||||||
|  |         function getHeaderText() { | ||||||
|  |           var edit = "edit"; | ||||||
|  |           if (!modelCtrl.$modelValue || !modelCtrl.$modelValue.length) return scope.header = 'Can ' + edit; | ||||||
|  |           if (isMultiple) { | ||||||
|  |             edit = ''; | ||||||
|  |             var accessLevelArray = []; | ||||||
|  |             modelCtrl.$modelValue.forEach(function(level) { | ||||||
|  |               accessLevelArray.push(level.name); | ||||||
|  |             }); | ||||||
|  |             scope.header = "Can " + accessLevelArray.join(', '); | ||||||
|  |           } else { | ||||||
|  |             var local = {}; | ||||||
|  |             local[parsedResult.itemName] = modelCtrl.$modelValue; | ||||||
|  |             scope.header = parsedResult.viewMapper(local); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         scope.valid = function validModel() { | ||||||
|  |           if(!required) return true; | ||||||
|  |           var value = modelCtrl.$modelValue; | ||||||
|  |           return (angular.isArray(value) && value.length > 0) || (!angular.isArray(value) && value != null); | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         function selectSingle(item) { | ||||||
|  |           if (item.checked) { | ||||||
|  |             scope.uncheckAll(); | ||||||
|  |           } else { | ||||||
|  |             scope.uncheckAll(); | ||||||
|  |             item.checked = !item.checked; | ||||||
|  |           } | ||||||
|  |           setModelValue(false); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         function selectMultiple(item) { | ||||||
|  |           item.checked = !item.checked; | ||||||
|  |           setModelValue(true); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         function setModelValue(isMultiple) { | ||||||
|  |           var value; | ||||||
|  | 
 | ||||||
|  |           if (isMultiple) { | ||||||
|  |             value = []; | ||||||
|  |             angular.forEach(scope.items, function (item) { | ||||||
|  |               if (item.checked) value.push(item.model); | ||||||
|  |             }) | ||||||
|  |           } else { | ||||||
|  |             angular.forEach(scope.items, function (item) { | ||||||
|  |               if (item.checked) { | ||||||
|  |                 value = item.model; | ||||||
|  |                 return false; | ||||||
|  |               } | ||||||
|  |             }) | ||||||
|  |           } | ||||||
|  |           modelCtrl.$setViewValue(value); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         function markChecked(newVal) { | ||||||
|  |           if (!angular.isArray(newVal)) { | ||||||
|  |             angular.forEach(scope.items, function (item) { | ||||||
|  |               if (angular.equals(item.model, newVal)) { | ||||||
|  |                 item.checked = true; | ||||||
|  |                 return false; | ||||||
|  |               } | ||||||
|  |             }); | ||||||
|  |           } else { | ||||||
|  |             angular.forEach(newVal, function (i) { | ||||||
|  |               angular.forEach(scope.items, function (item) { | ||||||
|  |                 if (angular.equals(item.model, i)) { | ||||||
|  |                   item.checked = true; | ||||||
|  |                 } | ||||||
|  |               }); | ||||||
|  |             }); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         scope.checkAll = function () { | ||||||
|  |           if (!isMultiple) return; | ||||||
|  |           angular.forEach(scope.items, function (item) { | ||||||
|  |             item.checked = true; | ||||||
|  |           }); | ||||||
|  |           setModelValue(true); | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         scope.uncheckAll = function () { | ||||||
|  |           angular.forEach(scope.items, function (item) { | ||||||
|  |             item.checked = false; | ||||||
|  |           }); | ||||||
|  |           setModelValue(true); | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         scope.select = function (item) { | ||||||
|  |           if (isMultiple === false) { | ||||||
|  |             selectSingle(item); | ||||||
|  |             scope.toggleSelect(); | ||||||
|  |           } else { | ||||||
|  |             selectMultiple(item); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |   }]) | ||||||
|  | 
 | ||||||
|  |   .directive('multiselectPopup', ['$document', function ($document) { | ||||||
|  |     return { | ||||||
|  |       restrict: 'E', | ||||||
|  |       scope: false, | ||||||
|  |       replace: true, | ||||||
|  |       templateUrl: 'templates/widgets/share-access-multiselect.html', | ||||||
|  |       link: function (scope, element, attrs) { | ||||||
|  | 
 | ||||||
|  |         scope.isVisible = false; | ||||||
|  | 
 | ||||||
|  |         scope.toggleSelect = function () { | ||||||
|  |           if (element.hasClass('open')) { | ||||||
|  |             element.removeClass('open'); | ||||||
|  |             $document.unbind('click', clickHandler); | ||||||
|  |           } else { | ||||||
|  |             element.addClass('open'); | ||||||
|  |             scope.focus(); | ||||||
|  |             $document.bind('click', clickHandler); | ||||||
|  |           } | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         function clickHandler(event) { | ||||||
|  |           if (elementMatchesAnyInArray(event.target, element.find(event.target.tagName))) | ||||||
|  |           return; | ||||||
|  |           element.removeClass('open'); | ||||||
|  |           $document.unbind('click', clickHandler); | ||||||
|  |           scope.$digest(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         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; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }]); | ||||||
| @ -191,18 +191,20 @@ | |||||||
|           </div> |           </div> | ||||||
|           <div ng-show="vm.showInviteContainer"> |           <div ng-show="vm.showInviteContainer"> | ||||||
|             <h1><i class="fa fa-folder"></i> Name</h1> |             <h1><i class="fa fa-folder"></i> Name</h1> | ||||||
|             <form class=""> |             <form class="form-horizontal"> | ||||||
|  | 
 | ||||||
|               <div class="form-group"> |               <div class="form-group"> | ||||||
|                 <label for="">To:</label> |                 <label class="col-md-1 control-label" for="">To:</label> | ||||||
|                 <input type="text" ng-model="r.shareEmail" class="form-control" placeholder="ex: john@example.com" /> |                 <div class="col-md-10"> | ||||||
|               </div> |                   <input type="text" ng-model="r.shareEmail" class="form-control" placeholder="ex: john@example.com" /> | ||||||
|               <div class="form-group"> |                   <input type="hidden" ng-model="vm.autoPopulateWebPath" class="form-control" placeholder="/" disabled /> | ||||||
|                 <!-- WORKING <input type="text" ng-model="r.sharePath" class="form-control" placeholder="/" /> --> |                 </div> | ||||||
|                 <input type="text" ng-model="vm.autoPopulateWebPath" class="form-control" placeholder="/" /> |  | ||||||
|               </div> |  | ||||||
|               <div class="form-group"> |  | ||||||
|                 <input type="text" ng-model="r.shareMode" class="form-control" placeholder="rwx (read, write, invite)" /> |  | ||||||
|               </div> |               </div> | ||||||
|  |               <multiselect class="input-xlarge" multiple="true" | ||||||
|  |                   ng-model="selectedAccess" | ||||||
|  |                   options="c.name for c in accessLevel" | ||||||
|  |                   change="selected()"> | ||||||
|  |               </multiselect> | ||||||
|               <button type="submit" class="btn btn-success" ng-click="vm.Shares.invite(r)">Invite</button> |               <button type="submit" class="btn btn-success" ng-click="vm.Shares.invite(r)">Invite</button> | ||||||
|             </form> |             </form> | ||||||
|           </div> |           </div> | ||||||
| @ -217,7 +219,7 @@ | |||||||
|                   <div class="media-body"> |                   <div class="media-body"> | ||||||
|                     <h4 ng-bind="share.comment">friend@email.com</h4> |                     <h4 ng-bind="share.comment">friend@email.com</h4> | ||||||
|                     <p><b>Share Path:</b> <span ng-bind="share.path" class="text-muted">/</span></p> |                     <p><b>Share Path:</b> <span ng-bind="share.path" class="text-muted">/</span></p> | ||||||
|                     <p><b>Actions Allowed:</b> <span ng-bind="share.mode" class="text-muted">rwx</span></p> |                     <p><b>Actions Allowed:</b> <span class="text-muted">{{ vm.prettyShareMode }}</span></p> | ||||||
|                     <p><b>Invite:</b> <em ng-if="share.pending" class="text-muted">pending</em></p> |                     <p><b>Invite:</b> <em ng-if="share.pending" class="text-muted">pending</em></p> | ||||||
|                   </div> |                   </div> | ||||||
|                   <div class="media-right align-self-center"> |                   <div class="media-right align-self-center"> | ||||||
|  | |||||||
							
								
								
									
										20
									
								
								templates/widgets/share-access-multiselect.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								templates/widgets/share-access-multiselect.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | <div class="dropdown"> | ||||||
|  |   <button class="btn" ng-click="toggleSelect()" ng-disabled="disabled" ng-class="{ 'error': !valid() }"> | ||||||
|  |     <span class="pull-left">{{ header }}</span> | ||||||
|  |     <span class="caret pull-right"></span> | ||||||
|  |   </button> | ||||||
|  |   <ul class="dropdown-menu"> | ||||||
|  |     <li class="hidden"> | ||||||
|  |       <input class="input-block-level" type="text" ng-model="searchText.label" autofocus="autofocus" placeholder="Filter" /> | ||||||
|  |     </li> | ||||||
|  |     <li ng-show="multiple" class=""> | ||||||
|  |       <button class="btn-link btn-small" ng-click="checkAll()"><i class="icon-ok"></i> Check all</button> | ||||||
|  |       <button class="btn-link btn-small" ng-click="uncheckAll()"><i class="icon-remove"></i> Uncheck all</button> | ||||||
|  |     </li> | ||||||
|  |     <li role="separator" class="divider"></li> | ||||||
|  |     <li ng-repeat="i in items | filter:searchText"> | ||||||
|  |       <a ng-click="select(i); focus()"> | ||||||
|  |         <i ng-class="{ 'icon-ok': i.checked, 'icon-empty': !i.checked }"></i> {{ i.label }}</a> | ||||||
|  |     </li> | ||||||
|  |   </ul> | ||||||
|  | </div> | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user