Simon Egersand
2017-02-09 64fc6ae90b13637f2c26c36d5f4d5f1d3bf3b9c2
Make component react to UTC or Locale prop updates

The component will now change accordingly when UTC or Locale props are
updated from the outside without having to manually trigger a re-render.
2 files modified
137 ■■■■ changed files
DateTime.js 59 ●●●● patch | view | raw | blame | history
tests/datetime.spec.js 78 ●●●● patch | view | raw | blame | history
DateTime.js
@@ -129,7 +129,7 @@
                date: props.dateFormat || '',
                time: props.timeFormat || ''
            },
            locale = this.localMoment( props.date ).localeData()
            locale = this.localMoment( props.date, null, props ).localeData()
        ;
        if ( formats.date === true ) {
@@ -153,23 +153,53 @@
    componentWillReceiveProps: function( nextProps ) {
        var formats = this.getFormats( nextProps ),
            update = {}
            updatedState = {}
        ;
        if ( nextProps.value !== this.props.value ||
            formats.datetime !== this.getFormats( this.props ).datetime ) {
            update = this.getStateFromProps( nextProps );
            formats.datetime !== this.getFormats( this.props ).datetime ) {
            updatedState = this.getStateFromProps( nextProps );
        }
        if ( update.open === undefined ) {
            update.open = this.state.open;
        if ( updatedState.open === undefined ) {
            updatedState.open = this.state.open;
        }
        if ( nextProps.viewMode !== this.props.viewMode ) {
            update.currentView = nextProps.viewMode;
            updatedState.currentView = nextProps.viewMode;
        }
        this.setState( update );
        if ( nextProps.locale !== this.props.locale ) {
            if ( this.state.viewDate ) {
                var updatedViewDate = this.state.viewDate.clone().locale( nextProps.locale );
                updatedState.viewDate = updatedViewDate;
            }
            if ( this.state.selectedDate ) {
                var updatedSelectedDate = this.state.selectedDate.clone().locale( nextProps.locale );
                updatedState.selectedDate = updatedSelectedDate;
                updatedState.inputValue = updatedSelectedDate.format( formats.datetime );
            }
        }
        if ( nextProps.utc !== this.props.utc ) {
            if ( nextProps.utc ) {
                if ( this.state.viewDate )
                    updatedState.viewDate = this.state.viewDate.clone().utc();
                if ( this.state.selectedDate ) {
                    updatedState.selectedDate = this.state.selectedDate.clone().utc();
                    updatedState.inputValue = updatedState.selectedDate.format( formats.datetime );
                }
            } else {
                if ( this.state.viewDate )
                    updatedState.viewDate = this.state.viewDate.clone().local();
                if ( this.state.selectedDate ) {
                    updatedState.selectedDate = this.state.selectedDate.clone().local();
                    updatedState.inputValue = updatedState.selectedDate.format(formats.datetime);
                }
            }
        }
        this.setState( updatedState );
    },
    onInputChange: function( e ) {
@@ -337,11 +367,12 @@
        }
    },
    localMoment: function( date, format ) {
        var momentFn = this.props.utc ? moment.utc : moment;
        var m = momentFn( date, format, this.props.strictParsing );
        if ( this.props.locale )
            m.locale( this.props.locale );
    localMoment: function( date, format, props ) {
        props = props || this.props;
        var momentFn = props.utc ? moment.utc : moment;
        var m = momentFn( date, format, props.strictParsing );
        if ( props.locale )
            m.locale( props.locale );
        return m;
    },
tests/datetime.spec.js
@@ -156,19 +156,6 @@
        expect(utils.isOpen(component)).toBeTruthy();
    });
    it('dateFormat -> prop changes and value updates accordingly', () => {
        const date = new Date(2000, 0, 15, 2, 2, 2, 2),
            component = utils.createDatetime({
                dateFormat: 'YYYY-MM-DD', timeFormat: false, defaultValue: date
            });
        const valueBefore = utils.getInputValue(component);
        component.setProps({ dateFormat: 'DD.MM.YYYY'});
        const valueAfter = utils.getInputValue(component);
        expect(valueBefore).not.toEqual(valueAfter);
    });
    describe('with custom props', () => {
        it('input=false', () => {
            const component = utils.createDatetime({ input: false });
@@ -642,6 +629,71 @@
                expect(component.find('.rdtCounter').length).toEqual(1);
            });
        });
        describe('being updated and should trigger update', () => {
            it('dateFormat -> value should change format', () => {
                const date = new Date(2000, 0, 15, 2, 2, 2, 2),
                    component = utils.createDatetime({
                        dateFormat: 'YYYY-MM-DD', timeFormat: false, defaultValue: date
                    });
                const valueBefore = utils.getInputValue(component);
                component.setProps({ dateFormat: 'DD.MM.YYYY'});
                const valueAfter = utils.getInputValue(component);
                expect(valueBefore).not.toEqual(valueAfter);
            });
            it('UTC -> value should change format (true->false)', () => {
                const date = new Date(2000, 0, 15, 2, 2, 2, 2),
                    momentDate = moment(date),
                    component = utils.createDatetime({ value: momentDate, utc: true });
                const valueBefore = utils.getInputValue(component);
                component.setProps({ utc: false }, () => {
                    const valueAfter = utils.getInputValue(component);
                    expect(valueBefore).not.toEqual(valueAfter);
                });
            });
            it('UTC -> value should change format (false->true)', () => {
                const date = new Date(2000, 0, 15, 2, 2, 2, 2),
                    momentDate = moment(date),
                    component = utils.createDatetime({ value: momentDate, utc: false });
                const valueBefore = utils.getInputValue(component);
                component.setProps({ utc: true }, () => {
                    const valueAfter = utils.getInputValue(component);
                    expect(valueBefore).not.toEqual(valueAfter);
                });
            });
            it('locale -> picker should change language (viewMode=days)', () => {
                const component = utils.createDatetime({ viewMode: 'days', locale: 'nl' }),
                    weekdaysBefore = component.find('.rdtDays .dow').map((element) =>
                        element.text()
                    );
                component.setProps({ locale: 'sv' });
                const weekdaysAfter = component.find('.rdtDays .dow').map((element) =>
                    element.text()
                );
                expect(weekdaysBefore).not.toEqual(weekdaysAfter);
            });
            it('locale -> picker should change language (viewMode=months)', () => {
                const component = utils.createDatetime({ viewMode: 'months', locale: 'nl' }),
                    monthsBefore = [utils.getNthMonth(component, 2).text(), utils.getNthMonth(component, 4).text()];
                component.setProps({ locale: 'sv' });
                const monthsAfter = [utils.getNthMonth(component, 2).text(), utils.getNthMonth(component, 4).text()];
                expect(monthsBefore).not.toEqual(monthsAfter);
            });
        });
    });
    describe('event listeners', () => {