Skip to main content

Search and Top Navigation

#11199 open bug ()

Opened February 24, 2015 02:15AM UTC

Last modified June 27, 2016 10:20PM UTC

Selectmenu throws error after datepicker selected in different UpdatePanel (IE 11)

Reported by: sandygettings Owned by: sandygettings
Priority: minor Milestone: none
Component: ui.selectmenu Version: 1.11.3
Keywords: Cc:
Blocked by: Blocking:
Description

Reduced test case: ​https://jsfiddle.net/h9yec1fc/

See the comment from Akaoni for more details.


original post:

APS.Net web pages implement asynchronous partial-page updates with UpdatePanel controls. When an UpdatePanel is triggered, the DOM elements within the UpdatePanel are reloaded. Other elements on the page are not.

Placing jQuery widgets for datepicker and selectmenu in different UpdatePanels causes a problem. If the user selects a date in the datepicker and triggers an async update, only the datepicker’s UpdatePanel is reloaded. If the user clicks the selectmenu’s button next, it throws an unhelpful JavaScript error:

Unhandled exception at line 12549, column 4 in http://localhost:49339/js/jquery-ui-1.11.3.js
0x80004005 - JavaScript runtime error: Unspecified error.

The code throwing the error is within the selectmenu widget, in the _setSelection function, which is called when the button is clicked. The last line below (selection.addRange) throws the error:

	if ( window.getSelection ) {
		selection = window.getSelection();
		selection.removeAllRanges();
		selection.addRange( this.range ); // Throws error
		...

My hypothesis (or guess, really): The ''this.range'' object references the user’s selected text because the widget wants to restore the text selection after the widget is clicked. The range originally refers to the datepicker’s element, but after the async postback the datepicker’s UpdatePanel is reloaded and the original selection is invalid. So, the addRange function is referencing invalid data and throws the unhelpful error.

This problem was only demonstrated using Internet Explorer 11 64-bit. It was not tested with other browsers. A sample demonstrating the problem is available here: http://adacare.com/TestSelectmenuBomb.aspx

Workaround: When the datepicker selects a date, set the focus to some other DOM element before the postback.

Attachments (0)
Change History (11)

Changed February 24, 2015 02:01PM UTC by scottgonzalez comment:1

owner: → sandygettings
status: newpending

It's not clear to me what's happening in that page. Can you please provide a reduced test case that doesn't use ASP? Here's what I thought might be happening, you can use it as a starting point to provide a proper test case: http://jsbin.com/hifiwuwufa/1/

Changed February 24, 2015 02:25PM UTC by sandygettings comment:2

status: pendingnew

Thanks for looking into this. I know the problem is rather obscure. I've only observed this in an ASP environment (because that's what I'm working on these days) and using IE11. After digging into this for three long, sad days, I've reduced the test case as much as I can. I guess if I understood exactly how ASP processes partial-page updates I could narrow the issue more, but the details are opaque to me.

If you want to see the problem yourself, use the test case provided. Also, use IE11 with script debugging enabled. It should bomb immediately with the error mentioned in the OP. (Sorry, but I'm not following what you were trying to show in your example.)

Changed February 24, 2015 02:27PM UTC by scottgonzalez comment:3

status: newpending

We can't debug ASP pages. I was trying to recreate whatever your page is doing, but if we can't get a properly reduced test case, then we can't work on a fix.

Changed February 24, 2015 02:35PM UTC by sandygettings comment:4

status: pendingnew

No ASP debugging? I have to say that I'm surprised, as Microsoft has embraced jQuery, and it's very common to use jQuery with ASP. Perhaps some kind jQuery contributor with ASP experience will be able to help?

Changed February 24, 2015 02:38PM UTC by scottgonzalez comment:5

resolution: → notabug
status: newclosed

I'll just close this for now. If someone wants to provide a reduced test case that we can work with, then we can reopen.

Changed February 24, 2015 02:49PM UTC by sandygettings comment:6

_comment0: Crap.1424789767412453

I hope you'll reconsider. This is a problem with jQuery in an ASP environment, so reducing ASP out of the test case really isn't productive. There are many, many commercial ASP products that use jQuery, and Microsoft even encourages developers to do so. The test case I've provided is about as simple as it gets for this problem, and I hope some effort can be made to resolve this issue. Just closing the ticket doesn't help.

Changed February 26, 2015 03:28PM UTC by sandygettings comment:7

Scott, I think I understand some of the confusion about the test case. The example I provided was to illustrate the ''behavior'' of the error, not the source code. The ASP source is much simpler, as what you saw rendered in your browser is the cryptic code ''rendered'' by ASP, not the original source. My apologies for misunderstanding, and the source code is below. Hope this helps someone look into this.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TestSelectmenuBomb.aspx.cs" Inherits="AdaCarePublic.TestSelectmenuBomb" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Test Selectmenu Bomb</title>
    <link href="App_Themes/02-jquery-ui-1.11.3.min.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="//code.jquery.com/jquery-1.11.2.min.js"></script>
    <script type="text/javascript" src="/js/jquery-ui-1.11.3.js"></script>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>

        To demonstrate the problem:
        <ol>
            <li>Click the Datepicker text box and select a date from the pop-up calendar.</li>
            <li>Click the Selectmenu. Do not click anywhere else.</li>
            <li>A JavaScript error will be raised.</li>
        </ol>

        <asp:UpdatePanel ID="DatepickerUpdatePanel" runat="server" UpdateMode="Conditional">
            <ContentTemplate>
                Datepicker<br />
                <input type="text" id="myDatepicker" />
                <input type="text" id="mySomeOtherElement" />

            </ContentTemplate>
        </asp:UpdatePanel>
        <br />
        <asp:UpdatePanel ID="SelectmenuUpdatePanel" runat="server" UpdateMode="Conditional">
            <ContentTemplate>
                Selectmenu<br />
                <select id="mySelectmenu">
                    <option>This is Item #1</option>
                    <option>This is Item #2</option>
                    <option>This is Item #3</option>
                </select>
            </ContentTemplate>
        </asp:UpdatePanel>

        <%-- This code is needed to re-initialize the widgets after an async postback --%>
        <script type="text/javascript">

            initWidgets = function () {

                var datepickerID = 'myDatepicker';
                var selectmenuID = 'mySelectmenu';

                // Initialize the jQuery datepicker.
                $('#' + datepickerID).datepicker({
                    onSelect: function (dateText, datepickerInstance) {
                        //$('#mySomeOtherElement').focus(); // Uncomment this line to avoid the error
                        __doPostBack(datepickerID, ''); // Reloads only the datepicker's UpdatePanel
                    }
                });

                // Initialize the jQuery selectmenu.
                $('#' + selectmenuID).selectmenu();
            };

            var prm = Sys.WebForms.PageRequestManager.getInstance();
            prm.add_pageLoaded(PageLoadedEventHandler);
            function PageLoadedEventHandler() {
                $(function () { initWidgets(); });
            };
        </script>
    </form>
</body>
</html>

Changed June 21, 2016 05:23AM UTC by Akaoni comment:8

I ran into this issue today too and have replicated it in jsFiddle (fails in IE11 only):

https://jsfiddle.net/h9yec1fc/


I believe the issue is that:

1. An element is selected by the user (i.e. a Date Picker or, in the case of the jsFiddle, text input)

1. JavaScript removes that selected element from the DOM but IE 11 does not remove it from the Selection API (window.getSelection()), creating a mal-formed Range object

1. A new select menu element is created and initialised

1. On mouse down of the select menu, jQuery UI stores the mal-formed Range from the Selection API (see selectmenu.js > _buttonEvents.mousedown())

1. On click of the select menu, jQuery UI tries to re-select the mal-formed Range (see selectmenu.js > _buttonEvents.click() > this._setSelection())

1. Error is thrown and select menu element doesn't function


Note that if you de-select the text input before loading the select menu, it works.

If you clear the HTML using .empty() instead of .html(""), it works.

Like IE, Edge also creates a mal-formed Range object but doesn't throw an error when jQuery UI attempts to re-select it - perhaps it's .addRange() implementation is more fault tolerant?


Clearly none of this is jQuery UI's fault, but given the Selection API is "experimental" (https://developer.mozilla.org/en-US/docs/Web/API/Selection), perhaps some fault tolerance around the storing or re-selecting of Ranges would be appropriate?

Changed June 27, 2016 10:10PM UTC by scottgonzalez comment:9

resolution: notabug
status: closedreopened

Changed June 27, 2016 10:16PM UTC by scottgonzalez comment:10

status: reopenedopen

Changed June 27, 2016 10:20PM UTC by scottgonzalez comment:11

description: APS.Net web pages implement asynchronous partial-page updates with UpdatePanel controls. When an UpdatePanel is triggered, the DOM elements within the UpdatePanel are reloaded. Other elements on the page are not. \ \ Placing jQuery widgets for datepicker and selectmenu in different UpdatePanels causes a problem. If the user selects a date in the datepicker and triggers an async update, only the datepicker’s UpdatePanel is reloaded. If the user clicks the selectmenu’s button next, it throws an unhelpful JavaScript error: \ \ \ {{{ \ Unhandled exception at line 12549, column 4 in http://localhost:49339/js/jquery-ui-1.11.3.js \ 0x80004005 - JavaScript runtime error: Unspecified error. \ \ }}} \ \ The code throwing the error is within the selectmenu widget, in the _setSelection function, which is called when the button is clicked. The last line below (selection.addRange) throws the error: \ \ \ {{{ \ if ( window.getSelection ) { \ selection = window.getSelection(); \ selection.removeAllRanges(); \ selection.addRange( this.range ); // Throws error \ ... \ \ }}} \ \ My hypothesis (or guess, really): The ''this.range'' object references the user’s selected text because the widget wants to restore the text selection after the widget is clicked. The range originally refers to the datepicker’s element, but after the async postback the datepicker’s UpdatePanel is reloaded and the original selection is invalid. So, the addRange function is referencing invalid data and throws the unhelpful error. \ \ This problem was only demonstrated using Internet Explorer 11 64-bit. It was not tested with other browsers. A sample demonstrating the problem is available here: http://adacare.com/TestSelectmenuBomb.aspx \ \ Workaround: When the datepicker selects a date, set the focus to some other DOM element before the postback. \ Reduced test case: ​https://jsfiddle.net/h9yec1fc/ \ See [#comment:8 the comment from Akaoni] for more details. \ \ ---- \ original post: \ \ \ APS.Net web pages implement asynchronous partial-page updates with UpdatePanel controls. When an UpdatePanel is triggered, the DOM elements within the UpdatePanel are reloaded. Other elements on the page are not. \ \ Placing jQuery widgets for datepicker and selectmenu in different UpdatePanels causes a problem. If the user selects a date in the datepicker and triggers an async update, only the datepicker’s UpdatePanel is reloaded. If the user clicks the selectmenu’s button next, it throws an unhelpful JavaScript error: \ \ \ {{{ \ Unhandled exception at line 12549, column 4 in http://localhost:49339/js/jquery-ui-1.11.3.js \ 0x80004005 - JavaScript runtime error: Unspecified error. \ \ }}} \ \ The code throwing the error is within the selectmenu widget, in the _setSelection function, which is called when the button is clicked. The last line below (selection.addRange) throws the error: \ \ \ {{{ \ if ( window.getSelection ) { \ selection = window.getSelection(); \ selection.removeAllRanges(); \ selection.addRange( this.range ); // Throws error \ ... \ \ }}} \ \ My hypothesis (or guess, really): The ''this.range'' object references the user’s selected text because the widget wants to restore the text selection after the widget is clicked. The range originally refers to the datepicker’s element, but after the async postback the datepicker’s UpdatePanel is reloaded and the original selection is invalid. So, the addRange function is referencing invalid data and throws the unhelpful error. \ \ This problem was only demonstrated using Internet Explorer 11 64-bit. It was not tested with other browsers. A sample demonstrating the problem is available here: http://adacare.com/TestSelectmenuBomb.aspx \ \ Workaround: When the datepicker selects a date, set the focus to some other DOM element before the postback. \