views:

1173

answers:

5

The old version of the question is below, after researching more, I decided to rephrase the question. The problem as before is, I need to focus a contenteditable div without highlighting the text, doing straight up focus highlights the text in Chrome.

I realize that people solved this problems in textareas by resetting the caret position in the textarea. How can I do that with a contenteditable element? All the plugins I've tried only works with textareas. Thanks.

Old Phrasing of the question:

I have a contenteditable element that I want to focus, but only insofar as to place the cursor at the front of the element, rather selecting everything.

elem.trigger('focus'); with jquery selects all the text in the entire element in chrome. Firefox behaves correctly, setting the caret at the front of the text. How can I get Chrome to behave the way I want, or is focus perhaps not what I'm looking for.

Thanks all.

+1  A: 

This previous question may help with cursor positioning.

Ken Redler
Are you sure those work on contenteditable. I was not able to get those to work.
Mark
A: 

Yes it happens because you have used

elem.trigger('focus'); 

try to use class or to identify the element on which you want to fire a trigger event.

Chirag
elem is a variable.
Mark
do you used it as input.trigger('focus'); ???
Chirag
+3  A: 

UPDATED:

DEMO: http://jsbin.com/oqozo3

//little implementation
    $(function() {
        $('#editable').bind('click', function(e) {
            var $edit = $(this);
            if ($('#text').length == 0) {
                $edit.html('<input id="text" type="text" name="text" value="'+ 
                $edit.text() + '" />');
                $('#text').focus();
                setCursor('text', $('#text').val().length); //set caret
                $('#text').bind('blur', function() {
                    $(this).parent().append(this.value);
                    $(this).remove();
                });
            }
        });
    });
/** 
 * this below is the function you need from:
 * http://stackoverflow.com/questions/1865563/
 * set-cursor-at-a-length-of-14-onfocus-of-a-textbox
 */
    function setCursor(node,pos){
    var node = (typeof node == "string" || 
    node instanceof String) ? document.getElementById(node) : node;
        if(!node){
            return false;
        }else if(node.createTextRange){
            var textRange = node.createTextRange();
            textRange.collapse(true);
            textRange.moveEnd(pos);
            textRange.moveStart(pos);
            textRange.select();
            return true;
        }else if(node.setSelectionRange){
            node.setSelectionRange(pos,pos);
            return true;
        }
        return false;
    }

so by referencing to my example/demo you need to have like this:

$elem = $('#wysiwyg_textarea');
$elem.focus();
setCursor( 'wysiwyg_textarea' , $elem.val().length ); //set caret
aSeptik
That's an interesting hack, great idea actually. Thank you. But the contenteditable is a wysiwyg editor, so I can't just substitute a textfield.
Mark
see the updates! ;-)
aSeptik
+3  A: 

Maybe I'm misreading the question, but wouldn't the following do (assuming an editable <div> with id "editable")? The timer is there because in Chrome, 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);
            range.collapse(true);
            sel = window.getSelection();
            sel.removeAllRanges();
            sel.addRange(range);
        } else if (document.body.createTextRange) {
            range = document.body.createTextRange();
            range.moveToElementText(div);
            range.collapse(true);
            range.select();
        }
    }, 1);
};

div.focus();
Tim Down
This is the correct answer. Thank you.
Mark
A: 

I managed to solve that problem after a bit of poking around the DOM.

elm.focus();
window.getSelection().setPosition(0);

It probably only works on WebKit browsers, but since it is the only source of the problem, I added a conditional (using jQuery)

if(!$.browser.webkit) {
    elm.focus();
} else {
    elm.focus();
    window.getSelection().setPosition(0);
}

Hope this solves your problem.

DfKimera
hmm, not sure why, that doesn't work for me. Tim Down's answer does though.
Mark