Bug w IE8 Using Javascript to Insert Text at Caret
Focusing on IE, I have a textbox (single line <input/>
) for which I need to insert text where the caret/cursor is. The text within a div is inserted at the caret position when the div is double clicked.
Bug: Text is inserted into the textbox, but at the beginning of the string in the textbox and not where the caret position is.
The following code works fine using the multiline input (no bug), the bug only occurs with the single line input.
Here is the simple Javascript for IE (other browser support has been removed for simplicity):
$.fn.insertAtCaret = function (tagName) {
return this.each(function () {
if (this.selectionStart || this.selectionStart == '0') {
//MOZILLA support
} else if (document.selection) {
//IE support
开发者_如何学Go this.focus();
sel = document.selection.createRange();
sel.text = tagName;
} else {
//ELSE
}
});
};
Just so you have everything in front of you, here is the JQuery that calls $.fn.insertAtCaret
:
$("#Subject").mousedown(function () { $("#InsertAtCaretFor").val("Subject"); });
$("#Subject").bind('click, focus, keyup', function () { $("#InsertAtCaretFor").val("Subject"); });
$("#Comment").mousedown(function () { $("#InsertAtCaretFor").val("Comment"); });
$("#Comment").bind('click, focus, keyup', function () { $("#InsertAtCaretFor").val("Comment"); });
$(".tag").dblclick(function () {
if ($("#InsertAtCaretFor").val() == "Comment") $("#Comment").insertAtCaret($(this).text());
if ($("#InsertAtCaretFor").val() == "Subject") $("#Subject").insertAtCaret($(this).text());
});
As you can see, when one of the two <input/>
s are clicked, focused, etc., a hidden field (ID="InsertAtCaretFor"
) value is set to either "Subject"
or "Comment"
. When the tag is double-clicked, its .text()
is inserted at the caret position within the <input/>
specified by the hidden field's value.
Here are the fields:
<%=Html.Hidden("InsertAtCaretFor") %>
<div class="form_row">
<label for="Subject" class="forField">
Subject:</label>
<%= Html.TextBox("Subject", "", new Dictionary<string, object> { { "class", "required no-auto-validation" }, { "style", "width:170px;" }, { "maxlength", "200" } })%>
</div>
<div class="form_row">
<label for="Comment" class="forField">
Comment:</label>
<%= Html.TextArea("Comment", new Dictionary<string,object> { {"rows","10"}, {"cols","50"}, { "class", "required"} })%>
</div>
Finally, here is an image so you can visually understand what I'm doing:
http://www.danielmckenzie.net/ie8bug.png
I'm using a different insertAtCaret code I found from googling around. Works on single inputs and textareas just fine.
$.fn.extend({
insertAtCaret: function (myValue) {
var $input;
if (typeof this[0].name != 'undefined')
$input = this[0];
else
$input = this;
if ($.browser.msie) {
$input.focus();
sel = document.selection.createRange();
sel.text = myValue;
$input.focus();
}
else if ($.browser.mozilla || $.browser.webkit) {
var startPos = $input.selectionStart;
var endPos = $input.selectionEnd;
var scrollTop = $input.scrollTop;
$input.value = $input.value.substring(0, startPos) + myValue + $input.value.substring(endPos, $input.value.length);
$input.focus();
$input.selectionStart = startPos + myValue.length;
$input.selectionEnd = startPos + myValue.length;
$input.scrollTop = scrollTop;
} else {
$input.value += myValue;
$input.focus();
}
}
});
After looking at your js code I'd change:
$(".tag").dblclick(function () {
if ($("#InsertAtCaretFor").val() == "Comment") $("#Comment").insertAtCaret($(this).text());
if ($("#InsertAtCaretFor").val() == "Subject") $("#Subject").insertAtCaret($(this).text());
});
To the following:
$(".tag").dblclick(function () {
if ($("#InsertAtCaretFor").val() == "Comment") {
$("#Comment").insertAtCaret($(this).text());
}
if ($("#InsertAtCaretFor").val() == "Subject") {
$("#Subject").insertAtCaret($(this).text());
}
});
Those two inline if statements with no ending curly brace look dangerous!
I've come the same problem myself in IE8. It seems that for INPUT type="text"
, it does not fill in selectionStart
and selectionEnd
. IE9 does, however.
精彩评论