Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions components/select/off-click.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {Directive, HostListener, Input, OnInit, OnDestroy} from 'angular2/core';

@Directive({
selector: '[offClick]'
})

export class OffClickDirective implements OnInit, OnDestroy {
/* tslint:disable */
@Input('offClick') public offClickHandler: any;
/* tslint:enable */
@HostListener('click', ['$event']) public onClick($event: MouseEvent): void {
$event.stopPropagation();
}

public ngOnInit(): any {
setTimeout(() => {document.addEventListener('click', this.offClickHandler);}, 0);
}

public ngOnDestroy(): any {
document.removeEventListener('click', this.offClickHandler);
}

}
2 changes: 1 addition & 1 deletion components/select/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {SELECT_DIRECTIVES} from 'ng2-select/ng2-select';
```typescript
// class Select
@Component({
selector: 'ng2-select',
selector: 'ng-select',
properties: [
'allowClear',
'placeholder',
Expand Down
54 changes: 19 additions & 35 deletions components/select/select.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import {Component, Input, Output, EventEmitter, ElementRef, OnInit, OnDestroy} from 'angular2/core';
import {Component, Input, Output, EventEmitter, ElementRef, OnInit} from 'angular2/core';
import {SelectItem} from './select-item';
import {HighlightPipe, stripTags} from './select-pipes';
import {OptionsBehavior} from './select-interfaces';
import {escapeRegexp} from './common';
import {OffClickDirective} from './off-click';

let optionsTemplate = `
<ul *ngIf="optionsOpened && options && options.length > 0 && !itemObjects[0].hasChildren()"
<ul *ngIf="optionsOpened && options && options.length > 0 && !firstItemHasChildren"
class="ui-select-choices ui-select-choices-content ui-select-dropdown dropdown-menu">
<li class="ui-select-choices-group">
<div *ngFor="#o of options"
Expand All @@ -20,7 +21,7 @@ let optionsTemplate = `
</li>
</ul>

<ul *ngIf="optionsOpened && options && options.length > 0 && itemObjects[0].hasChildren()"
<ul *ngIf="optionsOpened && options && options.length > 0 && firstItemHasChildren"
class="ui-select-choices ui-select-choices-content ui-select-dropdown dropdown-menu">
<li *ngFor="#c of options; #index=index" class="ui-select-choices-group">
<div class="divider" *ngIf="index > 0"></div>
Expand All @@ -41,18 +42,20 @@ let optionsTemplate = `
`;
@Component({
selector: 'ng-select',
directives: [OffClickDirective],
pipes: [HighlightPipe],
template: `
<div tabindex="0"
*ngIf="multiple === false"
(keyup)="mainClick($event)"
[offClick]="clickedOutside"
class="ui-select-container ui-select-bootstrap dropdown open">
<div [ngClass]="{'ui-disabled': disabled}"></div>
<div class="ui-select-match"
*ngIf="!inputMode">
<span tabindex="-1"
class="btn btn-default btn-secondary form-control ui-select-toggle"
(^click)="matchClick()"
(click)="matchClick($event)"
style="outline: 0;">
<span *ngIf="active.length <= 0" class="ui-select-placeholder text-muted">{{placeholder}}</span>
<span *ngIf="active.length > 0" class="ui-select-match-text pull-left"
Expand Down Expand Up @@ -110,7 +113,7 @@ let optionsTemplate = `
</div>
`
})
export class Select implements OnInit, OnDestroy {
export class Select implements OnInit {
@Input() public allowClear:boolean = false;
@Input() public placeholder:string = '';
@Input() public initData:Array<any> = [];
Expand Down Expand Up @@ -141,7 +144,6 @@ export class Select implements OnInit, OnDestroy {
public activeOption:SelectItem;
public element:ElementRef;

private offSideClickHandler:any;
private inputMode:boolean = false;
private optionsOpened:boolean = false;
private behavior:OptionsBehavior;
Expand All @@ -151,6 +153,7 @@ export class Select implements OnInit, OnDestroy {

public constructor(element:ElementRef) {
this.element = element;
this.clickedOutside = this.clickedOutside.bind(this);
}

public inputEvent(e:any, isUpMode:boolean = false):void {
Expand Down Expand Up @@ -229,21 +232,14 @@ export class Select implements OnInit, OnDestroy {
}

public ngOnInit():any {
this.behavior = this.itemObjects[0].hasChildren() ?
this.behavior = (this.firstItemHasChildren) ?
new ChildrenBehavior(this) : new GenericBehavior(this);
this.offSideClickHandler = this.getOffSideClickHandler(this);
document.addEventListener('click', this.offSideClickHandler);
if (this.initData) {
this.active = this.initData.map((data:any) => new SelectItem(data));
this.data.emit(this.active);
}
}

public ngOnDestroy():any {
document.removeEventListener('click', this.offSideClickHandler);
this.offSideClickHandler = void 0;
}

public remove(item:SelectItem):void {
if (this._disabled === true) {
return;
Expand All @@ -267,6 +263,15 @@ export class Select implements OnInit, OnDestroy {
}
}

public clickedOutside():void {
this.inputMode = false;
this.optionsOpened = false;
}

public get firstItemHasChildren():boolean {
return this.itemObjects[0] && this.itemObjects[0].hasChildren();
}

protected matchClick(e:any):void {
if (this._disabled === true) {
return;
Expand Down Expand Up @@ -337,27 +342,6 @@ export class Select implements OnInit, OnDestroy {
this.optionsOpened = true;
}

private getOffSideClickHandler(context:any):Function {
return function (e:any):void {
if (e.target && e.target.nodeName === 'INPUT'
&& e.target.className && e.target.className.indexOf('ui-select') >= 0) {
return;
}

if (e.srcElement.contains(context.element.nativeElement)
&& e.srcElement && e.srcElement.className &&
e.srcElement.className.indexOf('ui-select') >= 0) {
if (e.target.nodeName !== 'INPUT') {
context.matchClick(void 0);
}
return;
}

context.inputMode = false;
context.optionsOpened = false;
};
}

private hideOptions():void {
this.inputMode = false;
this.optionsOpened = false;
Expand Down