Issue
i am trying to make a simple add emoji in contenteditable div. But i have a problem after added emoji cursor. I have created this DEMO from codepen.io . In this demo you can see there is a tree example emoji. When you click first emoji the emoji will adding in the #text contenteditable div. So far everything is okay but after the emoji has been added, it remains behind the cursor emojis.
After adding emoji I want you in front of the cursor emoji. How can i do that ? Anyone can help me here please ?
$(document).ready(function() {
$("body").on("paste", "#text", function(e) {
e.preventDefault();
});
$("body").on("keydown", "#text", function(event) {
//$('.character').text($(this).text().length);
if ($(this).text().length === 200 && event.keyCode != 8) {
event.preventDefault();
}
});
// Click to show clicked smiley
$("body").on("click",".emoji-box", function(){
var emojiKey = $(this).attr("data-smiley");
var emojiURL = $(this).attr("data-url");
$("#text").append("<img src="+emojiURL+" class='app-moji'>");
$("#text").focus();
});
});
html, body {
width: 100%;
height: 100%;
padding: 0px;
margin: 0px;
font-family: 'Helvetica Neue', helvetica, arial, sans-serif;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
-ms-text-size-adjust: 100%;
-webkit-texts-size-adjust: 100%;
-webkit-backface-visibility: hidden;
}
.container {
position:relative;
width:100%;
max-width:500px;
margin:0px auto;
padding-top:100px;
}
.input {
position:relative;
width:100%;
display:inline-block;
padding:5px 0px;
}
#text {
width:100%;
outline:none;
border:1px solid #d8dbdf;
padding:15px;
border-radius:3px;
-webkit-border-radius:3px;
font-weight:300;
font-size:14px;
color:#444;
line-height: 17px;
word-wrap: break-word;
text-align: left !important;
}
#text img {
width:25px;
height:25px;
vertical-align: middle;
}
.app-moji {
margin-left:5px;
margin-right:5px;
display: inline-block;
}
[contenteditable=true]:empty:before {
content: attr(placeholder);
display: block; /* For Firefox */
color:#d8dbdf;
}
.button {
float:right;
width:100px;
padding:8px;
text-align:center;
background-color:#d8dbdf;
border-raduis:3px;
-webkit-border-radius:3px;
cursor:pointer;
transition: background-color 1s linear;
-moz-transition: background-color 1s linear;
-o-transition: background-color 1s linear;
-webkit-transition: background-color 1s linear;
}
.button:hover {
background-color:#000;
color:#fff;
}
div.coloranimation {
transition: background-color 1s linear;
-moz-transition: background-color 1s linear;
-o-transition: background-color 1s linear;
-webkit-transition: background-color 1s linear;
background-color:#000000;
}
.ornekgoster {
position:relative;
width:100%;
padding:10px;
}
.ornek {
position:relative;
width:100%;
font-weight:300;
font-size:13px;
color:#444;
}
*{
box-sizing:border-box;
-webkit-box-sizing:border-box;
}
.ap-emoji {
position: relative;
float: left;
width: 100%;
padding-right: 10px;
overflow:hidden;
margin-top:20px;
}
.emoji-box {
position:relative;
width:29px;
height:29px;
float:left;
padding:2px;
cursor:pointer;
}
.emoji-box img {
width:100%;
position:relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="input">
<div id="text" placeholder="Wite something..." contenteditable="true"></div>
<input type="hidden" id="hidden" value=""/>
</div>
<div class="ap-emoji" id="emoji1">
<div class="emoji-box" data-smiley=":P" data-url="https://cdn.shopify.com/s/files/1/1061/1924/products/Hungry_Emoji_Icon_c20f1808-f3e2-4051-8941-3d157764e8cb.png"><img src="https://cdn.shopify.com/s/files/1/1061/1924/products/Hungry_Emoji_Icon_c20f1808-f3e2-4051-8941-3d157764e8cb.png"></div>
<div class="emoji-box" data-smiley=":D" data-url="http://www.bigmouthdesign.co.uk/wp-content/uploads/2017/08/Happy-Face.png"><img src="http://www.bigmouthdesign.co.uk/wp-content/uploads/2017/08/Happy-Face.png"></div>
<div class="emoji-box" data-smiley="<3" data-url="http://clipart.info/images/ccovers/1496184263Heart-Eyes-Emoji-png-transparent-2.png"><img src="http://clipart.info/images/ccovers/1496184263Heart-Eyes-Emoji-png-transparent-2.png"></div>
</div>
</div>
Solution
Actually what you want is an updated caret position post insert/delete. You also have to take into account that user can himself update the caret position anywhere inbetween the emojis inserted. A better solution will be to insert HTML at a given caret position.
This also works if you paste HTML content. Just remove your event.preventDefault() from your paste listener on body.
For contentEditable code you should refer solutions given by TimDown on stackoverflow. His are some of the highest rated solutions. ContentEditable gets complex easily. I am sure your requirements won't end here. Try using a good standard library if possible, will save you lot of time and effort.
Refer the snippet below, hope this helps.
$(document).ready(function() {
$("body").on("paste", "#text", function(e) {
e.preventDefault();
});
$("body").on("keydown", "#text", function(event) {
//$('.character').text($(this).text().length);
if ($(this).text().length === 200 && event.keyCode != 8) {
event.preventDefault();
}
});
// Click to show clicked smiley
$("body").on("click",".emoji-box", function(){
var emojiKey = $(this).attr("data-smiley");
var emojiURL = $(this).attr("data-url");
//$("#text").append("<img src="+emojiURL+" class='app-moji'>");
//$("#text").focus();
insertHTMLAtCaret("<img src="+emojiURL+" class='app-moji'>")
});
function insertHTMLAtCaret(html) {
var sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
// Range.createContextualFragment() would be useful here but is
// non-standard and not supported in all browsers (IE9, for one)
var el = document.createElement("div");
el.innerHTML = html;
var frag = document.createDocumentFragment(), node, lastNode;
while ( (node = el.firstChild) ) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);
// Preserve the selection
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
} else if (document.selection && document.selection.type != "Control") {
// IE < 9
document.selection.createRange().pasteHTML(html);
}
}
});
html, body {
width: 100%;
height: 100%;
padding: 0px;
margin: 0px;
font-family: 'Helvetica Neue', helvetica, arial, sans-serif;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
-ms-text-size-adjust: 100%;
-webkit-texts-size-adjust: 100%;
-webkit-backface-visibility: hidden;
}
.container {
position:relative;
width:100%;
max-width:500px;
margin:0px auto;
padding-top:100px;
}
.input {
position:relative;
width:100%;
display:inline-block;
padding:5px 0px;
}
#text {
width:100%;
outline:none;
border:1px solid #d8dbdf;
padding:15px;
border-radius:3px;
-webkit-border-radius:3px;
font-weight:300;
font-size:14px;
color:#444;
line-height: 17px;
word-wrap: break-word;
text-align: left !important;
}
#text img {
width:25px;
height:25px;
vertical-align: middle;
}
.app-moji {
margin-left:5px;
margin-right:5px;
display: inline-block;
}
[contenteditable=true]:empty:before {
content: attr(placeholder);
display: block; /* For Firefox */
color:#d8dbdf;
}
.button {
float:right;
width:100px;
padding:8px;
text-align:center;
background-color:#d8dbdf;
border-raduis:3px;
-webkit-border-radius:3px;
cursor:pointer;
transition: background-color 1s linear;
-moz-transition: background-color 1s linear;
-o-transition: background-color 1s linear;
-webkit-transition: background-color 1s linear;
}
.button:hover {
background-color:#000;
color:#fff;
}
div.coloranimation {
transition: background-color 1s linear;
-moz-transition: background-color 1s linear;
-o-transition: background-color 1s linear;
-webkit-transition: background-color 1s linear;
background-color:#000000;
}
.ornekgoster {
position:relative;
width:100%;
padding:10px;
}
.ornek {
position:relative;
width:100%;
font-weight:300;
font-size:13px;
color:#444;
}
*{
box-sizing:border-box;
-webkit-box-sizing:border-box;
}
.ap-emoji {
position: relative;
float: left;
width: 100%;
padding-right: 10px;
overflow:hidden;
margin-top:20px;
}
.emoji-box {
position:relative;
width:29px;
height:29px;
float:left;
padding:2px;
cursor:pointer;
}
.emoji-box img {
width:100%;
position:relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="input">
<div id="text" placeholder="Wite something..." contenteditable="true"></div>
<input type="hidden" id="hidden" value=""/>
</div>
<div class="ap-emoji" id="emoji1">
<div class="emoji-box" data-smiley=":P" data-url="https://cdn.shopify.com/s/files/1/1061/1924/products/Hungry_Emoji_Icon_c20f1808-f3e2-4051-8941-3d157764e8cb.png"><img src="https://cdn.shopify.com/s/files/1/1061/1924/products/Hungry_Emoji_Icon_c20f1808-f3e2-4051-8941-3d157764e8cb.png"></div>
<div class="emoji-box" data-smiley=":D" data-url="http://www.bigmouthdesign.co.uk/wp-content/uploads/2017/08/Happy-Face.png"><img src="http://www.bigmouthdesign.co.uk/wp-content/uploads/2017/08/Happy-Face.png"></div>
<div class="emoji-box" data-smiley="<3" data-url="http://clipart.info/images/ccovers/1496184263Heart-Eyes-Emoji-png-transparent-2.png"><img src="http://clipart.info/images/ccovers/1496184263Heart-Eyes-Emoji-png-transparent-2.png"></div>
</div>
</div>
Answered By - Priyesh Diukar
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.