angularangular7angular-componentskendo-ui-angular2angular-component-life-cycle

Angular 7 getting value of selected date from Kendo UI date picker


My App Component.html has a basic navigation and a date picker, like so...

<div class="container-fluid">
    <div class="row">

<!-- Navigation Removed -->          
        <div class="col-md-2 float-right">
            <kendo-datepicker
                (valueChange)="onChange($event)"
                [(value)]="value">
            </kendo-datepicker>
        </div>
    </div>
</div>
<router-outlet></router-outlet>

The component.ts is set up in the following way:

import { Component, ViewEncapsulation, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-root',
  encapsulation: ViewEncapsulation.None,
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  @Input() value: Date = new Date();
  @Output() dateChanged: EventEmitter<Date> = new EventEmitter<Date>();

  constructor() {}

  public onChange(value: Date): void {
    this.dateChanged.emit(value);
  }
}

I've got some pages that have a grid control calling a service, but the date is currently hard-coded, and this all works fine. I want the ability to refresh the grid data based on the selected date from the above date picker, essentially, I will click on the datapicker, the emitted value will be passed to a method in the component with the grid controller.

Controller with Grid:

import { Component, OnInit, Input } from '@angular/core';
import { GridDataResult, DataStateChangeEvent } from '@progress/kendo-angular-grid';
import { DataSourceRequestState } from '@progress/kendo-data-query';
import { DataService } from '../services/DataService.service';

import { Observable } from 'rxjs/Observable';
import { State } from '@progress/kendo-data-query';

@Component({
  templateUrl: './grid.component.html',
  styleUrls: ['./grid.component.css']
})
export class GridComponent implements OnInit {

  public products: GridDataResult;
  public state: DataSourceRequestState = {
      skip: 0,
      take: 25
  };
  @Input() value: Date = new Date();

  constructor(private dataService: DataService) { }

  ngOnInit() {
     this.dataService.fetch(this.state).subscribe(r => this.products = r);
  }

  public dataStateChange(state: DataStateChangeEvent): void {
    this.state = state;
    this.dataService.fetch(state)
        .subscribe(r => this.products = r);
}

}

Solution

  • You can use Subject to listen changes on your date input.

    First create a date service.

    @Injectable()
    export class DateService {
    
      public chosenDate: Observable<Date>;
      private dateSubject: Subject<Date>;
    
      constructor() {
        this.dateSubject = new Subject<Date>();
        this.chosenDate = this.dateSubject.asObservable();
      }
    
      dateChanged(newDate:Date){
        this.dateSubject.next(newDate);
      }
    
    }
    

    Then in your Grid Controller, inject this service and subscribe to chosen date from service where you need in your component.

    
    constructor(private service: DateService){
    
    
    
    this.service.chosenDate.subscribe((date: Date) => { 
        // do something useful with date
    });
    
    

    and finally on your date field change event, put this code to pass new date to the service

    this.service.dateChanged(date);
    

    Edit: Here I made an example for you, demonstrating the solution. I'm sure you can easilty implement this in your code.

    DEMO