Skip to content

Commit

Permalink
fix: rework outside click
Browse files Browse the repository at this point in the history
  • Loading branch information
varnastadeus committed Apr 19, 2018
1 parent 812fa24 commit d248545
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 47 deletions.
2 changes: 1 addition & 1 deletion demo/app/examples/custom-templates.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ import { distinctUntilChanged, debounceTime, switchMap } from 'rxjs/operators'
<label>Custom search</label>
---html,true
<ng-select #api [items]="cities" [(ngModel)]="selectedCity" bindLabel="name" bindValue="name">
<ng-select #api [items]="cities" [searchable]="false" [(ngModel)]="selectedCity" bindLabel="name" bindValue="name">
<ng-template ng-header-tmp>
<input style="width: 100%" type="text" (input)="api.filter($event.target.value)" />
</ng-template>
Expand Down
32 changes: 26 additions & 6 deletions src/ng-select/ng-dropdown-panel.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,18 @@ import {
ChangeDetectionStrategy,
AfterContentInit,
OnInit,
OnChanges,
HostListener
OnChanges
} from '@angular/core';

import { NgOption } from './ng-select.types';
import { NgSelectComponent, DropdownPosition } from './ng-select.component';
import { ItemsList } from './items-list';
import { WindowService } from './window.service';
import { VirtualScrollService } from './virtual-scroll.service';
import { fromEventPattern } from 'rxjs/observable/fromEventPattern';
import { DOCUMENT } from '@angular/platform-browser';
import { takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs/Subject';

const TOP_CSS_CLASS = 'ng-select-top';
const BOTTOM_CSS_CLASS = 'ng-select-bottom';
Expand Down Expand Up @@ -67,7 +70,9 @@ export class NgDropdownPanelComponent implements OnInit, OnChanges, OnDestroy, A
@ViewChild('scroll', { read: ElementRef }) scrollElementRef: ElementRef;
@ViewChild('padding', { read: ElementRef }) paddingElementRef: ElementRef;

private readonly _destroy$ = new Subject<void>();
private _selectElement: HTMLElement;
private _document: Document;
private _previousStart: number;
private _previousEnd: number;
private _startupLoop = true;
Expand All @@ -80,6 +85,7 @@ export class NgDropdownPanelComponent implements OnInit, OnChanges, OnDestroy, A

constructor(
@Inject(forwardRef(() => NgSelectComponent)) _ngSelect: NgSelectComponent,
@Inject(DOCUMENT) document: Document,
private _renderer: Renderer2,
private _elementRef: ElementRef,
private _zone: NgZone,
Expand All @@ -88,10 +94,14 @@ export class NgDropdownPanelComponent implements OnInit, OnChanges, OnDestroy, A
) {
this._selectElement = _ngSelect.elementRef.nativeElement;
this._itemsList = _ngSelect.itemsList;
this._document = document;
}

ngOnInit() {
this._handleScroll();
fromEventPattern((handler: any) => this._document.addEventListener('mousedown', handler, true))
.pipe(takeUntil(this._destroy$))
.subscribe(($event) => this._handleOutsideClick($event))
}

ngOnChanges(changes: SimpleChanges) {
Expand All @@ -103,6 +113,8 @@ export class NgDropdownPanelComponent implements OnInit, OnChanges, OnDestroy, A
ngOnDestroy() {
this._disposeDocumentResizeListener();
this._disposeScrollListener();
this._destroy$.next();
this._destroy$.complete();
if (this.appendTo) {
this._renderer.removeChild(this._elementRef.nativeElement.parentNode, this._elementRef.nativeElement);
}
Expand Down Expand Up @@ -151,9 +163,17 @@ export class NgDropdownPanelComponent implements OnInit, OnChanges, OnDestroy, A
el.scrollTop = d.childHeight * (d.itemsLength + 1);
}

@HostListener('mousedown', ['$event'])
handleMousedown($event: MouseEvent) {
$event.preventDefault();
private _handleOutsideClick($event: any) {
if (this._selectElement.contains($event.target)) {
return;
}

const dropdown: HTMLElement = this._elementRef.nativeElement;
if (dropdown.contains($event.target)) {
return;
}

this.outsideClick.emit();
}

private _handleScroll() {
Expand Down Expand Up @@ -338,7 +358,7 @@ export class NgDropdownPanelComponent implements OnInit, OnChanges, OnDestroy, A
resolve();
return;
}
this._zone.runOutsideAngular(() => {
this._zone.runOutsideAngular(() => {
setTimeout(() => ready(resolve), 5);
});
};
Expand Down
10 changes: 6 additions & 4 deletions src/ng-select/ng-select.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1139,12 +1139,14 @@ describe('NgSelectComponent', function () {
select = fixture.componentInstance.select;
});

it('should close dropdown on input blur', fakeAsync(() => {
it('should close dropdown if opened and clicked outside dropdown container', fakeAsync(() => {
triggerKeyDownEvent(getNgSelectElement(fixture), KeyCode.Space);
expect(select.isOpen).toBeTruthy();
select.onInputBlur();
expect(fixture.componentInstance.select.isOpen).toBeTruthy();
document.getElementById('outside').click();
let event = new MouseEvent('mousedown', {bubbles: true});
document.getElementById('outside').dispatchEvent(event);
tickAndDetectChanges(fixture);
expect(select.isOpen).toBeFalsy();
expect(fixture.componentInstance.select.isOpen).toBeFalsy();
}));

it('should prevent dropdown close if clicked on select', fakeAsync(() => {
Expand Down
10 changes: 3 additions & 7 deletions src/ng-select/ng-select.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export class NgSelectComponent implements OnDestroy, OnChanges, AfterViewInit, C

@HostBinding('class.ng-select-opened') isOpen = false;
@HostBinding('class.ng-select-disabled') isDisabled = false;
@HostBinding('class.ng-select-filtered') get filtered() { return !!this.filterValue };
@HostBinding('class.ng-select-filtered') get filtered() { return !!this.filterValue && this.searchable };

itemsList = new ItemsList(this);
viewPortItems: NgOption[] = [];
Expand Down Expand Up @@ -365,7 +365,7 @@ export class NgSelectComponent implements OnDestroy, OnChanges, AfterViewInit, C
this._zone.runOutsideAngular(() => {
this._window.setTimeout(() => {
this.filterInput.nativeElement.focus();
}, 0);
}, 5);
});
}

Expand Down Expand Up @@ -415,9 +415,6 @@ export class NgSelectComponent implements OnDestroy, OnChanges, AfterViewInit, C
}

filter(term: string) {
if (!this.searchable) {
return;
}
this.filterValue = term;
this.open();

Expand All @@ -437,8 +434,7 @@ export class NgSelectComponent implements OnDestroy, OnChanges, AfterViewInit, C
onInputBlur() {
(<HTMLElement>this.elementRef.nativeElement).classList.remove('ng-select-focused');
this.blurEvent.emit(null);
this.close();
if (!this.isDisabled) {
if (!this.isOpen && !this.isDisabled) {
this._onTouched();
}
}
Expand Down
16 changes: 8 additions & 8 deletions src/themes/default.theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,6 @@ $color-selected: #f5faff;
}
}
}
.ng-dropdown-header {
border-bottom: 1px solid #ccc;
padding: 5px 7px;
}
.ng-dropdown-footer {
border-top: 1px solid #ccc;
padding: 5px 7px;
}
}

.ng-dropdown-panel {
Expand Down Expand Up @@ -196,6 +188,14 @@ $color-selected: #f5faff;
}
}
}
.ng-dropdown-header {
border-bottom: 1px solid #ccc;
padding: 5px 7px;
}
.ng-dropdown-footer {
border-top: 1px solid #ccc;
padding: 5px 7px;
}
.ng-dropdown-panel-items {
margin-bottom: 1px;
.ng-optgroup {
Expand Down
35 changes: 14 additions & 21 deletions src/themes/material.theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ $highlight-color: #3f51b5;
line-height: 1.375em;
}
}

&.ng-has-value {
align-items: center;
.ng-value-container {
Expand Down Expand Up @@ -152,18 +151,6 @@ $highlight-color: #3f51b5;
.ng-spinner-zone {
top: 3px;
}
.ng-dropdown-header {
border-bottom: 1px solid rgba(0, 0, 0, .12);
padding: 0 16px;
line-height: 3em;
height: 3em;
}
.ng-dropdown-footer {
border-top: 1px solid rgba(0, 0, 0, .12);
padding: 0 16px;
line-height: 3em;
height: 3em;
}
}

.ng-dropdown-panel {
Expand All @@ -186,28 +173,37 @@ $highlight-color: #3f51b5;
}
}
}

.ng-dropdown-header {
border-bottom: 1px solid rgba(0, 0, 0, .12);
padding: 0 16px;
line-height: 3em;
height: 3em;
}
.ng-dropdown-footer {
border-top: 1px solid rgba(0, 0, 0, .12);
padding: 0 16px;
line-height: 3em;
height: 3em;
}
.ng-dropdown-panel-items {
.ng-optgroup {
user-select: none;
cursor: default;
line-height: 3em;
height: 3em;
padding: 0 16px;

&.ng-option-marked {
background: rgba(0, 0, 0, .04);
color: rgba(0, 0, 0, .87);
}
&.ng-option-disabled {
color: rgba(0,0,0,.54);
color: rgba(0, 0, 0, .54);
}
&.ng-option-selected {
background: rgba(0, 0, 0, .12);
color: $highlight-color;
}
}

.ng-option {
line-height: 3em;
height: 3em;
Expand All @@ -218,8 +214,7 @@ $highlight-color: #3f51b5;
text-align: left;
text-decoration: none;
position: relative;
color: rgba(0,0,0,.87);

color: rgba(0, 0, 0, .87);
&.ng-option-marked {
background: rgba(0, 0, 0, .04);
color: rgba(0, 0, 0, .87);
Expand All @@ -234,7 +229,6 @@ $highlight-color: #3f51b5;
&.ng-option-child {
padding-left: 32px;
}

.ng-tag-label {
padding-right: 5px;
font-size: 80%;
Expand All @@ -243,5 +237,4 @@ $highlight-color: #3f51b5;
}
}
}

}

0 comments on commit d248545

Please sign in to comment.