I am working on an in-browser editor within a textarea
. I have started looking for some information on dealing with textarea
selection and found this jQuery plugin, fieldSelection that does some simple manipulation.
However, it doesn't explain what's going on.
I want to understand more on textarea selection in JavaScript, preferably with a description of both pre-DOM3 and post-DOM30 scenarios.
setSelectionRange() method sets the start and end positions of the current text selection in an <input> or <textarea> element. Optionally, in newer browser versions, you can specify the direction in which selection should be considered to have occurred.
Browser support: 9. Specifies or returns the start position of the selected text within the current element. To retrieve the end position, use the selectionEnd property.
We can get the value of textarea in jQuery with the help of val() method . The val() method is used to get the values from the elements such as textarea, input and select. This method simply returns or sets the value attribute of the selected elements and is mostly used with the form elements.
The hidden attribute hides the <textarea> element. You can specify either 'hidden' (without value) or 'hidden="hidden"'. Both are valid. A hidden <textarea> element is not visible, but it maintains its position on the page.
function get_selection(the_id)
{
var e = document.getElementById(the_id);
//Mozilla and DOM 3.0
if('selectionStart' in e)
{
var l = e.selectionEnd - e.selectionStart;
return { start: e.selectionStart, end: e.selectionEnd, length: l, text: e.value.substr(e.selectionStart, l) };
}
//IE
else if(document.selection)
{
e.focus();
var r = document.selection.createRange();
var tr = e.createTextRange();
var tr2 = tr.duplicate();
tr2.moveToBookmark(r.getBookmark());
tr.setEndPoint('EndToStart',tr2);
if (r == null || tr == null) return { start: e.value.length, end: e.value.length, length: 0, text: '' };
var text_part = r.text.replace(/[\r\n]/g,'.'); //for some reason IE doesn't always count the \n and \r in the length
var text_whole = e.value.replace(/[\r\n]/g,'.');
var the_start = text_whole.indexOf(text_part,tr.text.length);
return { start: the_start, end: the_start + text_part.length, length: text_part.length, text: r.text };
}
//Browser not supported
else return { start: e.value.length, end: e.value.length, length: 0, text: '' };
}
function replace_selection(the_id,replace_str)
{
var e = document.getElementById(the_id);
selection = get_selection(the_id);
var start_pos = selection.start;
var end_pos = start_pos + replace_str.length;
e.value = e.value.substr(0, start_pos) + replace_str + e.value.substr(selection.end, e.value.length);
set_selection(the_id,start_pos,end_pos);
return {start: start_pos, end: end_pos, length: replace_str.length, text: replace_str};
}
function set_selection(the_id,start_pos,end_pos)
{
var e = document.getElementById(the_id);
//Mozilla and DOM 3.0
if('selectionStart' in e)
{
e.focus();
e.selectionStart = start_pos;
e.selectionEnd = end_pos;
}
//IE
else if(document.selection)
{
e.focus();
var tr = e.createTextRange();
//Fix IE from counting the newline characters as two seperate characters
var stop_it = start_pos;
for (i=0; i < stop_it; i++) if( e.value[i].search(/[\r\n]/) != -1 ) start_pos = start_pos - .5;
stop_it = end_pos;
for (i=0; i < stop_it; i++) if( e.value[i].search(/[\r\n]/) != -1 ) end_pos = end_pos - .5;
tr.moveEnd('textedit',-1);
tr.moveStart('character',start_pos);
tr.moveEnd('character',end_pos - start_pos);
tr.select();
}
return get_selection(the_id);
}
function wrap_selection(the_id, left_str, right_str, sel_offset, sel_length)
{
var the_sel_text = get_selection(the_id).text;
var selection = replace_selection(the_id, left_str + the_sel_text + right_str );
if(sel_offset !== undefined && sel_length !== undefined) selection = set_selection(the_id, selection.start + sel_offset, selection.start + sel_offset + sel_length);
else if(the_sel_text == '') selection = set_selection(the_id, selection.start + left_str.length, selection.start + left_str.length);
return selection;
}
Start with PPK's introduction to ranges. Mozilla developer connection has info on W3C selections. Microsoft have their system documented on MSDN. Some more tricks can be found in the answers here.
In addition to incompatible interfaces you'll be happy to know that there is extra bizarreness going on with textarea
nodes. If I remember correctly they behave as any other nodes when you select them in IE, but in other browsers they have an independent selection range which is exposed via the .selectionEnd
and .selectionStart
properties on the node.
Additionally, you should really take a look at .contentEditable
as a means to edit things live. From the release of Firefox3, this is now supported by all browsers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With