2

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
            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

bug behavior

2 Answers 2

2

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!

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks jfar, but the issue is still occurring in IE8 when the browser's settings are reset to default. I changed my code to what you use as it is more readable.
@BueKoW - That stinks, I use almost the exact same code as you to do achieve the exact same functionality except I use single click inputs instead of divs. I don't know what could be wrong besides a selector mistake or something.
It has to be something specific to IE8 and I can't figure it out. If I install Google Chrome Frame for IE, everything works fine. The problem is non-existent in IE9. I haven't tested this in IE7... I may change the divs to inputs for kicks.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.