Reputation: 251
I have these two functions to add a selected emoji to the input field.
However the first click it doesnt show any emoji's, the second click it shows two emoji's and on the third click it shows four emoji's.
Is there any way to fix this?
Thanks.
HTML:
<a id="smiley" title="smiley" href="#" onclick="enableTxt(this)" >😃</a>
<a id="sadface" title="sadface" href="#" onclick="enableTxt(this)" >😒</a>
JQuery:
function enableTxt(elem) {
var id = $(elem).attr("id");
//Add emoji to chat when clicked with selected id
$("#" + id).click(function() {
$('#usermsg').val($('#usermsg').val() + $("#" + id).html());
});
}
Upvotes: 5
Views: 4009
Reputation: 61904
You're getting mixed up between inline event handlers and unobtrusive event handlers. Basically every time you run "enableTxt" it sets a new "click" event handler onto the same button. So the first time you click nothing happens because it just creates a handler ready for next time. Then the second time you click it runs "enableTxt" (and thus creates another new handler) and the handler which "enableTxt" created the previous time. Then the next time, this effect is doubled, etc etc.
This will work much better:
<a id="smiley" title="smiley" href="#" class="emoji" >😃</a>
<a id="sadface" title="sadface" href="#" class="emoji" >😒</a>
JS
// this wrapper stops the code from declaring the handler until the page has loaded
// all the elements, otherwise the element we want to bind to might not exist yet
$(function() {
$(".emoji").click(function() {
$('#usermsg').val($('#usermsg').val() + $(this).html());
});
});
Upvotes: 5
Reputation: 4298
You should not use click event inside caller function, it binds click event in every function call so it is increasing, remove click event binding from inside the function
function enableTxt(elem) {
$('#usermsg').val($('#usermsg').val() + $(elem).html());
}
demo https://jsbin.com/misiwuyena/edit?html,js,output
Upvotes: 3
Reputation: 42054
You define this event handler:
$("#" + id).click(function() {
inside the enableTxt function. That means, each time you call the outer function a new event handler is added. Hence your issue.
If you need to have the inline code, i suggest to add the event parameter for future necessities and so, the reduced code is:
function enableTxt(elem) {
document.querySelector('#usermsg').value += elem.textContent;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="smiley" title="smiley" href="#" onclick="enableTxt(this, event)" >😃</a>
<a id="sadface" title="sadface" href="#" onclick="enableTxt(this, event)" >😒</a>
<input type="text" id="usermsg">
Upvotes: 3
Reputation: 2075
Each time enableTxt
is called, it will define a new click handler on the element, that's why it adds multiple emojis.
You should insert the emoji directly, for example:
function enableTxt(elem) {
$('#usermsg').val($('#usermsg').val() + $(elem).html());
}
Demo:
function enableTxt(elem) {
$('#usermsg').val($('#usermsg').val() + $(elem).html());
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="smiley" title="smiley" href="#" onclick="enableTxt(this)" >😃</a>
<a id="sadface" title="sadface" href="#" onclick="enableTxt(this)" >😒</a>
<input id="usermsg">
Upvotes: 2