0

Okay so basically I have a form with a textarea where users can add content and apply some bbcode to the selected text.

Now I get the selected text with this function:

selection_get: function() {
    var text = "";
    if (window.getSelection) {
        text = window.getSelection().toString();
    } else if (document.selection && document.selection.type != "Control") {
        text = document.selection.createRange().text;
    }
    return text;
}

And that works properly, the only issue is if there is duplicate content like this for example:

You what, you what...

Now say I select the second you what from the string above and run it through something like this:

// get the selected text
var text = selection_get();
var original_text = $('textarea').val();
var newtext = '[b]you what[/b]';

$(container).val(original_text.replace(text, newtext));

Now newtext would be the selected code with the bbcode applied (for the sake of this example, we'll have it set as [b]you what[/b]).

The issue is that replace() will replace the very first occurrence of the selected text. How do I replace the actual selected text in its set position?

Note: Please ask if I need to clarify more, the question is rather vague :-( Cheers.

Darren
  • 13,050
  • 4
  • 41
  • 79

2 Answers2

1

Use the selectionStart and selectionEnd properties and add your BBcode on either end.

Once you've got the selected text, get the prepending text by getting a substr from the start of the textarea contents until the selectionStart point, and the appended text after the selection from selectionEnd to the end of the textarea contents.

Then set the value of the textarea like this (psuedo):

$('textarea').val( prependingText + BBCodeStartTag + selectedText + BBCodeEndTag + endText );
// e.g. :          You what,        [b]              you what       [/b]           ...

This method is really the only way to do what you are proposing, because it targets the exact section of text that you have selected rather than doing a replace() on the matching text which as you mention will replace the first occurrence instead of what you've selected. In a block of text like hello hello hello hello hello if you select the fourth hello your code would replace the first hello instead...

Edit: here's an example using a function from this answer to illustrate this idea:

function getSelected() {
    var editor = $('textarea');

    var u     = editor.val();
    var start = editor.get(0).selectionStart;
    var end   = editor.get(0).selectionEnd;

    return [u.substring(0, start), u.substring(end), u.substring(start, end)];
}

$('#ButtonToAddBBCode').click(function(e) {
    e.preventDefault();
    var bits = getSelected();
    var bb = ['[b]', '[/b]']; // your example BB code
    $('textarea').val(bits[0] + bb[0] + bits[2] + bb[1] + bits[1]);
});
Community
  • 1
  • 1
scrowler
  • 24,273
  • 9
  • 60
  • 92
0

You definitely want to look at Rangy for that. Using a straight up replace is not robust enough. The CSS Class Applier Module does pretty much exactly what you want. Tim Down is on here somewhere, if you add Rangy as a tag in your question he'll probably comment...

samson
  • 1,152
  • 11
  • 23