Opened 5 years ago

Last modified 3 years ago

#11199 open bug

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 (last modified by Scott González)

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.

Change History (11)

comment:1 Changed 5 years ago by Scott González

Owner: set to 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/

comment:2 Changed 5 years ago by sandygettings

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.)

comment:3 Changed 5 years ago by Scott González

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.

comment:4 Changed 5 years ago by sandygettings

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?

comment:5 Changed 5 years ago by Scott González

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.

comment:6 Changed 5 years ago by sandygettings

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.

Last edited 5 years ago by sandygettings (previous) (diff)

comment:7 Changed 5 years ago by sandygettings

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>

comment:8 Changed 3 years ago by Casey

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)
  2. 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
  3. A new select menu element is created and initialised
  4. On mouse down of the select menu, jQuery UI stores the mal-formed Range from the Selection API (see selectmenu.js > _buttonEvents.mousedown())
  5. On click of the select menu, jQuery UI tries to re-select the mal-formed Range (see selectmenu.js > _buttonEvents.click() > this._setSelection())
  6. 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?

comment:9 Changed 3 years ago by Scott González

Resolution: notabug
Status: closedreopened

comment:10 Changed 3 years ago by Scott González

Status: reopenedopen

comment:11 Changed 3 years ago by Scott González

Description: modified (diff)
Note: See TracTickets for help on using tickets.