views:

78

answers:

3

I have a <p> containing text. When the <p> is clicked on, I create a <textarea> containing the text from the <p>. Is it possible to calculate where in the <p>'s text the click occurred, and move the <textarea>'s cursor to that same point?

+2  A: 

I don't believe so, no. The DOM just knows what containing element received the click event, it doesn't distinguish between pieces of text within the containing element unless they are elements themselves. And I doubt you want to wrap every character in your text with its own element tag :)

David
@David I think you're right... but I hope you're wrong!
Alison
@Yeti's answer seems to contradict what you're saying, David. It's something I wasn't aware of either.
morgancodes
@morgancodes: I certainly hope Yeti's solution works. I'll have to keep it around in case I ever encounter the same thing :)
David
A: 

I'm guessing this is going to take a fair amount of fiddling to get right, and you won't be able to get it exactly right. But you'll probably want to use event.clientX and event.clientY.

EDIT -- didn't know about this stuff when I replied. Looks pretty possible to get it exactly correct. http://www.quirksmode.org/dom/range_intro.html

An alterntive idea: style the textarea so it looks like plain text, and re-style it to look like a form field when it gets clicked.

morgancodes
ooo, I like that alternative idea. I may have to tinker around with that at some point in future development.
David
@morgancodes nice idea re: textarea styling. This is the nicest thing I've thought of too, but I still see some drawbacks, e.g. when more than one paragraph is entered in a `<textarea>`, splitting that into separate `<textarea>`s later might be desirable. Looks like I'll be compromising on one front or other.
Alison
+2  A: 

Hope this simple example helps:

<html>
<head/>

<body>
<script type='text/javascript'>

function getPosition() 
{   
        var currentRange=window.getSelection().getRangeAt(0);   
        return currentRange.endOffset;
}

function setPosition(elemId, caretPos) {
    var elem = document.getElementById(elemId);

    if(elem != null) {
        if(elem.createTextRange) {
            var range = elem.createTextRange();
            range.move('character', caretPos);
            range.select();
        }
        else {
            if(elem.selectionStart) {
                elem.focus();
                elem.setSelectionRange(caretPos, caretPos);
            }
            else
                elem.focus();
        }
    }
}

function test()
{
    setPosition('testId', getPosition());
}


</script>
<p onclick = 'test()'>1234567890</p>
<textarea  id='testId'>123467890</textarea>
</body>
</html>

Or you can use third-party JS library like jQuery - see this example.

Yeti
This doesn't work in my opera.
jpalecek
@jpalecek The Barber of Seville used jQuery?
Peter Ajtai
@peter @jpalecek that figuros. Can we stop this now?
Alison
@Yeti thanks for the answer! I really hope this works; hopefully will get a chance to try in the next few days.
Alison