select all text in contenteditable div when it focus/click [duplicate]
Asked Answered
G

3

44

I've got contenteditable div as below.

<div style=" border:solid 1px #D31444" contenteditable="true">12 some text...</div>

What I need is, when I click on the div, all the text will automatically get selected. Can you give me solution please?

Gyimah answered 27/9, 2010 at 16:34 Comment(2)
This answer provides the most 'correct' way to do what you want: https://mcmap.net/q/22268/-programmatically-select-text-in-a-contenteditable-html-elementEogene
Create a function called SelectAll(). Add it to the div with onclick and onfocus, including tabindex="0" and some id for easy selection. The function: const editableDiv = document.getElementById("that-div"); window.getSelection().selectAllChildren(editableDiv);Darell
O
57

Try this:

<div style="border:solid 1px #D31444"
     contenteditable="true"
     onclick="document.execCommand('selectAll',false,null)">12 some text...</div>

Update: Note that document.execCommand is now deprecated although it still works.

Octennial answered 27/9, 2010 at 16:39 Comment(11)
This would be better done using the focus event, because using the click event will highlight everything whenever the user tries to click to position the caret.Chlorate
Well, probably, but that depends on what the author of the question wants.Octennial
I just tried this in Chrome Version 24.0.1312.57 OS X. Using jQuery 1.9.1, binding to the focus does not work. Binding to the click event did select the text: $('.editable').on('click', function () { document.execCommand('selectAll', false, null); });Norris
After tinkering a bit more I noticed that the focus event does work, but there are subsequent events (positioning the cursor, maybe) that undo the selection. I tried stopPropagation(), but that didn't work for me.Norris
jsfiddle.net/rudiedirkx/MgASG/1/show might help?Sanjak
This doesn't work when the user navigates to the contenteditable div with the 'Tab' key.Osgood
@Sanjak thank you! I'll have to look into the performance implications of this, but works perfectly for me!Idaidae
@Norris is correct. Chrome doesn't handle selectAll on focus correctly, and I filed an issue about it. click works, but as Tim pointed out, usability suffers when the user wants to select only part of the text.Proteiform
You cannot focus a div, unless you set its tabindex property.Saccharase
The elegance of this answer is unparalleled for this task.Better
Here is a short and undeprecated solution: window.getSelection().selectAllChildren(div);Darell
C
58

This will do it. The timer is there for Chrome and Safari because in those browsers, the native browser behaviour that selects the whole element seems to trigger after the focus event, thereby overriding the effect of the selection code unless postponed until after the focus event:

var div = document.getElementById("editable");

div.onfocus = function() {
    window.setTimeout(function() {
        var sel, range;
        if (window.getSelection && document.createRange) {
            range = document.createRange();
            range.selectNodeContents(div);
            sel = window.getSelection();
            sel.removeAllRanges();
            sel.addRange(range);
        } else if (document.body.createTextRange) {
            range = document.body.createTextRange();
            range.moveToElementText(div);
            range.select();
        }
    }, 1);
};
Chlorate answered 27/9, 2010 at 16:55 Comment(12)
Shouldn't there be a way to do this with preventDefault or stopPropagation too? Using setTimeout seems kind of ugly because you have to break the call stack.Cysteine
@Adam: I don't think so. You don't want to prevent the editable element from receiving focus, so preventDefault() is out. stopPropagation() only stops the event from propagating to the next target, which is not useful for this.Chlorate
tim, why aren't you a moderator?Photodynamics
@think123: Three reasons: I haven't put myself forward, I don't really want to and I don't know whether I'd do it well anyway.Chlorate
This should be the accepted answer - it doesn't require an inline script. Can I ask what are the various compatibility reasons for the "getSelection", "createRange" property checks etc..?Bivouac
@Jonz: window.getSelection() and document.createRange(), which are both now standardized, are supported in most browsers but not IE < 9. IE does have its own selection/range API though, accessed here via document.body.createTextRange().Chlorate
Thanks! I minified your function with UglifyJS2 also... Element.prototype.SelectAll=function(d){d=this;var sel,range;window.getSelection&&document.createRange?(range=document.createRange(),range.selectNodeContents(d),sel=window.getSelection(),sel.removeAllRanges(),sel.addRange(range)):document.body.createTextRange&&(range=document.body.createTextRange(),range.moveToElementText(d),range.select())}Nancynandor
@TimDown I want to set focus() and for some columns need to select text on focus. Unable to figure out these both on this function could you help on it.Hubbs
The above can nowadays be replaced by window.getSelection().selectAllChildren(div);Darell
@JasonVasilev: selectAllChildren existed in 2010 but not all browsers at the time followed the spec precisely, so I didn't use it in this answer. I don't know whether all current browsers follow the spec now, tbh.Chlorate
@TimDown, just checked MDN selectAllChildren and support seems flawless. Could you add an update to your answer? It might help people scan quicker for the most modern solution.Darell
@JasonVasilev What I meant was that selectAllChildren existed in all browsers in 2010 but was not implemented the same in all of them, so it's not as simple as just saying "MDN lists support for all browsers" and leaving it at that. However, I will check and update if necessary when I get a moment.Chlorate
O
57

