Material: mdDatepicker calendar opens up to wrong view

Created on 15 Dec 2016  路  31Comments  路  Source: angular/material

Actual Behavior:

  • What is the issue? * When I click on the datepicker, the calendar view shows the wrong month.
  • What is the expected behavior? It should open up to the currently selected date or the current date.

CodePen (or steps to reproduce the issue): *

Angular Versions: *

  • Angular Version: 1.5.9
  • Angular Material Version: 1.1.1

Additional Information:

  • Browser Type: * Chrome
  • Browser Version: * 55
  • OS: * Ubuntu 12.04
  • Stack Traces: N/A

I should note that this problem doesn't occur in OS X. It also only occurs on the Angular Material Demo page, but works fine in the CodePen.

- Lots of Comments urgent Pull Request fixed

Most helpful comment

I submitted a pull request that should fix the issue. Please try the below CodePens below to see if it fixes it for you.

CodePens:

All 31 comments

I see the same problem with Angular Material 1.0.6. It actually scrolls to April 2017 for me.

I have created a plnkr with a similiar problem. md-datepicker doesn't even render.

  • Angular Version: 1.6.0
  • Angular Material Version: 1.1.1
  • Google Chrome Version: 54

https://plnkr.co/edit/4YBK4Eb8LVNeQbH5wIac

I have this problem with:

  • Angular 1.5.9
  • Angular Material 1.1.1
  • Chrome 55
  • OS: macOS 10.12.1

Confirming same problem:

  • Angular 1.5.8
  • Angular Material 1.1.1
  • Chrome 55.0.2883.87 (64-bit)
  • Kubuntu 16.04.1 LTS

Note that this issue does not seem to occur in Firefox. I have not tested in other browsers.

