Daan De Deckere
2018-02-12 d40f6d89bf9084e5d03df1aeea8bffd67662f0c0
Add onSubtractTime and onAddTime hooks (#508)

* Add onSubtractTime and onAddTime hooks

* Add tests for onSubtractTime and onAddTime hooks

* Fix mixup in describe blocks

* Give onSubtractTime and onAddTime hooks more logical names onNavigateBack and onNavigateForward
5 files modified
111 ■■■■ changed files
DateTime.d.ts 10 ●●●●● patch | view | raw | blame | history
DateTime.js 31 ●●●●● patch | view | raw | blame | history
README.md 2 ●●●●● patch | view | raw | blame | history
react-datetime.d.ts 10 ●●●●● patch | view | raw | blame | history
test/tests.spec.js 58 ●●●●● patch | view | raw | blame | history
DateTime.d.ts
@@ -99,6 +99,16 @@
         */
        onViewModeChange?: (viewMode: string) => void;
        /*
         Callback trigger when the user navigates to the previous month, year or decade.
         The callback receives the amount and type ('month', 'year') as parameters.
         */
        onNavigateBack?: (amount: number, type: string) => void;
        /*
         Callback trigger when the user navigates to the next month, year or decade.
         The callback receives the amount and type ('month', 'year') as parameters.
         */
        onNavigateForward?: (amount: number, type: string) => void;
        /*
         The default view to display when the picker is shown. ('years', 'months', 'days', 'time')
         */
        viewMode?: ViewMode | number;
DateTime.js
@@ -26,6 +26,8 @@
        onBlur: TYPES.func,
        onChange: TYPES.func,
        onViewModeChange: TYPES.func,
        onNavigateBack: TYPES.func,
        onNavigateForward: TYPES.func,
        locale: TYPES.string,
        utc: TYPES.bool,
        input: TYPES.bool,
@@ -254,26 +256,29 @@
        };
    },
    addTime: function( amount, type, toSelected ) {
        return this.updateTime( 'add', amount, type, toSelected );
    subtractTime: function( amount, type, toSelected ) {
        var me = this;
        return function() {
            me.props.onNavigateBack( amount, type );
            me.updateTime( 'subtract', amount, type, toSelected );
        };
    },
    subtractTime: function( amount, type, toSelected ) {
        return this.updateTime( 'subtract', amount, type, toSelected );
    addTime: function( amount, type, toSelected ) {
        var me = this;
        return function() {
            me.props.onNavigateForward( amount, type );
            me.updateTime( 'add', amount, type, toSelected );
        };
    },
    updateTime: function( op, amount, type, toSelected ) {
        var me = this;
        return function() {
            var update = {},
                date = toSelected ? 'selectedDate' : 'viewDate'
            ;
            date = toSelected ? 'selectedDate' : 'viewDate';
            update[ date ] = me.state[ date ].clone()[ op ]( amount, type );
        update[ date ] = this.state[ date ].clone()[ op ]( amount, type );
            me.setState( update );
        };
        this.setState( update );
    },
    allowedSetTime: ['hours', 'minutes', 'seconds', 'milliseconds'],
@@ -459,6 +464,8 @@
    onBlur: function() {},
    onChange: function() {},
    onViewModeChange: function() {},
    onNavigateBack: function() {},
    onNavigateForward: function() {},
    timeFormat: true,
    timeConstraints: {},
    dateFormat: true,
README.md
@@ -54,6 +54,8 @@
| **onFocus** | `function` | empty function | Callback trigger for when the user opens the datepicker. The callback receives an event of type SyntheticEvent. |
| **onBlur** | `function` | empty function | Callback trigger for when the user clicks outside of the input, simulating a regular onBlur. The callback receives the selected `moment` object as only parameter, if the date in the input is valid. If the date in the input is not valid, the callback returned. |
| **onViewModeChange** | `function` | empty function | Callback trigger when the view mode changes. The callback receives the selected view mode string (`years`, `months`, `days` or `time`) as only parameter.|
| **onNavigateBack** | `function` | empty function | Callback trigger when the user navigates to the previous month, year or decade. The callback receives the amount and type ('month', 'year') as parameters. |
| **onNavigateForward** | `function` | empty function | Callback trigger when the user navigates to the next month, year or decade. The callback receives the amount and type ('month', 'year') as parameters. |
| **viewMode** | `string` or `number` | `'days'` | The default view to display when the picker is shown (`'years'`, `'months'`, `'days'`, `'time'`). |
| **className** | `string` or `string array` | `''` | Extra class name for the outermost markup element. |
| **inputProps** | `object` | `undefined` | Defines additional attributes for the input element of the component. For example: `onClick`, `placeholder`, `disabled`, `required`, `name` and `className` (`className` *sets* the class attribute for the input element). See [Customize the Input Appearance](#customize-the-input-appearance). |
react-datetime.d.ts
@@ -80,6 +80,16 @@
    */
    onViewModeChange?: (viewMode: string) => void;
    /*
      Callback trigger when the user navigates to the previous month, year or decade.
      The callback receives the amount and type ('month', 'year') as parameters.
     */
    onNavigateBack?: (amount: number, type: string) => void;
    /*
      Callback trigger when the user navigates to the next month, year or decade.
      The callback receives the amount and type ('month', 'year') as parameters.
     */
    onNavigateForward?: (amount: number, type: string) => void;
    /*
     The default view to display when the picker is shown. ('years', 'months', 'days', 'time')
     */
    viewMode?: string|number;
test/tests.spec.js
@@ -1087,6 +1087,64 @@
    });
    describe('onNavigateForward', () => {
        it('when moving to next month', () => {
            const component = utils.createDatetime({ onNavigateForward: (amount, type) => {
                expect(amount).toEqual(1);
                expect(type).toEqual('months');
            }});
            utils.clickOnElement(component.find('.rdtNext'));
        });
        it('when moving to next year', () => {
            const component = utils.createDatetime({ viewMode: 'months', onNavigateForward: (amount, type) => {
                expect(amount).toEqual(1);
                expect(type).toEqual('years');
            }});
            utils.clickOnElement(component.find('.rdtNext'));
        });
        it('when moving decade forward', () => {
            const component = utils.createDatetime({ viewMode: 'years', onNavigateForward: (amount, type) => {
                expect(amount).toEqual(10);
                expect(type).toEqual('years');
            }});
            utils.clickOnElement(component.find('.rdtNext'));
        });
    });
    describe('onNavigateBack', () => {
        it('when moving to previous month', () => {
            const component = utils.createDatetime({ onNavigateBack: (amount, type) => {
                expect(amount).toEqual(1);
                expect(type).toEqual('months');
            }});
            utils.clickOnElement(component.find('.rdtPrev'));
        });
        it('when moving to previous year', () => {
            const component = utils.createDatetime({ viewMode: 'months', onNavigateBack: (amount, type) => {
                expect(amount).toEqual(1);
                expect(type).toEqual('years');
            }});
            utils.clickOnElement(component.find('.rdtPrev'));
        });
        it('when moving decade back', () => {
            const component = utils.createDatetime({ viewMode: 'years', onNavigateBack: (amount, type) => {
                expect(amount).toEqual(10);
                expect(type).toEqual('years');
            }});
            utils.clickOnElement(component.find('.rdtPrev'));
        });
    });
    describe('with set value', () => {
        it('date value', () => {
            const date = new Date(2000, 0, 15, 2, 2, 2, 2),