Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(datepicker): directives #2446

Merged
merged 5 commits into from
Aug 17, 2017
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ yarn.lock
npm-debug.log

# ignore build and dist for now
.tmp
/dist
/temp
/demo/dist
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
<pre>{{bsValue}}</pre>

<input type="text"
value="{{ bsValue | date:'yMd'}}"
bsDatepicker [(bsValue)]="bsValue">
<span style="display: inline-block">
<button class="btn btn-success" (click)="dp.toggle()">Date Picker popup</button>
<bs-datepicker #dp [(value)]="bsValue" style="display: block"></bs-datepicker>
<bs-datepicker #dp [(bsValue)]="bsValue" style="display: block"></bs-datepicker>
</span>

<br>
<br>

<pre>{{bsRangeValue}}</pre>

<input type="text"
value="{{ bsRangeValue[0] | date:'yMd'}} - {{ bsRangeValue[1] | date:'yMd'}}"
bsDaterangepicker [(bsValue)]="bsRangeValue">
<span style="display: inline-block">
<button class="btn btn-success" (click)="drp.toggle()">Date Range Picker popup</button>
<bs-daterangepicker #drp [(value)]="bsRangeValue" placement="right" style="display: block"></bs-daterangepicker>
<bs-daterangepicker #drp [(bsValue)]="bsRangeValue" placement="right" style="display: block"></bs-daterangepicker>
</span>

2 changes: 1 addition & 1 deletion demo/src/typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ declare const PR:any;
// declare const global:any;

declare module jasmine {
interface Matchers {
interface Matchers<T> {
toHaveCssClass(expected: any): boolean;
}
}
50 changes: 25 additions & 25 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,29 +77,29 @@
"@angular/platform-browser-dynamic": "^2.4.4",
"@angular/router": "^3.4.4",
"@angular/tsc-wrapped": "0.5.1",
"@types/jasmine": "2.5.41",
"@types/marked": "0.0.28",
"@types/node": "7.0.15",
"@types/webpack": "^2.2.2",
"@types/jasmine": "2.5.53",
"@types/marked": "0.3.0",
"@types/node": "8.0.23",
"@types/webpack": "3.0.9",
"bootstrap": "3.3.7",
"classlist-polyfill": "1.0.3",
"codecov": "2.1.0",
"codelyzer": "3.0.1",
"conventional-changelog-cli": "1.3.1",
"conventional-github-releaser": "1.1.3",
"classlist-polyfill": "1.2.0",
"codecov": "2.3.0",
"codelyzer": "3.1.2",
"conventional-changelog-cli": "1.3.2",
"conventional-github-releaser": "1.1.12",
"core-js": "^2.4.1",
"cpy": "5.0.0",
"cpy": "5.1.0",
"cpy-cli": "1.0.1",
"del-cli": "0.2.1",
"gh-pages": "0.12.0",
"del-cli": "1.1.0",
"gh-pages": "1.0.0",
"gitignore-to-glob": "0.3.0",
"google-code-prettify": "1.0.5",
"html-loader": "0.4.5",
"html-loader": "0.5.1",
"intl": "^1.2.5",
"jasmine": "2.6.0",
"jasmine-core": "2.6.1",
"jasmine": "2.7.0",
"jasmine-core": "2.7.0",
"jasmine-data-provider": "2.2.0",
"jasmine-spec-reporter": "3.2.0",
"jasmine-spec-reporter": "4.2.1",
"karma": "1.7.0",
"karma-chrome-launcher": "^2.0.0",
"karma-cli": "^1.0.1",
Expand All @@ -115,18 +115,18 @@
"ng2-page-scroll": "4.0.0-beta.7",
"ngm-cli": "0.6.1",
"npm-run-all": "4.0.2",
"protractor": "5.1.1",
"protractor": "5.1.2",
"reflect-metadata": "0.1.10",
"require-dir": "0.3.1",
"require-dir": "0.3.2",
"rxjs": "5.4.3",
"ts-helpers": "^1.1.1",
"tslint": "4.5.1",
"tslint-config-valorsoft": "1.2.0",
"typedoc": "0.5.9",
"tslint": "5.6.0",
"tslint-config-valorsoft": "2.1.0",
"typedoc": "0.8.0",
"typescript": "2.4.2",
"wallaby-webpack": "0.0.37",
"webdriver-manager": "12.0.4",
"webpack-bundle-analyzer": "2.8.2",
"zone.js": "0.8.14"
"wallaby-webpack": "0.0.39",
"webdriver-manager": "12.0.6",
"webpack-bundle-analyzer": "2.9.0",
"zone.js": "0.8.16"
}
}
2 changes: 1 addition & 1 deletion scripts/typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ declare const ENV:string;
declare const PR:any;

