Created
May 12, 2016 14:15
-
-
Save KerryRitter/6e997d6e89701269572444de059c914c to your computer and use it in GitHub Desktop.
Bootstrap Multi-Select Angular 1.5 Typescript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MultiselectController { | |
public static $inject = ["$timeout", "$scope"]; | |
public allSelectedLabel: string; | |
public options: IMultiselectOption[]; | |
public ngModel: IMultiselectOption[]; | |
private _maxLabelItems: number = 3; | |
private _clickTracker: IMultiselectOption[]; | |
constructor( | |
private _timeoutService: angular.ITimeoutService, | |
scope: angular.IScope) { | |
this.ngModel = []; | |
this.options = []; | |
this.allSelectedLabel = ""; | |
this._clickTracker = []; | |
scope.$watch(() => this.options, () => { | |
this.selectAll(); | |
}); | |
} | |
public getLabel(): string { | |
if (this.ngModel.length === this.options.length) { | |
return this.allSelectedLabel; | |
} | |
if (this.ngModel.length > this._maxLabelItems) { | |
return `${this.ngModel.length} items selected`; | |
} | |
return _.slice(_.map(this.ngModel, "label"), 0, this._maxLabelItems).join(", "); | |
} | |
public isItemSelected(item: IMultiselectOption): boolean { | |
return _.includes(this.ngModel, item); | |
} | |
public selectItem(item: IMultiselectOption) { | |
if (_.includes(this._clickTracker, item)) { | |
this.deselectAll(); | |
this.ngModel.push(item); | |
return; | |
} | |
this._clickTracker.push(item); | |
this._timeoutService(() => { | |
this._clickTracker = _.without(this._clickTracker, item); | |
}, 300); | |
if (this.isItemSelected(item)) { | |
this.ngModel = _.without(this.ngModel, item); | |
if (!this.ngModel.length) { | |
this.selectAll(); | |
} | |
} else { | |
this.ngModel.push(item); | |
} | |
} | |
public selectAll() { | |
this.ngModel = _.clone(this.options); | |
} | |
private deselectAll() { | |
this.ngModel = []; | |
} | |
} | |
export interface IMultiselectOption { | |
label: string; | |
value: any; | |
} | |
var itemStyle = `cursor: pointer; | |
user-select: none; | |
-webkit-touch-callout: none; /* iOS Safari */ | |
-webkit-user-select: none; /* Chrome/Safari/Opera */ | |
-moz-user-select: none; /* Firefox */ | |
-ms-user-select: none; /* Internet Explorer/Edge */`; | |
export class Multiselect implements ng.IComponentOptions { | |
public controller: any = MultiselectController; | |
public bindings: any = { | |
allSelectedLabel: "<", | |
options: "=", | |
ngModel: "=" | |
}; | |
public template: string = ` | |
<div class="dropdown"> | |
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown"> | |
{{$ctrl.getLabel()}} | |
<span class="caret"></span> | |
</button> | |
<ul class="dropdown-menu"> | |
<li style="${itemStyle}" ng-click="$event.stopPropagation(); $ctrl.selectAll();"> | |
<a>Select All</a> | |
</li> | |
<li role="separator" class="divider"></li> | |
<li style="${itemStyle}" | |
ng-repeat="item in $ctrl.options" | |
ng-click="$event.stopPropagation(); $ctrl.selectItem(item);" | |
ng-class="{'active': $ctrl.isItemSelected(item)}"> | |
<a style="user-select: none;"> | |
{{item.label}} | |
<span ng-class="{'glyphicon glyphicon-ok pull-right': $ctrl.isItemSelected(item)}" | |
style="margin-top: 2px;"> | |
</span> | |
</a> | |
</li> | |
</ul> | |
</div>`; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment