evansmwendwa / ng2-daterangepicker

Usage Demos update in this url >>>
https://codesandbox.io/s/6yr1zm18w3
MIT License
132 stars 88 forks source link

How to reload with update new options #23

Closed taipeiwu closed 7 years ago

taipeiwu commented 7 years ago

I want to change locale's language, so if using ngx-translate with options, ngx-translate get translate is synchronous mode, but ng2-daterangepicker can't get new options.

evansmwendwa commented 7 years ago

I will implement ngOnChanges() on the next release to support change detection in the options. A simple workaround before I get time to do that would be to wrap the directive in another component that implement ngOnChanges() to update the options.

Hopefully fix in the next few days.

SlidEnergy commented 7 years ago

Hello. I have same problem, workaround works for me, but I want to use daterangepicker global settings with asynchronous translate service. My code:

import { Component, OnInit } from "@angular/core";
import { LangService } from "app/services/lang.service";
import { AuthService } from "app/services/auth.service";
import { DaterangepickerConfig } from 'ng2-daterangepicker';
import { TranslateService } from "@ngx-translate/core";
import * as moment from 'moment';
import { Observable } from 'rxjs/Observable';

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

    isLoggedIn: Observable<boolean>;

    constructor(
        private langService: LangService,
        private authService: AuthService,
        private daterangepickerOptions: DaterangepickerConfig,
        private translateService: TranslateService
    ) { 
        this.isLoggedIn = authService.isLoggedIn
    }

    ngOnInit() {
        this.langService.init()

        this.initDaterangepicker();
    }

    initDaterangepicker() {

        this.translateService.get([
            'daterangepicker.today',
            'daterangepicker.last7days',
            'daterangepicker.last14days',
            'daterangepicker.last30days',
            'daterangepicker.thisMonth',
            'daterangepicker.lastMonth',

            'daterangepicker.dateFormat',
            'daterangepicker.apply',
            'daterangepicker.cancel',
            'daterangepicker.from',
            'daterangepicker.to',
            'daterangepicker.custom',
            'daterangepicker.daysOfWeek',
            'daterangepicker.monthNames',
            'daterangepicker.firstDay']
        ).subscribe(
            data => {

            let ranges = [];

            ranges[data['daterangepicker.today']] = [moment(), moment()];
            ranges[data['daterangepicker.last7days']] = [moment().subtract(6, 'days'), moment()];
            ranges[data['daterangepicker.last14days']] = [moment().subtract(13, 'days'), moment()];
            ranges[data['daterangepicker.last30days']] = [moment().subtract(29, 'days'), moment()];
            ranges[data['daterangepicker.thisMonth']] = [moment().startOf('month'), moment().endOf('month')];
            ranges[data['daterangepicker.lastMonth']] = [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')];

            let locale = {
                format: data['daterangepicker.dateFormat'],
                applyLabel: data['daterangepicker.apply'],
                cancelLabel: data['daterangepicker.cancel'],
                fromLabel:data['daterangepicker.from'],
                toLabel: data['daterangepicker.to'],
                customRangeLabel: data['daterangepicker.custom'],
                daysOfWeek: data['daterangepicker.daysOfWeek'].split(" "),
                monthNames: data['daterangepicker.monthNames'].split(" "),
                firstDay: data['daterangepicker.firstDay'],
                separator: " - "
            };

            this.daterangepickerOptions.settings = {
                ranges: ranges,
                locale: locale,
                autoApply: true,
                opens: 'center',
                minDate: moment().subtract(100, 'years'),
                maxDate: moment()
            };
        });
    }
}

Is it possible?

SlidEnergy commented 7 years ago

Before that, I was wrong, this workaround does not work for me. The options are not always applied. Maybe I'm using the wrapper incorrectly.

daterangepicker-wrapper.component.ts

import { Component, OnInit, OnChanges, Input, Output, ViewChild, EventEmitter } from '@angular/core';
import { DaterangePickerComponent } from 'ng2-daterangepicker';

@Component({
    selector: 'app-daterangepicker-wrapper',
    templateUrl: './daterangepicker-wrapper.component.html'
})
export class DaterangepickerWrapperComponent implements OnInit, OnChanges {

    @ViewChild(DaterangePickerComponent)
    private picker: DaterangePickerComponent;

    @Input("options") options: any;

    @Output() dateSelected = new EventEmitter();

    constructor() { }

    ngOnInit() {
    }

    ngOnChanges(changes: any) {
        this.options = changes.options.currentValue;
    }

    selected(e: any) {
        this.dateSelected.emit(e);
    }

    public toggle() {
        this.picker.datePicker.toggle();
    }
}

daterangepicker-wrapper.component.html
<input type="text" daterangepicker 
    (selected)="selected($event)"
    [options]="options"
    style="position: absolute; display: none; left: 0; right: 0; width: 100%;" 
/>
sudosandwich3 commented 7 years ago

Hey, is there any update on this issue? @evansmwendwa

penniath commented 7 years ago

Hi @evansmwendwa, no news about this feature?

evansmwendwa commented 7 years ago

Sorry guys for the delay.

Currently working on this. Should be ready in a day or two

evansmwendwa commented 7 years ago

Released a new version to support change detection. Please test if v2.0.8 fixes this issue

WaveMeUp commented 7 years ago

Hello, I got the same issue with translations. For example, I'm changing language at my LocaleSerivce, and I want to change moment locale too.

I'm using moment.locale(locale), but value (month name in my case) in the daterangepicker input doesn't change. To change it I have to select date again. How can I solve this thing?

SlidEnergy commented 6 years ago

When I change my global options or local settings ngDoCheck fired, but activeRange is undefined. I look for https://github.com/evansmwendwa/ng2-daterangepicker/blob/master/src/app/daterangepicker/daterangepicker.component.ts. ActiveRange is undefined because I do't select any dates manualy, but I set dates in options or setStartDate/setEndDate methods. In this case callback not called.

I have my workaround code:

initDateRangePicker() {
    this.daterangepickerOptions = Object.assign(this.daterangepickerHelperService.getOptionsInstant(), {
        startDate: moment(),
        endDate: moment()
    });

    this.translate.onLangChange.pipe(untilComponentDestroyed(this)).subscribe(() => {
        if (this.daterangepicker) {
            this.daterangepickerOptions = Object.assign(this.daterangepickerHelperService.getOptionsInstant(), {
                startDate: this.daterangepicker.datePicker.startDate,
                endDate: this.daterangepicker.datePicker.endDate
            });
        }
    });
}

We need set dates into options or destroy directive and call ngAfrerViewInit for render new directive and then set dates use setStartDate/setEndDate methods

SlidEnergy commented 6 years ago

I cannot build your project, but i can propose use next code in https://github.com/evansmwendwa/ng2-daterangepicker/blob/master/src/app/daterangepicker/daterangepicker.component.ts:

ngDoCheck() {
        let optionsChanged = this._differ['options'].diff(this.options);
        let settingsChanged = this._differ['settings'].diff(this.config.settings);

        if(optionsChanged || settingsChanged) {
            if (this.datePicker) {
                var start = this.datePicker.startDate;
                var end = this.datePicker.endDate;

                this.render();
                this.attachEvents();

                this.datePicker.setStartDate(start);
                this.datePicker.setEndDate(end);
            }
        }
    }
SlidEnergy commented 6 years ago

Hello, I got the same issue with translations. For example, I'm changing language at my LocaleSerivce, and I want to change moment locale too.

I'm using moment.locale(locale), but value (month name in my case) in the daterangepicker input doesn't change. To change it I have to select date again. How can I solve this thing?

You can use same code like in the moment library https://github.com/dangrossman/daterangepicker/blob/master/daterangepicker.js

this.locale = {
            direction: 'ltr',
            format: moment.localeData().longDateFormat('L'),
            separator: ' - ',
            applyLabel: 'Apply',
            cancelLabel: 'Cancel',
            weekLabel: 'W',
            customRangeLabel: 'Custom Range',
            daysOfWeek: moment.weekdaysMin(),
            monthNames: moment.monthsShort(),
            firstDay: moment.localeData().firstDayOfWeek()
};
SlidEnergy commented 6 years ago

Also if I initialize settings with option property and then I want change period using options it's not working. I need use setStartDate and setEndDate method, but it's not Angular way.

jifrivly commented 3 years ago

Released a new version to support change detection. Please test if v2.0.8 fixes this issue

How to use this feature, I need to update ranges dynamically.