1

I have a textarea with this content:

<textarea id="text">
Hello! Who am I? This is the third sentence. This, is another sentence.
</textarea>

Since it's a textarea, it can be focused. I'm trying to find a way to:

  1. Separate all sentences inside the textarea into a javascript array. I tried a $('#text').val().split() approach, but there is more than just one sentence separator in my example.

  2. I also need to know in which sentence the cursor is currently positioned on.

Why, you may ask? I need to process (with a paid API that charges per character) sentences when the user changes their content. If I only make a small change in the 2nd sentence, why should the 1st, 3rd and 4th sentences be submitted? It is of course much less expensive to only submit the 2nd one.

As I previously said, the .split() approach would be perfect if people only used dots to separate sentences, but there are other characters that should also be considered (!?.) -- about the second point, i found a function to find de caret position:

function doGetCaretPosition (ctrl) {
    var CaretPos = 0;
    if (document.selection) {
        ctrl.focus ();
        var Sel = document.selection.createRange ();
        Sel.moveStart ('character', -ctrl.value.length);
        CaretPos = Sel.text.length;
    } else if (ctrl.selectionStart || ctrl.selectionStart == '0') {
        CaretPos = ctrl.selectionStart;
    }
    return (CaretPos);
}

The question is, how does the position help me find the sentence number? All ideas are welcome!

Andres SK
  • 10,779
  • 25
  • 90
  • 152

1 Answers1

4

The easiest way I can see to do this is to split() the str like you mentioned. From my understanding (and not finding any references to this), jQuery doesn't actually have a split() function, however:

var str = $('#text').val();
var sentences = str.split(/[.|!|?]\s/gi);

So as you can see, javascript's split function allows for regular expressions. The regex however isn't perfect (it's getting late, i'll look into getting a better one tomorrow).

Once you have the sentences it's just a matter of counting the length of each string until you get the caret's position. So get length of first sentence, is it bigger of = to the caret position, if not, get length of second string + first string, is that = or bigger. If it is equal or bigger, then that's the sentence you're on and the index your using is the sentence number.

Matt R
  • 2,577
  • 5
  • 30
  • 46
  • that's actually a great approach. i'm not that well-versed in regex, but i tested it and it worked pretty good. of course, if you think that the regex can be improved, that would be great! – Andres SK Jun 20 '12 at 04:47
  • Yeah, the problem I found with the regex is that it doesn't include the punctuation, which may cause a problem if the punctuation is changed – Matt R Jun 20 '12 at 12:55
  • i added this to the split regex to also grab new lines: var sentences = str.split(/\r\n|\r|\n|[.|!|?]\s/gi); – Andres SK Jun 20 '12 at 15:21
  • @MattR yes, just tested the punctuation issue. Without that character inside the array item value, the sentence length count won't work :s any ideas on that? – Andres SK Jun 20 '12 at 16:21
  • Unfortunately I haven't been able to come up with anything. My knowledge with using regexps is very limited. – Matt R Jun 20 '12 at 17:29
  • 1
    @MattR someone helped on that specific issue http://stackoverflow.com/questions/11127132/including-separator-characters-in-split-javascript/11127276 it works great! – Andres SK Jun 21 '12 at 10:19