Try this:

<div style="border:solid 1px #D31444"
     contenteditable="true"
     onclick="document.execCommand('selectAll',false,null)">12 some text...</div>

Update: Note that document.execCommand is now deprecated although it still works.

Octennial answered 27/9, 2010 at 16:39 Comment(11)
This would be better done using the focus event, because using the click event will highlight everything whenever the user tries to click to position the caret.Chlorate
Well, probably, but that depends on what the author of the question wants.Octennial
I just tried this in Chrome Version 24.0.1312.57 OS X. Using jQuery 1.9.1, binding to the focus does not work. Binding to the click event did select the text: $('.editable').on('click', function () { document.execCommand('selectAll', false, null); });Norris
After tinkering a bit more I noticed that the focus event does work, but there are subsequent events (positioning the cursor, maybe) that undo the selection. I tried stopPropagation(), but that didn't work for me.Norris
jsfiddle.net/rudiedirkx/MgASG/1/show might help?Sanjak
This doesn't work when the user navigates to the contenteditable div with the 'Tab' key.Osgood
@Sanjak thank you! I'll have to look into the performance implications of this, but works perfectly for me!Idaidae
@Norris is correct. Chrome doesn't handle selectAll on focus correctly, and I filed an issue about it. click works, but as Tim pointed out, usability suffers when the user wants to select only part of the text.Proteiform
You cannot focus a div, unless you set its tabindex property.Saccharase
The elegance of this answer is unparalleled for this task.Better
Here is a short and undeprecated solution: window.getSelection().selectAllChildren(div);Darell
S
7

The problem with focus event on a div is that it can't fire because it thinks a div should not be editable. Editable contents in the DOM are marked with tabindex in the background, so in order for your div to receive the onfocus event, you need to explicitly declare the div's tabindex property. HTML:

<div style=" border:solid 1px #D31444" contenteditable="true" tabindex="1" onfocus="document.execCommand('selectAll',false,null)" >12 some text...</div>

That should work with onfocus.

Saccharase answered 13/2, 2016 at 21:2 Comment(2)
Doing this causes it to select the whole entire document. You can use the same code, but I recommend using a setTimeout for 150 ms so it won't select the whole document. Hope this helps you all!Nymphet
Rather than working around the workaround (see 'XY Problem' on Wikipedia & Stack Exchange), use the <style> & <script> sections (or .css & .js pages), like the jsGods intended and it won't be an issue; you shouldn't need tabindex either. You could use something like a plain ol' <div id='myDiv'>&nbsp;</div> styled like #myDiv{border:solid 1px #d14;} or whatever, and js myDiv.addEventListener('click', function(e){this.contentEditable = true; this.focus(); document.execCommand('selectAll', false, null);});. (Works on FF anyway)Popeyed

© 2022 - 2024 — McMap. All rights reserved.