4

I'm struggling with an actually straighforward problem: In Internet Explorer I want to insert plain text at the current caret position. This works really fine for simple TEXTAREA elements but it doesn't entirely work for editable IFRAMEs, which is what I have.

In the script I use I am creating a TextRange object from the document of the IFRAME which I use to paste the text as HTML at the cursor position.

<iframe id="editable">
  <html>
    <body>
      Some really boring text.
    </body>
  </html>
</iframe>
<script type="text/javascript">

    window.onload = function() {
        var iframe = document.getElementById('editable');
        var doc = iframe.contentDocument || iframe.contentWindow.document;

        doc.body.innerHTML = iframe.textContent || iframe.innerHTML;

        // Make IFRAME editable
        if (doc.body.contentEditable) {
            doc.body.contentEditable = true;
        } 
    }

    function insert(text) {
        var iframe = document.getElementById('editable');
        var doc = iframe.contentDocument || iframe.contentWindow.document;
        iframe.focus();
      if(typeof doc.selection != 'undefined') {
            var range = doc.selection.createRange();
            range.pasteHTML(text);
      }
}
</script>
<input type="button" value="Insert" onClick="insert('foo');"/>

When I select some text in the IFRAME, the selection will be replaced with "foo" - this is expected behaviour. But when I just place the caret somewhere in the text, the insertion won't work.

Is this common behaviour, as there is "no real selection" for the case that I just place the cursor somewhere or is it a bug with editable IFRAMEs in IE, since it works pretty well with simple TEXTAREA elements?

Is there a workaround?

Andreas Pasch
  • 125
  • 1
  • 9
  • I have the very [same problem](http://stackoverflow.com/questions/5104102/paste-into-iframe-at-caret-position). It must be possible as wordpress do this. – Alex Mar 17 '11 at 11:59

1 Answers1

6

You may find it works if you use onmousedown rather than onclick in your button.

UPDATE

The reason why this makes a difference is that the click event fires after the iframe has lost focus (which destroys a collapsed selection in IE) whereas mousedown fires before.

FURTHER UPDATE

You could also try fixing this in IE by saving/restoring the selected TextRange as the iframe loses/receives focus. Something like this should work:

function fixIframeCaret(iframe) {
    if (iframe.attachEvent) {
        var selectedRange = null;
        iframe.attachEvent("onbeforedeactivate", function() {
            var sel = iframe.contentWindow.document.selection;
            if (sel.type != "None") {
                selectedRange = sel.createRange();
            }
        });
        iframe.contentWindow.attachEvent("onfocus", function() {
            if (selectedRange) {
                selectedRange.select();
            }
        });
    }
}

window.onload = function() {
    var iframe = document.getElementById('editable');
    fixIframeCaret(iframe);
};
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • That didn't seem to work either [http://jsfiddle.net/FjZY6/](http://jsfiddle.net/FjZY6/). I have a vested interest in this, so would be very keen to see a solution too. – Alex Mar 17 '11 at 12:23
  • Works for me. But to be honest, I don't really understand why this works, and it won't help me in my situation, since the insertion in my app is actually not triggerted from a button but from a Sencha GXT grid component. Why is this working? What is the difference between `onmousedown` and `onclick` event-wise? – Andreas Pasch Mar 17 '11 at 12:40
  • This is an IE specific question. Thus the snippet only works in IE. In any other browser you might use `iframe.document.execCommand("insertHTML", false, text);` – Andreas Pasch Mar 17 '11 at 13:07
  • @Alex, @Andreas: I updated my answer. That jsfiddle example does work for me in IE 7. – Tim Down Mar 17 '11 at 15:30