1

I'm having a contenteditable div. I want to replace smiley code to smiley image on keyup/keydown events. I've understood the marked answer code of question Replace smiley codes to images for replacing smiley codes to images.

And so I tried to modify it for keyup/keydown events but, it is not working. Below is the snippet of modified code with that answered one.

var emoticons = {
        ':-)' : 'chair.gif',
        ':)'  : 'cheers1.gif',
        ':D'  : 'clapping.gif',
        ':-|' : 'dance.gif'
      };

    var url = "http://digitalsetups.com/emoji/";
    var patterns = [];
    var metachars = /[[\]{}()*+?.\\|^$\-,&#\s]/g;
      
    // build a regex pattern for each defined property
    for (var i in emoticons) {
       if (emoticons.hasOwnProperty(i)){ // escape metacharacters
         patterns.push('('+i.replace(metachars, "\\$&")+')');
       }
    }
    // Building Regex Expression
    var regex = new RegExp(patterns.join('|'),'g');

    // My modification starts here to replace smiley code to image on keyup/keydown events
    $(document).ready(function(){
        $("#chatMessage").keyup(function(){
        // var start = this.selectionStart;
            $("#chatMessage").html($("#chatMessage").html().replace(regex, 
        function (match) {
            return typeof emoticons[match] != 'undefined' ?
                   '<img src="'+url+emoticons[match]+'"/>' :
                   match;
         }));
         // this.selectionEnd = start;
            });
    });
#chatMessage {
max-height: 20px;
max-width: 400px;
overflow: auto;
}
<html>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
    </script>
   </head>
   <body>
      <div id="chatMessage" contenteditable>This is contenteditable div. Press space to change :) into image. Or :-) into another image.</div>
   </body>
</html>

UPDATE:

  1. I have updated JQuery code. Changed val() to html() in keyup function() definition. When I changed it, codes change to image upon keyup but the cursor moves to beginning of line every time I write 1 character.
  2. I've tried the solution of selectionStart and selectionEnd (which I've commented it in the code.) Nothing happens. Also, if I specify start position to be selectionEnd and end position to be selectionStart then, cursor works but smiley codes do not change then.
sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Suman Khan
  • 11
  • 3

2 Answers2

0

.val() is not the appropriate method to use for this - you want to get and set the innerHTML of the element, so use jQuery's .html() method.

Josiah Keller
  • 3,635
  • 3
  • 23
  • 35
  • Alright. I've changed both val() to html() and it is now changing codes to images but, it is allowing me to write just 1 character. As soon as I write 1 character, the pointer position moves to the start of div. – Suman Khan Jun 18 '17 at 21:12
  • @SumanKhan Ah yes, because setting the HTML destroys the previous contents of the div. To fix that you're going to have to look at the [Selection API](https://developer.mozilla.org/en-US/docs/Web/API/Selection). It's kind of gross, but it does the job. – Josiah Keller Jun 18 '17 at 21:57
  • Problem. :/ Please, see the updated part of question. – Suman Khan Jun 19 '17 at 07:02
0

This is more efficient version which uses on for all contenteditables, Especially if your contenteditables is chat box becuase sometimes user not only keyup on it.

var emoticons = {
        ':-)' : 'chair.gif',
        ':)'  : 'cheers1.gif',
        ':D'  : 'clapping.gif',
        ':-|' : 'dance.gif'
      };

    var url = "http://digitalsetups.com/emoji/";
    var patterns = [];
    var metachars = /[[\]{}()*+?.\\|^$\-,&#\s]/g;
      
    // build a regex pattern for each defined property
    for (var i in emoticons) {
       if (emoticons.hasOwnProperty(i)){ // escape metacharacters
         patterns.push('('+i.replace(metachars, "\\$&")+')');
       }
    }
    // Building Regex Expression
    var regex = new RegExp(patterns.join('|'),'g');

    // My modification starts here to replace smiley code to image on keyup/keydown events
    $(function(){
        $("#chatMessage").on('blur keyup paste input', function(){
        // var start = this.selectionStart;
            $("#chatMessage").html($("#chatMessage").html().replace(regex, 
        function (match) {
            return typeof emoticons[match] != 'undefined' ?
                   '<img src="'+url+emoticons[match]+'"/>' :
                   match;
         }));
         // this.selectionEnd = start;
            });
    });
#chatMessage {
max-height: 20px;
max-width: 400px;
overflow: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div id="chatMessage" contenteditable>This is contenteditable div. Press space to change :) into image. Or :-) into another image.</div>
Kamarul Anuar
  • 312
  • 4
  • 16