How to avoid multiple function call - javascript

I have click event function to create a new dom elements. Basically, every time I click a button. It allows create a new hyperlink tag.
I also want to have a functionality that if new created hyperlink clicked, I want to call different function.
Please have a look following code,
var id = 1;
$('#create').on('click', function() {
id ++
$('.players').append('<a href="#" class="new" data-id='+ id + '> ' + id + 'player</a>');
getId()
});
function getId() {
$('.new').on('click', function() {
var id = $(this).data('id')
alert(id);
});
}
My problem is I don't want to run getId() function everytime I clicked a button, But if I run getId() function alone, new created hyperlink won't effent that functionality.
Is anyway I can call getId() function once. and It still going to effect a new created hyperlink?

You can use one method to use the function only for once.
function getId() {
$('.new').one('click', function() {
var id = $(this).data('id')
alert(id);
});

Use delegation, then there is no need to attach the event handler function every time you append. Remove your getId() function and replace it with a delegated on() method:
var id = 1;
$('#create').on('click', function () {
id++;
$('.players').append('<a href="#" class="new" data-id=' + id + '> ' + id + 'player</a>');
});
$('.players').on('click', '.new', function(e) {
e.preventDefault();
var id = $(this).data('id')
alert(id);
});
JSFiddle

Try to use on() for dynamic elements like,
$(function(){
var id = 1;
$('#create').on('click', function() {
id ++;
$('.players').append('<a href="#" class="new" data-id='+id+'>'+id+'player</a>');
});
$(document).on('click','.new', function() {
//use ^ document or your parent element players
var id = $(this).data('id');
alert(id);
});
});

Related

"Add to Favorite / Remove" - Ajax not working

I want to create a "Add to favorite" & "Remove from favorite".
When I add the favorite, I change the ID of the DIV for remove.
I can successfully add to favorite but I can't undo.
This code for add
$('#addToFavoriteButton').click(function (event) {
var ItemID = $('#addToFavoriteButton').data('itemid');
event.preventDefault();
$.post('/system/ajax.php', {
AddFavID: ItemID
}, function (response) {
document['getElementById']('addToFavorite').id = 'RemoveFavoriteButton';
});
});
This code for remove
$('#RemoveFavoriteButton').click(function (event) {
var ItemID = $('#RemoveFavoriteButton').data('itemid');
event.preventDefault();
$.post('/system/ajax.php', {
RemoveFavbidID: ItemID
}, function (response) {
document['getElementById']('RemoveFavoriteButton').id = 'addToFavoriteButton';
});
});
Where am I wrong?
The main problem with your code is that you are assigning an event handler to a button and then changing the ID of that button, expecting it to trigger different code when it is clicked. That is wrong.
If you change the ID of an element it will still trigger the event handler that you originally assigned to it. See this example...
$("#button1").on("click", function() {
alert("you clicked button 1 - my id is " + this.id);
});
$("#button2").on("click", function() {
alert("you clicked button 2");
});
// change the ID of #button1 to #button2
$("#button1").attr("id", "button2");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button id="button1">button 1</button><br/>
<button id="button2">button 2</button><br/>
What makes more sense is to have a button to add a favourite, and a button to remove a favourite. You just hide the remove button until add is clicked, and vice-versa.
Like this...
var $add = $("#addFavourite");
var $remove = $("#removeFavourite");
$add.on("click", function() {
$add.hide();
$remove.show();
var itemId = $add.data("item-id");
alert("adding item " + itemId);
// do your AJAX stuff to add the favourite here
});
$remove.on("click", function() {
$add.show();
$remove.hide();
var itemId = $add.data("item-id");
alert("removing item " + itemId);
// do your AJAX stuff to remove the favourite here
});
#removeFavourite {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button id="addFavourite" data-item-id="123">add favourite</button>
<button id="removeFavourite" data-item-id="123">remove favourite</button>
I Suggested that you change the class instead of the id, since the id must be unique.
Or you can always use HTML5 data attribute, which you can use for both CSS styling (using attribute selector) and JS use (with dataset or jQuery's .data () method). see
Example:
HTML
<div id="el" data-test="data"></div>
vanilla javascript
var el = document.getElementById('el');
el.dataset.test // 'data'
by the way how you get the id is wrong -
document['getElementById']('RemoveFavoriteButton').id
You must use
vanilla javascript
document.getElementById('RemoveFavoriteButton').id;
jQuery
$('#RemoveFavoriteButton')attr('id');

Assign click-event on a new element in the event itself

I want to create a new element and assign this element the same event for onclick, which it has created it.
DEMO
$(function(){
var counter = 0;
$('.sub').click(function(event){
event.stopPropagation();
counter++;
$div = $(this); // makes more sense in the original code
$div.append('<div class="sub" title="subsub">subsub' + counter + '</div>');
//$div.find('.sub').click // <-- ?????
});
});
In my demo I want to create a new subsub for every sub, which was clicked. Than I want to add the same click event to the new subsub element.
Could anyone help me with this?
I've found nothing for this problem. Maybe I don't have the correct keywords for google or SO :/
Just use event Delegation
$(document).on('click', '.sub', function(event){
Your click events seem to be working correctly at this point,because you are using append which actually nests the new div inside the div that is clicked. Try using after and the functionality breaks.
$(function(){
var counter = 0;
$(document).on('click', '.sub', function(event){
event.stopPropagation();
counter++;
$div = $(this); // makes more sense in the original code
$div.after('<div class="sub" title="subsub">subsub' + counter + '</div>');
});
});
Check Fiddle
Why not create proper elements instead :
$(function(){
var counter = 0;
$('.sub').on('click', doStuff);
function doStuff(event) {
event.stopPropagation();
counter++;
var $div = $(this),
$sub = $('<div />', {'class':'sub',
title : 'subsub',
text : 'subsub' + counter,
on : {
click : doStuff
}
}
);
$div.append($sub);
}
});

Dynamically created form fields keep having the same ID

I dynamically add some text fields to my page with this line of code:
var textboxCount = 0;
$('#addFields').on('click', function(){
var TextField = document.createElement("input");
TextField.setAttribute("type", "text");
TextField.setAttribute("value", textboxCount);
TextField.setAttribute("name", "textbox");
TextField.setAttribute("class", "foo");
TextField.setAttribute("id", "textbox" + textboxCount);
TextField.setAttribute('onkeyup','doSomething('+textboxCount+');'); // for FF
TextField.onkeyup = function() {doSomething(textboxCount);}; // for IE
jQuery('#TextfieldList').append(eleText);
textboxCount += 1; //Increment the count
});
Now I need the unique ID of the field in this function:
function doSomething(id){
alert(id);
}
But when I call the function, I keep getting the same ID with every added field. The value in the textfield is correct though.
Extremely common problem. Change the keyup handler:
TextField.onkeyup = function(textboxCount) {
return function() {
doSomething(textboxCount);}; // for IE
};
}(textboxCount);
(Get rid of the "For FF" line; it's not necessary at all.)
If you don't introduce a new lexical scope somehow, then all of your event handlers will be referring to the exact same "textboxCount" variable. By doing something like what I've shown above (and there are variations), you ensure that each event handler has its own private copy of the counter as it stood at the time the handler was created.
Since you want to get the id of an element in its own event handler you can bypass the whole closure issue by just referencing this.id, where this is the element and id is its id property
TextField.onkeyup = function() {doSomething(this.id);};
You could just use the jQuery library you have in play:
$('#addFields').on('click', function () {
var thisId = $('.foo').length + 1;
var TextField = '<input type="text" name="textbox" class="foo" value="' + thisId + '" id="textbox' + thisId + '">';
jQuery(TextField).appendTo('#TextfieldList');
});
$('#TextfieldList').on('keyup', '.foo', function () {
doSomething($(this).attr('id'));
// or
doSomething(this.id);
});
function doSomething(id){
alert(id);
}
Sample jsFiddle: http://jsfiddle.net/mHT7Z/

trying to append content to DOM element

I'm trying to add a div to a row of content with the click of a button. My code works for the first row but not for any other row. Please help. This is the function for the button:
$(".addMMbtn").each(function() {
$(this).bind("click",
function() {
var thisRow = $(this).closest(".txtContentRow");
var thisTxt = thisRow.find(".txtContent");
var cellStr = '<div class = "mmCell prep"></div>';
$(cellStr).appendTo(thisTxt);
}
);
});
You can see a fiddle of the problem here: http://jsfiddle.net/z7uuJ/
$(".addMMbtn") will only find the elements present on the page and your code will only attach click event handler on them. Since you are adding the elements dynamically you should either use delegate or on (if you are using jQuery 1.7+) for click event to work on them too. Try this
Using delegate
$('#default').delegate('.addMMbtn', 'click', function() {
$('<div class = "mmCell prep"></div>')
.appendTo($(this).closest(".txtContentRow").find(".txtContent"));
});
Using on
$('#default').on('click', '.addMMbtn', function() {
$('<div class = "mmCell prep"></div>')
.appendTo($(this).closest(".txtContentRow").find(".txtContent"));
});
Demo
Instead of assigning click event directly on the button you need to use on():
$(document).on("click", ".addMMbtn",
function() {
var thisRow = $(this).closest(".txtContentRow");
var thisTxt = thisRow.find(".txtContent");
var cellStr = '<div class = "mmCell prep"></div>';
$(cellStr).appendTo(thisTxt);
}
);
In this case event handler will be subscribed to all newly added elements.
Code: http://jsfiddle.net/z7uuJ/5/
You don't need to loop through the elements to bind the handler:
$(".addMMbtn").live('click', function() {
var thisRow = $(this).closest(".txtContentRow");
var thisTxt = thisRow.find(".txtContent");
var cellStr = '<div class = "mmCell prep"></div>';
$(cellStr).appendTo(thisTxt);
});

JQuery attach event to method in instance

I have code that looks like this....
function Finder(id) {
this.id = id;
this.input = $("#" + this.id + " :input[type='text']:first")[0];
$(this.input).bind('keyup'....);
this.KeyUpHandler = function (e) { ..the event should trigger this.. }
this.input = the 1st element of type input found within 'id' which is what I will be referencing. This works fine for what I need.
What I want to do then is to bind the keyup event on 'input'. However I want the event to reference the instance method contained in my function - this.KeyUpHandler().
Also I need 'e' to be event that would have been passed into the function had I just done this on the markup for the input (onkeypress="keyuphandler();").
Any ideas how I can bind the event to the a function in the instance of the function I am working within?
function Finder(id) {
this.id = id;
this.input = $("#" + this.id + " :input[type='text']:first")[0];
that=this;
this.KeyUpHandler = function (e) { ..the event should trigger this.. }
$(this.input).bind('keyup', this.KeyUpHandler);
}
It is important that you call bind() after defining the function!
this.KeyUpHandler = function (e) { ..the event should trigger this.. }
$(this.input).bind('keyup', function(){
this.KeyUpHandler(event);
//more code can go here
});

Categories