views:

38

answers:

1

I have problem with jCaret plugin in IE.

jCaret downloads

I want to get the caret position inside a textarea.

My code looks like this:

$('.myTextArea').click(function(){
    var myCaretPos = $(this).caret().end;
});

The problem in IE is that I only get correct result if the textarea is only one line, but if there are more than one line the result is wrong. It seems that line breaks takes one extra char in IE. So how can I remove line breaks in IE?

A: 

I've encountered and solved this problem. Here's a function that will do it outside jQuery:

function getInputSelection(el) {
    var start = 0, end = 0, normalizedValue, range,
        textInputRange, len, endRange;

    if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
        start = el.selectionStart;
        end = el.selectionEnd;
    } else {
        range = document.selection.createRange();

        if (range && range.parentElement() == el) {
            len = el.value.length;
            normalizedValue = el.value.replace(/\r\n/g, "\n");

            // Create a working TextRange that lives only in the input
            textInputRange = el.createTextRange();
            textInputRange.moveToBookmark(range.getBookmark());

            // Check if the start and end of the selection are at the very end
            // of the input, since moveStart/moveEnd doesn't return what we want
            // in those cases
            endRange = el.createTextRange();
            endRange.collapse(false);

            if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
                start = end = len;
            } else {
                start = -textInputRange.moveStart("character", -len);
                start += normalizedValue.slice(0, start).split("\n").length - 1;

                if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
                    end = len;
                } else {
                    end = -textInputRange.moveEnd("character", -len);
                    end += normalizedValue.slice(0, end).split("\n").length - 1;
                }
            }
        }
    }

    return {
        start: start,
        end: end
    };
}

And an example of how to use it:

$('.myTextArea').click(function(){
    var myCaretPos = getInputSelection(this).end;
});

I've also made a jQuery plug-in that includes this functionality, along with other functionality relating to textarea selections. It's not yet released but is stable and tested. Source is here: http://code.google.com/p/rangy/source/browse/trunk/src/js/modules/textinputs_jquery.js. Example:

$('.myTextArea').click(function(){
    var myCaretPos = $(this).getSelection().end;
});
Tim Down
Thank you Tim, but my problem is still there. I have tried both your solutions but it didn't work. In IE I still have one extra character for line breaks so I don't know how I can solve this.
Guest
Oh, maybe I've misunderstood. The problem my stuff solves is with leading and trailing line breaks in textareas in IE. Textareas in IE do indeed use `\r\n` instead of `\n`, but why is that causing you a problem?
Tim Down
Thank you very much! Now it works perfectly in IE. But I the problem is still there in Opera. Do you know how I can implement same thing for Opera?
Guest
Hang on, so what's changed that makes it work perfectly? I'm confused.
Tim Down
I'm sorry for that. I have replaced "\n" with "\r\n". So this solution solved my problem in IE, but I still have the same problem in Opera. I want to remove the caracter for line breaks in Opera.
Guest
I'm still confused. What are you actually trying to do with the caret position? The position my code returns will always be a position within the textarea's value, regardless of whether line breaks are represented by `\n` or `\r\n`.
Tim Down
For example. If I get caret position from the second line in a textarea, the value of the caret position will be one number higher in Opera than in the other browsers. So now I'm looking for a line breake character for Opera. Do you understand what I mean?
Guest
But why does it actually matter that the actual position is one higher?
Tim Down
Because I'm using this script for a XML parser. I select out information betweeen xml tags using caret position. And this line breaks infects my code. So do you know how I can remove the line breaks in Opera?
Guest
At the risk of sounding stupid, it's still not entirely clear. I'm trying to help, and I don't think I'm being stupid. Forgetting the XML bit for a moment, are you trying to extract the portion of the textarea's value selected by the user? If not, what is it that you are you trying to extract from the textarea that depends on the caret position?
Tim Down
Why is it so important for you to know why I need to remove the line breaks? It's difficult to explain all details here. But I'm trying to do my best. Yes I'm trying to extract the portion of the textarea's value selected by the user. I have created a sub string based on the caret positions value. After that I'm trying to find the character "<" on the right side and ">" on the left side. After that i'm trying to to manage the information between this characters. All this code is based on the caret position and doesn't work in Opera because of the extra line breake characters.
Guest
It's important because I didn't know what you're asking for and therefore what to suggest. If you use the first piece of code, you can do `var myCaretPos = getInputSelection(this); var selectedText = this.value.slice(myCaretPos.start, myCaretPos.end);` and with the jQuery plug-in you can do `var selectedText = $(this).getSelection().text;`. Both work fine in Opera. I don't know whether line breaks within `selectedText` will be a problem for you but if so you can remove them easily enough.
Tim Down
Thanks. I will try this.
Guest