declare module jasmine {
interface Matchers {
interface Matchers<T> {
toHaveCssClass(expected: any): boolean;
}
}
63 changes: 35 additions & 28 deletions src/component-loader/component-loader.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ export class ComponentLoader<T> {
*/
private triggers: string;

_listenOpts: ListenOptions = {};
_globalListener = Function.prototype;

/**
* Do not use this directly, it should be instanced via
* `ComponentLoadFactory.attach`
Expand Down Expand Up @@ -145,6 +148,9 @@ export class ComponentLoader<T> {
this._componentRef.changeDetectorRef.detectChanges();
this.onShown.emit(this._componentRef.instance);
}

this._registerOutsideClick();

return this._componentRef;
}

Expand Down Expand Up @@ -172,8 +178,10 @@ export class ComponentLoader<T> {

this._contentRef = null;
this._componentRef = null;
this._removeGlobalListener();

this.onHidden.emit();

return this;
}

Expand All @@ -200,36 +208,13 @@ export class ComponentLoader<T> {

public listen(listenOpts: ListenOptions): ComponentLoader<T> {
this.triggers = listenOpts.triggers || this.triggers;
this._listenOpts.outsideClick = listenOpts.outsideClick;
listenOpts.target = listenOpts.target || this._elementRef.nativeElement;

listenOpts.target = listenOpts.target || this._elementRef;
let _removeGlobalListener = Function.prototype;

const hide = () => {
if (listenOpts.hide) {
listenOpts.hide();
} else {
this.hide();
}

_removeGlobalListener();
};

const show = (registerHide: Function) => {
listenOpts.show ? listenOpts.show() : this.show();
// register hide listeners
// register outsideClick
const hide = this._listenOpts.hide = () => listenOpts.hide ? listenOpts.hide() : this.hide();
const show = this._listenOpts.show = (registerHide: Function) => {
listenOpts.show ? listenOpts.show(registerHide) : this.show(registerHide);
registerHide();
if (this._componentRef && this._componentRef.location) {
// why: should run after first event bubble
const target = this._componentRef.location;
setTimeout(() => {
_removeGlobalListener = registerOutsideClick(this._renderer, {
target,
outsideClick: listenOpts.outsideClick,
hide
});
});
}
};

const toggle = (registerHide: Function) => {
Expand All @@ -245,6 +230,28 @@ export class ComponentLoader<T> {
return this;
}

_removeGlobalListener() {
if (this._globalListener) {
this._globalListener();
this._globalListener = null;
}
}

_registerOutsideClick(): void {
if (!this._componentRef || !this._componentRef.location) {
return;
}
// why: should run after first event bubble
const target = this._componentRef.location.nativeElement;
setTimeout(() => {
this._globalListener = registerOutsideClick(this._renderer, {
targets: [target, this._elementRef.nativeElement],
outsideClick: this._listenOpts.outsideClick,
hide: () => this._listenOpts.hide()
});
});
}

public getInnerComponent(): ComponentRef<T> {
return this._innerComponent;
}
Expand Down
5 changes: 2 additions & 3 deletions src/component-loader/listen-options.model.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ElementRef } from '@angular/core';

export interface ListenOptions {
target?: ElementRef | HTMLElement;
target?: HTMLElement;
targets?: HTMLElement[];
triggers?: string;
outsideClick?: boolean;
show?: Function;
Expand Down
37 changes: 27 additions & 10 deletions src/datepicker/bs-datepicker.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import { Subscription } from 'rxjs/Subscription';
import 'rxjs/add/operator/filter';

@Component({
selector: 'bs-datepicker',
selector: 'bs-datepicker,[bsDatepicker]',
exportAs: 'bsDatepicker',
template: ''
template: ' '
})
export class BsDatepickerComponent implements OnInit, OnDestroy {
/**
Expand All @@ -30,6 +30,8 @@ export class BsDatepickerComponent implements OnInit, OnDestroy {
* event names.
*/
@Input() triggers = 'click';

@Input() outsideClick = true;
/**
* A selector specifying the element the popover should be appended to.
* Currently only supports "body".
Expand Down Expand Up @@ -61,8 +63,14 @@ export class BsDatepickerComponent implements OnInit, OnDestroy {
// @Input() config: BsDatePickerOptions;
// configChange: EventEmitter<BsDatePickerOptions> = new EventEmitter();

@Input() value: Date;
@Output() valueChange: EventEmitter<Date> = new EventEmitter();
_bsValue: Date;
@Input()
set bsValue(value: Date) {
this._bsValue = value;
this.bsValueChange.emit(value);
}

@Output() bsValueChange: EventEmitter<Date> = new EventEmitter();

protected subscriptions: Subscription[] = [];

Expand All @@ -79,10 +87,6 @@ export class BsDatepickerComponent implements OnInit, OnDestroy {
// Object.assign(this, _config);
this.onShown = this._datepicker.onShown;
this.onHidden = this._datepicker.onHidden;

this.valueChange
.filter(value => !!value)
.subscribe(value => this.hide());
}

/**
Expand All @@ -101,9 +105,21 @@ export class BsDatepickerComponent implements OnInit, OnDestroy {
.show({placement: this.placement});

// link with datepicker
this._datepickerRef.instance.value = this.value;
// set initial value of picker
this._datepickerRef.instance.value = this._bsValue;

// if date changes from external source (model -> view)
this.bsValueChange.subscribe((value: Date) => {
this._datepickerRef.instance.value = value;
});

// if date changes from picker (view -> model)
this.subscriptions.push(this._datepickerRef.instance
.valueChange.subscribe((value: Date) => this.valueChange.emit(value)));
.valueChange.subscribe((value: Date) => {
if (value === this._bsValue) {return; }
this.bsValueChange.emit(value);
this.hide();
}));
}

/**
Expand All @@ -130,6 +146,7 @@ export class BsDatepickerComponent implements OnInit, OnDestroy {

ngOnInit(): any {
this._datepicker.listen({
outsideClick: this.outsideClick,
triggers: this.triggers,
show: () => this.show()
});
Expand Down
2 changes: 2 additions & 0 deletions src/datepicker/bs-datepicker.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { BsDaterangepickerComponent } from './bs-daterangepicker.component';
import { BsDatepickerComponent } from './bs-datepicker.component';
import { ComponentLoaderFactory } from '../component-loader/component-loader.factory';
import { PositioningService } from '../positioning/positioning.service';
import { BsDatepickerDayDecoratorComponent } from './themes/bs/bs-datepicker-day-decorator.directive';

@NgModule({
imports: [CommonModule],
Expand All @@ -22,6 +23,7 @@ import { PositioningService } from '../positioning/positioning.service';
BsDatepickerViewComponent,
BsDatepickerNavigationViewComponent,
BsDatepickerDayViewComponent,
BsDatepickerDayDecoratorComponent,
BsDatepickerContainerComponent,
BsDaterangepickerContainerComponent,
BsDatepickerComponent,
Expand Down
Loading