4

I have a little question

I want to click on my smileys and insert the text to the textarea. and when I want to add a smiley later, the smiley should be added to the cursor position and not at the end in the textarea.

This is my html code:

<textarea id="description" name="description"></textarea>

<div id="emoticons">
    <a href="#" title=":)"><img alt=":)" border="0" src="/images/emoticon-happy.png" /></a>
    <a href="#" title=":("><img alt=":(" border="0" src="/images/emoticon-unhappy.png" /></a>
    <a href="#" title=":o"><img alt=":o" border="0" src="/images/emoticon-surprised.png" /></a>
</div>

This is my JS code:

$('#emoticons a').click(function(){

    var smiley = $(this).attr('title');
    $('#description').val($('#description').val()+" "+smiley+" ");

});

Here you can see the result (NO WRAP - BODY) http://jsfiddle.net/JVDES/8/

I use an extern JS file for my javascript-code...
Do you know why the code isn't running in NO WRAP - HEAD mode? http://jsfiddle.net/JVDES/9/

Thanks for helping

Regards bernte

FelipeAls
  • 21,711
  • 8
  • 54
  • 74
bernte
  • 1,184
  • 2
  • 19
  • 34
  • WOW thanks!! So many answers! :D But I have still a problem. The problem in all codes the same! Example: I write **HOHO** than i click the **1st,2nd, 3rd smiley** than i click the coursor **in front of HOHO** and click the **1st and 2nd smilie**.. You will see the that last smilie isn't on the right position! In google chrome the result is very bad! With the same example the smilies are in the wrong order. Is there a way to set the coursor into the textarea after adding the smiley? – bernte Jun 17 '12 at 18:10

4 Answers4

7

Also, you can use something this function:

function ins2pos(str, id) {
   var TextArea = document.getElementById(id);
   var val = TextArea.value;
   var before = val.substring(0, TextArea.selectionStart);
   var after = val.substring(TextArea.selectionEnd, val.length);
   TextArea.value = before + str + after;
}

For your example, look here.


UPD 1:

To set cursor at specified position, use the next function:

function setCursor(elem, pos) {
   if (elem.setSelectionRange) {
      elem.focus();
      elem.setSelectionRange(pos, pos);
   } else if (elem.createTextRange) {
      var range = elem.createTextRange();
      range.collapse(true);
      range.moveEnd('character', pos);
      range.moveStart('character', pos);
      range.select();
   }
}

I updated code on jsFiddle, so, to view new example, look here.

Victor
  • 5,493
  • 1
  • 27
  • 28
  • I added a comment to my question! There is still a small problem with your code. Thanks for your fast response! regards berni – bernte Jun 17 '12 at 18:13
  • 2
    @bernte, I updated my answer and added new function which set the cursor into the textarea. – Victor Jun 17 '12 at 20:20
  • that is perfect! Thank you! i tried to add a space between the str but than the cursor isn't in the right position. do you have any idea? i don't know if my changes do match. CHANGED: **TextArea.value = before + " " + str + " " + after;** the coursor is between the : and the ) - http://jsfiddle.net/JVDES/15/ – bernte Jun 17 '12 at 21:23
  • 1
    @bernte The problem is that you add 2 more characters (spaces) to field, but to `setCursor()` function you don't send "them" (means `str` length). In this case, you need to add spaces to `str` before assign it to textarea and send to `setCursor()` function. See [example](http://jsfiddle.net/JVDES/16/). – Victor Jun 17 '12 at 21:43
  • There is a problem on Chrome, while you click frequently on Smilies, each new smiley goes BEFORE the others!! – Pars Oct 04 '13 at 11:02
3

Try this - http://jsfiddle.net/JVDES/12/

Credit for the caret position function goes to - https://stackoverflow.com/a/1891567/981134

Community
  • 1
  • 1
Zoltan Toth
  • 46,981
  • 12
  • 120
  • 134
  • I added a comment to my question! There is still a small problem with your code. Thanks for your fast response! regards berni – bernte Jun 17 '12 at 18:12
3

The difference between no wrap (head) and no wrap (body) is that the former will run the code as soon as possible and the latter will run the code after the page has loaded.

In this case, with no wrap (head), the code is being run before '#emoticons a' exists. Thus $('#emoticons a') returns none and does not attach the click handler. Later, the link is created.

Thus, the solution is to tell the code to run when the page is loaded.

There are a couple, equivalent ways of doing this. http://api.jquery.com/ready/

  1. $(document).ready(handler)

  2. $().ready(handler) (this is not recommended)

  3. $(handler)

So using version 3, we have:

$(function() {
    $('#emoticons a').click(function(){

    var smiley = $(this).attr('title');
    $('#description').val($('#description').val()+" "+smiley+" ");

    });
});

http://jsfiddle.net/Nc67C/

Liyan Chang
  • 7,721
  • 3
  • 39
  • 59
  • Ah. I must have skipped the portion about the cursor. The above answers all seem good and the cited thread was a good read as well. – Liyan Chang Jun 17 '12 at 11:29
2

try also this...

$('#emoticons a').click(function() {

    var smiley = $(this).attr('title');

    var cursorIndex = $('#description').attr("selectionStart");
    var lStr =  $('#description').val().substr(0,cursorIndex);
    var rStr = $('#description').val().substr(cursorIndex);

    $('#description').val(lStr+" "+smiley+" "+rStr);

});

Fix after your comment:

$('#emoticons a').click(
function(){var smiley = $(this).attr('title');

var cursorIndex = $('#description').attr("selectionStart");
var lStr =  $('#description').val().substr(0,cursorIndex) + " " + smiley + " ";
var rStr = $('#description').val().substr(cursorIndex);

$('#description').val(lStr+rStr);
$('#description').attr("selectionStart",lStr.length);                                     
});​

Chris Happy
  • 7,088
  • 2
  • 22
  • 49
MaJac89
  • 151
  • 4
  • I added a comment to my question! There is still a small problem with your code. Thanks for your fast response! regards berni – bernte Jun 17 '12 at 18:13
  • I think you should use `.prop("selectionStart")` instead of `.attr("selectionStart")` – Youssef Feb 03 '18 at 21:24