Reputation: 1371
I have two different datepickers
that I want to close after I choose a date. I keep finding things online about autoclose: true
but I can't figure out how/where to set it. I'm able to choose dates and have the change show in the input and everything, but I want the datepicker
to close immediately upon choosing the first date.
<form class="form-inline">
<div>
<div class="form-group" [ngClass]="{'has-error':!secondForm.controls['startDate'].valid && secondForm.controls['startDate'].touched}">
<label>Start Date:</label>
<input style="width:250px" [value]="getStartDate()" class="form-control" type="text" [formControl]="secondForm.controls['startDate']">
</div>
<div style="display:inline-block">
<ngb-datepicker id="special" *ngIf="startCheck==true;" [(ngModel)]="dt" class="dropdown-toggle" [ngModelOptions]="{standalone: true}"></ngb-datepicker>
</div>
<button type="button" class="btn icon-calendar" (click)="showStartDatePick()"></button>
<div class="form-group" [ngClass]="{'has-error':!secondForm.controls['endDate'].valid && secondForm.controls['endDate'].touched}">
<label>End Date:</label>
<input style="width:250px" [value]="getEndDate()" class="form-control" type="text" [formControl]="secondForm.controls['endDate']">
</div>
<div style="display:inline-block">
<ngb-datepicker id="special" *ngIf="endCheck==true;" [(ngModel)]="dt2" class="dropdown-toggle" [ngModelOptions]="{standalone: true}"></ngb-datepicker>
</div>
<button type="button" class="btn icon-calendar" (click)="showEndDatePick()"></button>
<button type="button" class="btn icon-search" [disabled]="!secondForm.valid"></button>
</div>
</form>
Corresponding Typescript:
import { Component } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
import {NgbDateStruct} from '@ng-bootstrap/ng-bootstrap';
import {DatePipe} from "@angular/common";
@Component({
selector: 'calendar-pick',
styleUrls: ['../app.component.css'],
templateUrl: './calendarpick.component.html',
providers: [DatePipe]
})
export class CalendarPickComponent {
public dt: NgbDateStruct;
public dt2: NgbDateStruct;
public startCheck: boolean = false;
public endCheck: boolean = false;
secondForm : FormGroup;
public constructor(fb: FormBuilder, private datePipe: DatePipe) {
this.secondForm = fb.group({
'startDate' : [this.dt, Validators.required],
'endDate' : [this.dt2, Validators.required]
})
this.secondForm.valueChanges.subscribe( (form: any) => {
console.log('form changed to:', form);
}
);
}
public getStartDate(): void {
let timestamp = this.dt != null ? new Date(this.dt.year, this.dt.month-1, this.dt.day).getTime() : new Date().getTime();
this.secondForm.controls['startDate'].setValue(this.datePipe.transform(timestamp, 'fullDate'));
}
public getEndDate(): void {
let timestamp = this.dt2 != null ? new Date(this.dt2.year, this.dt2.month-1, this.dt2.day).getTime() : new Date().getTime();
this.secondForm.controls['endDate'].setValue(this.datePipe.transform(timestamp, 'fullDate'));
}
public showStartDatePick():void {
if (this.startCheck == false){
this.startCheck = true;
} else {
this.startCheck = false;
}
}
public showEndDatePick():void {
if (this.endCheck == false){
this.endCheck = true;
} else {
this.endCheck = false;
}
}
}
Upvotes: 1
Views: 3419
Reputation: 8335
This can be achieved by attaching a function to fire on ngModelChange
like so:
<ngb-datepicker *ngIf="startCheck;" [(ngModel)]="startDate" (ngModelChange)="showDatePick(0)" class="dropdown-toggle" [ngModelOptions]="{standalone: true}" style="position:absolute; z-index:1"></ngb-datepicker>
This feels a touch hacky to me with the [(ngModel)] and (ngModelChange) but the first is ensuring the two way binding directly and the second is adding a layer of do this thing on change.
To handle it for two pass an argument into showDatePick
and flip the appropriate boolean to false:
public showDatePick(selector):void {
if(selector === 0) {
this.startCheck = !this.startCheck
} else {
this.endCheck = !this.endCheck;
}
}
And with the inputs we're going to get a little clever with our setting so that we can reuse the same code, because if a bit of code is 99% the same there's probably a way to make it all one thing:
<input style="width:250px" [value]="getDate('start')"
class="form-control" type="text" [formControl]="secondForm.controls['startDate']">
And the getDate function:
public getDate(dateName: string) {
let workingDateName = dateName + 'Date';
let timestamp = this[workingDateName] != null ? new Date(this[workingDateName].year, this[workingDateName].month-1, this[workingDateName].day).getTime() : new Date().getTime();
this.secondForm.controls[dateName + 'Date'].setValue(this.datePipe.transform(timestamp, 'fullDate'));
}
Working example to mess with: http://plnkr.co/edit/BtBUvNYeUYFgr1VmACS3?p=preview
Upvotes: 1