23

I have an EditForm in which a Date field is located towards the bottom. When clicking the DatePicker button in Chrome, the form jumps to the top forcing the user to scroll to the bottom again. This is a problem for my users and they don't want to use Internet Explorer (where it works). Is there a way to preserve the scroll position so it doesn't jump to the top of the form? ty

Benny Skogberg
  • 25,542
  • 12
  • 68
  • 163
Michael Colbs
  • 3,919
  • 2
  • 48
  • 96

4 Answers4

21

Might have a slight flicker, but my solution will keep the scroll position of Chrome after you click on calendar icon (better than not having an answer since 2013 ^_^). At the bottom of your aspx page, add following script:

function OnIframeLoadFinish() {
ULSvmd:
    ;
    var picker;    
    if (typeof this.Picker != 'undefined')
        picker = this.Picker;
    if (picker != null && typeof picker.readyState != 'undefined' && picker.readyState != null && picker.readyState == "complete") {
        document.body.scrollLeft = g_scrollLeft;
        document.body.scrollTop = g_scrollTop;
        g_scrollTop = document.getElementById('s4-workspace').scrollTop;
        picker.style.display = "block";
        if (typeof document.frames != 'undefined' && Boolean(document.frames)) {  /* "document.frames" doesn't work on chrome use "window.frames" instead*/
            var frame = document.frames[picker.id];    
            if (frame != null && typeof frame.focus == 'function')
                frame.focus();
        }
        else {
            picker.focus();
        }
    }
    setTimeout(function(){
        document.getElementById('s4-workspace').scrollTop = g_scrollTop;
    }, 1);
}

Hope this can help!

Mahmoud Farahat
  • 57
  • 1
  • 13
Quang San Hai
  • 226
  • 2
  • 2
6

I just wrote up a blogpost with the answer: http://kwizcom.blogspot.ca/2018/05/sharepoint-2013-date-picker-scrolls.html

But here are the details:

The problem occures in the setFocusDatepicker function, like igby said - but didn't mention how we solve it from our current page if we have no code running in an iframe.

Also - the answer by Quang San Hi rely on a timeout, which gives you a slight flicker and delay in the UI.

You can combine both answers to achieve the (almost) perfect solution:

First I will attach to OnIframeLoadFinish in the current page, which will tell me when the iframe is ready. Then I will find the setFocusDate function INSIDE the iframe and override it, adding a code to preserve the workspace scroll position in the current window.

Here is the code:

ExecuteOrDelayUntilScriptLoaded(
function(){
    if(typeof(window.original_OnIframeLoadFinish)!=='function'){
        window.original_OnIframeLoadFinish = window.OnIframeLoadFinish;
        window.OnIframeLoadFinish = function(){
            original_OnIframeLoadFinish.apply(this, arguments);
            window.Picker.contentWindow.original_setFocusDatepicker = window.Picker.contentWindow.setFocusDatepicker;

            window.Picker.contentWindow.setFocusDatepicker = function(){
                workspaceTop = document.getElementById('s4-workspace').scrollTop;
                window.Picker.contentWindow.original_setFocusDatepicker.apply(this, arguments);
                document.getElementById('s4-workspace').scrollTop = workspaceTop;
            }
        }
    }
}, "datepicker.js");

Hope this helps. It is really surprising to learn a bug like this wasn't fixed... I guess I will just include this fix in our forms product for our customers...

Shai Petel
  • 279
  • 3
  • 6
5

The problem is coming from setFocusDatepicker in datepicker.js. The method is calling focus inside calendar iframe which at the end scrolls the window. To make it work you can try to override the method, provided by MS which looks like this:

function setFocusDatepicker(elm) {
if (elm.onfocus == null) {
    if (browseris.ie)
        elm.onfocus = function() {
        ULSvmd:
            ;
            FocusOnDay(true, event);
            return false;
        };
    else
        elm.onfocus = function(evt) {
        ULSvmd:
            ;
            FocusOnDay(true, evt);
            return false;
        };
}
if (elm.onblur == null) {
    if (browseris.ie)
        elm.onblur = function() {
        ULSvmd:
            ;
            FocusOnDay(false, event);
            return false;
        };
    else
        elm.onblur = function(evt) {
        ULSvmd:
            ;
            FocusOnDay(false, evt);
            return false;
        };
}
try {
    elm.focus();
}
catch (exception) { }}

You have to change the end part with focus call, in my case I replaced it with following code:

    try {
    if (browseris.chrome) {
        FocusOnDay(true, { target: elm });// Just to have styling for current day
    }
    else {
        elm.focus();
    }

}
catch (exception) { }

And the tricky part, to apply this "patch" you have following options:

  • edit layouts/iframe.aspx and overwrite js method, but this will removed by CU, SP or other fixes
  • fix the method in datepicker.js and datepicker.debug.js, but again same problems with updates
  • and the sledgehammer: write httpmodule which will render this small piece of javascript :D
igby
  • 51
  • 1
  • 5
1

It seems related to a reported bug, Page scrolls unnecessarily when focusing on input in iframe near bottom of screen, in Chrome.

The bug is reported in SharePoint > SharePoint 2013 - General Discussions and Questions SharePoint page scrolls to top when I enter something in people picker .

emaV
  • 111
  • 2