13

I have been doing research on this simple sounding issue for a couple of days and I have not seen any result.

In a nutshell my problem is as follows: I would like to select text in a some input field, move focus to another field (or generally speaking some other element), but not lose my selected text.

Such a situation could correspond to a use-case in which I select text in a field, right-click and display a custom popup menu, but do not wish to lose focus of selected text, because I want to do some operations on the previously selected text.

A small code test sample would be (for my initial simple scenario - here I am forcing text selection when the second input field gains focus):

<html>
<head>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
    <input type="text" id="text1" size="20" value="Test1"/>
    <input type="text" id="text2" size="20" value="Test2"/>

    <script>
    $('#text2').focus( function (evt) {
        var target = $('#text1')[0];
        target.select();
        console.log('active/focused element: ' + document.activeElement.id);
    });
    </script>
</body>
</html>

I have been searching SO and web for a solution to this and have not seen much if any help. I am not sure this is even really possible (due to the link between blur and selection lost and focus and selection). I have seen a style property called preventDeselect, in another SO answer - this does not work and I have not even such documentation or browser support for this.

I am quite struggling with this and would appreciate some help: even saying I can't do this at all or maybe some ways to go.

UPDATE: Just for the record, my user scenario, which refers to text selection and context menu, is a common one (it slipped my mind to mention): just select some text in this page (or in an input type field) and right click to get the browser's default context menu - my scenario is different in that i want to use a custom menu, but with similar behavior to the browser's context menu - which normally allows to select some text, cut/copy the selection, navigate within the context menu without losing the selected text. So I think it should be possible somehow :) to do all these things with a context menu and still have your selection.

Community
  • 1
  • 1
acostache
  • 2,177
  • 7
  • 23
  • 48

2 Answers2

4

Attempting to answer this part of your question:

Such a situation could correspond to a use-case in which I select text in a field, right-click and display a custom popup menu, but do not wish to lose focus of selected text, because I want to do some operations on the previously selected text.

For this use-case, I created a quick fiddle: http://jsfiddle.net/4XE9a/1/

Note: Am using the same getSelection function from @David's answer.

If you select any text and then right-click on the input, a custom popup menu appears. Click "option 1". You will find that the selection is not lost even though the focus has shifted to that anchor tag.

However, for the second part of your question regarding focus shifting to another textbox, @David's answer suffices.

Update: (after your comments)

Please see this updated fiddle: http://jsfiddle.net/783mA/1/

Now, when you select some text and right-click on the input it will show the custom popup menu with three options. Use tab to navigate and press space or click on the highlighted option. (Due to paucity of time I could not implement up/down arrow keys, but the concept remains the same)

This demonstrates your question in the comment that the selection is still not lost while navigating the menu.

Note: You are wanting to visually keep the selection highlight and not lose the selection while clicking anywhere else. Please note that this is not possible because text selection behavior is OS implemented. Browser, html etc do not play a role here. The text selection is lost as soon as you click anywhere outside the context of selection. This is because the system starts expecting a new selection as soon as you click anywhere outside. However, controls without text surface are exempt. Button, scrollbar arrows etc will not cause selection to lose.

To view this behaviour, in the fiddle, select some text and then click any dropdown on the left pane. The text selection is not lost, even visually for that matter.

This is why in the new fiddle above, I purposely used buttons to demonstrate.

Abhitalks
  • 27,721
  • 5
  • 58
  • 81
  • Very nice, thanks for taking the time to do this; to be a bit more specific (maybe this should be a different question) - would it be possible for the context menu shown to be "navigatable" (via up/down keys) but still not lose the selection visually? – acostache Nov 29 '13 at 13:06
  • 1
    @acostache, I just came back. Please see the updated answer above. – Abhitalks Nov 29 '13 at 14:04
  • Very cool! but the concept code works only in IE on my side (FF or Chrome not) :(. Thank you very much for the help on this. Sorry to have consumed so much of your time for this. I will try to see if I can get it to work in Chrome and/or FF. – acostache Nov 29 '13 at 14:15
  • It's working on Chrome at my end as I use Chrome only. IE I don't know ;) – Abhitalks Nov 29 '13 at 14:23
  • This is turning into a longer discussion, sorry for bugging you, but maybe it's OS related - I am working on a Win7 machine. If this is the same for you, then I am getting a bit lost :). – acostache Nov 29 '13 at 14:26
  • No problems :) I am on Win7 yes. I have updated the earlier fiddle with anchors. http://jsfiddle.net/4XE9a/2/ See if it works. Select text, right-click, tab to option2 and hit enter. – Abhitalks Nov 29 '13 at 15:03
  • Unfortunately, that had the same effect as before; no idea why Chrome/FF does not do the same trick for me. That .focus() which does all the magic is not working the way we want it :) – acostache Nov 30 '13 at 15:19
  • Marking this as the accepted answer as it provides the answer to my user scenario and also mentions @David's general answer. I still have to find a workaround that works in every case for me. But this should provide guidelines for others facing similar issues. Thanks for all the help. – acostache Dec 02 '13 at 09:01
1

You can save each selection in an interval, then retrieve it when you like. Here is an example that pulls the selection when the input has focus and clears the interval on blur:

function getSelection(elm) {
    var start = elm.selectionStart;
    var end = elm.selectionEnd;
    return elm.value.substring(start, end);
}

$('input').focus(function() {
    var self = this;
    $(this).data('interval', setInterval(function() {
        $(self).data('selection', getSelection(self));
    },20));
}).blur(function() {
    clearInterval($(this).data('interval'));
});

Now you can stuff like:

$('#text2').focus(function() {
    console.log('selection in #text1 was: '+$('#text1').data('selection'));
});

Demo: http://jsfiddle.net/qCCY5/

David Hellsing
  • 106,495
  • 44
  • 176
  • 212
  • Thanks for the answer; I know I can save the interval, but I would like to visually not use the selection when I focus something else (like have the text highlight still there). Hope I'm expressing myself properly :). – acostache Nov 29 '13 at 12:59
  • @acostache Eh.. like `$('input').blur(function(){$(this).focus()});`? – David Hellsing Nov 29 '13 at 13:06
  • yes, something like it, but still being able to use/navigate in the second field (the one which i really want to have the focus in, just not losing my selected text visually at least) - something like i told abhitalks – acostache Nov 29 '13 at 13:09
  • @acostache sounds like you are asking for a generic solution for a specific scenario. Losing focus but keeping selection is not possible in HTML, so you need to find a workaround that works for your specific need. – David Hellsing Nov 29 '13 at 13:14
  • I am thinking if this is the only method. But it seems to be impossible to get a current value from the element without an event and a continuous interval. – Tom Chung Nov 29 '13 at 13:14
  • @David yes; unfortunately, I think you are right with "Losing focus but keeping selection is not possible in HTML". I am just hoping to somehow find a way to keep the selection visually (not the focus). – acostache Nov 29 '13 at 13:18
  • @TomChung I think if you have, for instance, the id of an element and maybe a related event, you can do a lot. But, in my current case, indeed, it seems I am trying to keep selection and lose the focus. Kind of a hard one, with all the constraints I mentioned. – acostache Nov 29 '13 at 13:57
  • @David I just improved my user scenario example, in my questions description - maybe this way it makes more sense like that. – acostache Dec 02 '13 at 09:54