Skip to main content

Search and Top Navigation

#10701 open bug ()

Opened November 20, 2014 02:36PM UTC

Last modified November 26, 2014 06:47AM UTC

DIalog: selecting text programmatically in IE is impossible in modals

Reported by: SimenB Owned by:
Priority: minor Milestone: none
Component: ui.dialog Version: 1.11.2
Keywords: Cc:
Blocked by: Blocking:
Description

Bad title...

We have a copy to clipboard dialog, that marks the text in the dialog, so the user just has to press ctrl c, as well as a button underneath to allow you to select all the text on demand.

If the dialog is a modal, this only works in Chrome, not in IE8, 9 or 11. If it's not a modal, it works in all.

JSFiddle: http://jsfiddle.net/SimenB/v7jm7tro/

If you remove modal: true, and run it anew, you can see that the selecting work.

Attachments (0)
Change History (5)

Changed November 20, 2014 02:47PM UTC by SimenB comment:1

_comment0: After digging in the source code, I found that _allowInteraction returns false in IE1416494881175230
_comment1: After digging in the source code, I found that _allowInteraction returns false in IE, as $( event.target ).closest( ".ui-dialog" ).length is 01416562436794480

After digging in the source code, I found that _allowInteraction returns false in IE, as $( event.target ).closest( ".ui-dialog" ).length is 0.

EDIT: This is because the target is the body of the document.

Changed November 21, 2014 05:09PM UTC by tj.vantoll comment:2

status: newopen
summary: When having a jQuery UI DIalog as a modal, selecting text programatically in IE is impossibleDIalog: selecting text programmatically in IE is impossible in modals

Same underlying cause as #9125.

Changed November 23, 2014 07:23PM UTC by SimenB comment:3

Do you have any workaround or hack we could use? We have to support IE, and we have to be able to select the text from the user (client demand). I suppose we could try to use the overlay manually, but then we lose a lot of the magic surrounding the modal that's really useful.

Changed November 24, 2014 01:45PM UTC by tj.vantoll comment:4

Replying to [comment:3 SimenB]:

Do you have any workaround or hack we could use? We have to support IE, and we have to be able to select the text from the user (client demand). I suppose we could try to use the overlay manually, but then we lose a lot of the magic surrounding the modal that's really useful.

Unfortunately I don't know of a good workaround without foregoing the modal functionality. When I looked at this problem before I got this far (http://bugs.jqueryui.com/ticket/9313#comment:5). I would recommend playing with an extension that overrides

_allowInteraction
to see if you can come up with something that works.

Changed November 26, 2014 06:47AM UTC by SimenB comment:5

_comment0: I did just that, and got it working (tested in IE8-11). \ \ I added the middle ```if``` in _allowInteraction \ \ {{{ \ _allowInteraction: function( event ) { \ if ( $(event.target).closest( ".ui-dialog" ).length ) { \ return true; \ } \ \ if ( event.target === this.document[ 0 ].body && $(event.target).hasClass( "ui-dialog-allow-focus" ) ) { \ $(event.target).removeClass( "ui-dialog-allow-focus" ); \ \ return true; \ } \ \ // TODO: Remove hack when datepicker implements \ // the .ui-front logic (#8989) \ return !!$(event.target).closest( ".ui-datepicker" ).length; \ } \ }}} \ \ and also added the class in my selection-method \ \ {{{ \ makeSelection: function (element) { \ var range, selection, \ body = document.body; \ \ $(body).addClass('ui-dialog-allow-focus'); \ \ if (body.createTextRange) { \ range = body.createTextRange(); \ range.moveToElementText(element); \ range.select(); \ } else if (window.getSelection) { \ selection = window.getSelection(); \ range = document.createRange(); \ range.selectNodeContents(element); \ selection.removeAllRanges(); \ selection.addRange(range); \ } \ } \ }}} \ \ Very much an ugly hack, but at least it works. Hopefully you guys can come up with a much better solution to the problem.1416984765799915
_comment1: I did just that, and got it working (tested in IE8-11). \ \ I added the middle ```if``` in _allowInteraction \ \ {{{ \ _allowInteraction: function( event ) { \ if ( $(event.target).closest( ".ui-dialog" ).length ) { \ return true; \ } \ \ if ( event.target === this.document[ 0 ].body && $(event.target).hasClass( "ui-dialog-allow-focus" ) ) { \ $(event.target).removeClass( "ui-dialog-allow-focus" ); \ \ return true; \ } \ \ // TODO: Remove hack when datepicker implements \ // the .ui-front logic (#8989) \ return !!$(event.target).closest( ".ui-datepicker" ).length; \ } \ }}} \ \ and also added the class in my selection-method \ \ {{{ \ makeSelection: function (element) { \ var range, selection, \ body = document.body; \ \ $(body).addClass('ui-dialog-allow-focus'); \ \ if (body.createTextRange) { \ range = body.createTextRange(); \ range.moveToElementText(element); \ range.select(); \ } else if (window.getSelection) { \ selection = window.getSelection(); \ range = document.createRange(); \ range.selectNodeContents(element); \ selection.removeAllRanges(); \ selection.addRange(range); \ } \ \ // This is only necesarry if not using a jQuery UI Dialog that is modal (which we never do), but putting \ // it here to be safe \ setTimeout(function () { \ $(body).removeClass('ui-dialog-allow-focus'); \ }, 5); \ } \ }}} \ \ Very much an ugly hack, but at least it works. Hopefully you guys can come up with a much better solution to the problem.1416984796655456

I did just that, and got it working (tested in IE8-11).

I added the middle ``if`` in _allowInteraction

_allowInteraction: function( event ) {
    if ( $(event.target).closest( ".ui-dialog" ).length ) {
        return true;
    }

    if ( event.target === this.document[ 0 ].body && $(event.target).hasClass( "ui-dialog-allow-focus" ) ) {
        $(event.target).removeClass( "ui-dialog-allow-focus" );

        return true;
    }

    // TODO: Remove hack when datepicker implements
    // the .ui-front logic (#8989)
    return !!$(event.target).closest( ".ui-datepicker" ).length;
}

and also added the class in my selection-method

makeSelection: function (element) {
    var range, selection,
        body = document.body;

    $(body).addClass('ui-dialog-allow-focus');

    if (body.createTextRange) {
        range = body.createTextRange();
        range.moveToElementText(element);
        range.select();
    } else if (window.getSelection) {
        selection = window.getSelection();
        range = document.createRange();
        range.selectNodeContents(element);
        selection.removeAllRanges();
        selection.addRange(range);
    }

    // This is only necessary if not using a jQuery UI Dialog that is modal (which we never do), but putting
    // it here to be safe
    setTimeout(function () {
        $(body).removeClass('ui-dialog-allow-focus');
    }, 5);
}

Very much an ugly hack, but at least it works. Hopefully you guys can come up with a much better solution to the problem.