Steps to reproduce on the demo page (https://material.angularjs.org/latest/demo/datepicker):

  • Open first datepicker, note the start date is correct
  • Click <> to view code
  • Click same datepicker, note the start date is not correct

Same issue with:

Angular: 1.5.8
Material: 1.1.0
Browser: Chrome 55.0.2883.95 (64-bits)
Mac OS X El Capitan 10.11.6

Same issue with:

Angular: 1.5.8
Material: 1.1.1
Browser: Chrome 55.0.2883.87
OS: Windows 10

Adding:
How far ahead it scrolls appears to be related with it's position on the page. The further down on the page the datepicker is, more months past the selected date it will scroll

Confirming same issue:

Angular. 1.5.10
Material: 1.1.1
Browser: Chrome 56.0.2924.28 beta (64-bit)
OS: Windows 10

If I resize the browser window or scroll the md-content a little bit the issue disappears.

Has anyone been able to fix this problem?

I submitted a pull request that should fix the issue. Please try the below CodePens below to see if it fixes it for you.

CodePens:

@ppham27 Your patch seems to work with 1.1.1, but not with 1.0.6.

I'm not expecting to make it work with that old of a version, but letting people know that if they take only his change in their version, it might not work.

Same issue (version 1.1.1 - before fix):

  • Angular 1.5.5
  • Angular Material 1.1.1
  • Chrome 55.0.2883.87
  • OS: Windows 10

Codepen: http://codepen.io/czesiu/pen/dNpdWO

I tired to fix this and for me works commenting this line: https://github.com/angular/material/blob/master/src/components/virtualRepeat/virtual-repeater.js#L357

EDIT: @ppham27 fix also works for me

Any patch release soon? Or otherwise, a pointer on how we can point to master and get the latest code using npm is appreciated

EDIT: looks like PR not merged yet https://github.com/angular/material/pull/10177

@ernsheong With NPM, just update your package.json to specify angular-material#master. That should grab the latest.

This is ~a bit~ very gross, but while we wait for the PR to be merged, I've done the following

angular.module("material.components.virtualRepeat")._invokeQueue[1][2][1]().controller.prototype.virtualRepeatUpdate_ = function (items, oldItems) {
        this.isVirtualRepeatUpdating_ = true;

        var itemsLength = items && items.length || 0;
        var lengthChanged = false;

        // If the number of items shrank, keep the scroll position.
        if (this.items && itemsLength < this.items.length && this.container.getScrollOffset() !== 0) {
            this.items = items;
            var previousScrollOffset = this.container.getScrollOffset();
            this.container.resetScroll();
            this.container.scrollTo(previousScrollOffset);
        }

        if (itemsLength !== this.itemsLength) {
            lengthChanged = true;
            this.itemsLength = itemsLength;
        }

        this.items = items;
        if (items !== oldItems || lengthChanged) {
            this.updateIndexes_();
        }

        this.parentNode = this.$element[0].parentNode;

        if (lengthChanged) {
            this.container.setScrollSize(itemsLength * this.itemSize);
        }

        var cleanupFirstRender = false, firstRenderStartIndex;
        if (this.isFirstRender) {
            cleanupFirstRender = true;
            this.isFirstRender = false;
            firstRenderStartIndex = this.$attrs.mdStartIndex ?
                this.$scope.$eval(this.$attrs.mdStartIndex) :

                this.container.topIndex;
            this.container.scrollToIndex(firstRenderStartIndex);
        }


        // Detach and pool any blocks that are no longer in the viewport.
        Object.keys(this.blocks).forEach(function (blockIndex) {
            var index = parseInt(blockIndex, 10);
            if (index < this.newStartIndex || index >= this.newEndIndex) {
                this.poolBlock_(index);
            }
        }, this);

        // Add needed blocks.
        // For performance reasons, temporarily block browser url checks as we digest
        // the restored block scopes ($$checkUrlChange reads window.location to
        // check for changes and trigger route change, etc, which we don't need when
        // trying to scroll at 60fps).
        this.$browser.$$checkUrlChange = angular.noop;

        var i, block,
            newStartBlocks = [],
            newEndBlocks = [];

        // Collect blocks at the top.
        for (i = this.newStartIndex; i < this.newEndIndex && this.blocks[i] == null; i++) {
            block = this.getBlock_(i);
            this.updateBlock_(block, i);
            newStartBlocks.push(block);
        }

        // Update blocks that are already rendered.
        for (; this.blocks[i] != null; i++) {
            this.updateBlock_(this.blocks[i], i);
        }
        var maxIndex = i - 1;

        // Collect blocks at the end.
        for (; i < this.newEndIndex; i++) {
            block = this.getBlock_(i);
            this.updateBlock_(block, i);
            newEndBlocks.push(block);
        }

        // Attach collected blocks to the document.
        if (newStartBlocks.length) {
            this.parentNode.insertBefore(
                this.domFragmentFromBlocks_(newStartBlocks),
                this.$element[0].nextSibling);
        }
        if (newEndBlocks.length) {
            this.parentNode.insertBefore(
                this.domFragmentFromBlocks_(newEndBlocks),
                this.blocks[maxIndex] && this.blocks[maxIndex].element[0].nextSibling);
        }


        if (cleanupFirstRender) {
            this.container.scrollToIndex(firstRenderStartIndex);
        }


        // Restore $$checkUrlChange.
        this.$browser.$$checkUrlChange = this.browserCheckUrlChange;

        this.startIndex = this.newStartIndex;
        this.endIndex = this.newEndIndex;

        this.isVirtualRepeatUpdating_ = false;
    };

did we get this fixed yet ? Please let me know, if there is a quick way around this ?

This is not the best solution but a quick fix, just reseting the scroller to 0 to keep the top of the scroll in hideVerticalScrollbar function:

CalendarCtrl.prototype.hideVerticalScrollbar = function(childCtrl) {
...
...
var scroller = childCtrl.calendarScroller;
scroller.scrollTop = 0;
...
...
};

I have pulled the master code using bower install angular-material#master --save command but I am experiencing same problem and the datepicker is showing 3 months in future upon opening.

Can anyone help me in that ?

In my application, the issue still occurs when the md-min-date is set. When I use md-date-filter instead of the md-min-date it works.

The issue is still occurring in master branch. Can we reopen this @ppham27 ?

I'm seeing this problem on:

Angular: 1.6.0.
Angular Material: 1.1.1.

I'm seeing this problem on:

Angular: 1.6.2.
Angular Material: 1.1.3.

Agreed with @Yaroslav-Pryadunov we are experiencing the same on Angular Material 1.1.3 with Angular 1.6.2. We did have Angular Material 1.1.1 and I upgraded to 1.1.3. with the issue still persisting.

This happens when the min and max dates are set to values greater than a year in both directions. If the min and max are less than a year from the selected date the picker works fine and scrolls to the model's set date on open.

I'm seeing this problem on:

Angular: 1.6.1.
Angular Material: 1.1.3.

@ernsheong Can you provide a Codepen against the master branch that reproduces this? Also, what browser/version are you using?

@topherfangio I think you can observe this behaviour in the Angular Material demo: https://material.angularjs.org/latest/demo/datepicker

Try opening the one that says: "Custom calendar trigger".

@lobo-tuerto: Indeed! Thanks for showing me which one; I hadn't clicked on that one yet :-)

Here's an observation from https://material.angularjs.org/latest/demo/datepicker:

If the body scroll is 0, "Standard" datepicker works just fine:
screen shot 2017-03-23 at 9 57 55 pm

If body scroll is > certain threshold (itemSize?), the "Standard" datepicker scrolls away from selection:
screen shot 2017-03-23 at 9 56 43 pm

In fact, the "Custom calendar trigger" works just fine with >0 body scroll:
screen shot 2017-03-23 at 9 57 00 pm

I've spent hours on a good fix (bad fix being $timeout of the initial scroll) but have yet to find something. Really appreciate if someone who has experience with virtual-repeat/calendar/datepicker can take another look at this.

I'm seeing this problem on:

Angular: 1.6.1.
Angular Material: 1.1.1.

I'm seeing this problem on:

Angular: 1.6.3.
Angular Material: 1.1.3.

Please help us. Thanks

@ekarudianto @QiaoyuanMaxDeng Can you please test this PR from @ernsheong to verify that it fixes your problem?

So will this be update be release with 1.1.5?

Was this page helpful?
0 / 5 - 0 ratings