0

There is a custom method to insert HTML(html fragment not just plain text) into an editor (Rich Text Editor), but for some reason I have to use e.preventDefault to prevent browser default paste action and insert the copy data later. My code looks like below:

editor.addEventListener('paste', function(e) {
   var data = e.clipboardData.getData('text/html'),
       newData;
   e.preventDefault();
   newData = custom.handle(data);
   custom.insert(newData);
}, false); 

After custom.insert(newData), cursor is still blinking at the origin position. I expected it to have moved the end of newData.

Can anybody help me fix that?

L_K
  • 2,838
  • 2
  • 16
  • 36
  • possible duplicate of [Set focus and cursor to end of text input field / string w. Jquery](http://stackoverflow.com/questions/19568041/set-focus-and-cursor-to-end-of-text-input-field-string-w-jquery) – pedromendessk Sep 16 '15 at 09:05
  • @PedroMendes Eh..., actually the pasted data maybe a html fragment, as we paste data into a iframe that has ```contentEditable``` attribute instead of ```input``` or ```textarea```. – L_K Sep 16 '15 at 09:13

2 Answers2

1

Your question may already have an answer here:

Use JavaScript to place cursor at end of text in text input element

Set focus and cursor to end of text input field / string w. Jquery

With Mike Berrow's example, you can replace the input value with itself to set the carret to the end of the input. This would seem to be the most reliable way to do it, event if it is slightly hackish.

myInput.value = myInput.value;

With browsers that support it, you can rather use the setSelectionRange method. Since you already use clipboardData, this shouldn't be a problem.

myInput.setSelectionRange(myInput.value.length, myInput.value.length);

Pay attention to the fact that the value length may be harder to get if you are working with a textarea.

https://developer.mozilla.org/fr/docs/Web/API/HTMLInputElement/setSelectionRange

Community
  • 1
  • 1
saeraphin
  • 395
  • 1
  • 9
  • It seems that the ```setSelectionRange``` works fine with text, but what if ```newData``` is a html fragment? In that case we can't calculate the length of pasted data :( – L_K Sep 16 '15 at 09:07
0

I don't know what properties of functions your custom has, but you can use this the code to move the cursor to the end of the text in an input and textarea:

custom.selectionStart = custom.selectionEnd;

If newData is pasted in the middle or beginning of the text, then you will have to calculate the length of newData and move the cursor by that many characters. Something like:

custom.selectionStart = custom.selectionStart + newData.length;
custom.selectionEnd = custom.selectionStart;

Edit to answer your question: How to calculate the length of text with HTML tags?

Well, this will be a bit tricky. You can create a temporary HTML element in memory, add the newData in it, and calculate the length of its innerText property. Something like this:

var temp = document.createElement("div");
temp.innerHTML = newData;
custom.selectionStart = custom.selectionStart + temp.innerText.length;
custom.selectionEnd = custom.selectionStart;

Note: innerText is was introduced by Microsoft and is not a W3C standard. The implementation varies across browsers although most replicate IE's behavior. innerText is style-aware and will only return the visible text.

Racil Hilan
  • 24,690
  • 13
  • 50
  • 55
  • In my case, the pasted data maybe a html fragment, it seems that we can't just calculate the ```newData.length```... – L_K Sep 16 '15 at 09:10
  • Oh, I know what you mean, but the data will be pasted in is a iframe that has ```contentEditable``` attribute, How can I implement ```setSelectionRange``` method? – L_K Sep 16 '15 at 09:47
  • It doesn't make sense to use `setSelectionRange` because you're not really selecting, you're just moving the cursor. And you still need to know where the cursor currently is, so you still need `selectionStart`. Try this: `custom.setSelectionRange(custom.selectionStart + temp.innerText.length, custom.selectionStart + temp.innerText.length);`. Obviously, it is better to put the value `custom.selectionStart + temp.innerText.length` into a variable instead of repeating it twice. – Racil Hilan Sep 16 '15 at 10:56