Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save KerryRitter/6e997d6e89701269572444de059c914c to your computer and use it in GitHub Desktop.
Save KerryRitter/6e997d6e89701269572444de059c914c to your computer and use it in GitHub Desktop.
Bootstrap Multi-Select Angular 1.5 Typescript
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