addEventListener firing twice - javascript

I'm creating a simple phonebook, that adds person name, last name and phone into a div and into the DOM, with option to delete this div with click event.
I have a class called Phonebook which contain these 2 functions:
//add an event button to all divs inside the DOM
this.deleteBtnEvent = function(){
var _this = this;
//get all the divs that currently on the DOM
var deleteBtn = document.getElementsByClassName('delete');
for (var i = 0; i < deleteBtn.length; i++) {
deleteBtn[i].addEventListener('click', function(e){
_this.removeContact(e.target.parentElement.attributes.index.value);
});
}
};
//remove the div from the array and from the DOM
this.removeContact = function(index){
var contactsHolder = document.getElementById('contacts');
var contact = document.getElementsByClassName('contact');
this._contacts.splice(index, 1);
contactsHolder.removeChild(contact[index]);
//update localstorage
var stringArr = JSON.stringify(this._contacts);
localStorage.setItem('data', stringArr);
console.log('current: ');
console.log(this._contacts);
};
for some reason the addEventListener is firing twice.
first time that the addEventListener is called, the function delete the div from the DOM and the array, the second time the listener is fired, i'm getting an error because the div with the same ID doesn't exist, because its already deleted.
I'm wondering if there's a way to solve this issue.

In addContact(), you call this.deleteBtnEvent(), presumably to bind deletion to the delete button that was just added. In deleteBtnEvent(), however, you're binding an event listener to all delete buttons on the page. This means the following will happen:
Add a contact. A new contact will show up with a delete button that has a listener.
Add a second contact. A new contact will show up with a delete button that has a listener, and a second listener will be added to the first button.
Add a third contact. A new contact will show up with a delete button that has a listener, and a third listener will be added to the first button, and a second listener will be added to the second button.
etc....
So, in deleteBtnEvent(), don't add (duplicate) listeners to all delete buttons. Instead, only add a listener to the delete button that was just created via addContact().

Related

Event gets called multiple times

I am calling JQuery global function on button click
$.fn.editFaculty = function() {
var id = $(this).data('id');
var name = $(this).data('name');
$('#editFacultyName').val(name);
console.log(id); //this works fine
$('#update_btn').click(function (e){
e.preventDefault()
console.log('btn ' + id) //this keeps on adding and sends multiple requests...
})
};
on button click
onclick="$(this).editFaculty();"
On button click this function gets called along with a popup and shows value in popup, then when I click update_button button then I am doing updating value (through ajax but not included in question).
Issue is when I click a button with id=1 (id is not id attribute of html it means the button which corosponds to item which has id 1),
first console.log(id); shows 1 and second console.log('btn' + id) shows btn 1. When I again click on other button with id 2
first console.log(id); shows 2 and second console.log('btn' + id) shows btn 1 btn 2.
$('#update_btn').click(function (e){ gets called twice and then keeps on going to 3, 4, 5, ... until I refresh page.
To answer your question, I ask you (not a question but an imperative) to say to yourself: "How is the event listener function added to the element?"
The response is, via the click method in function body.
The response is, via the onclick property.
So you need to determine how you are going to attach the listener.
Variants of solution
Variant 1get the $('#update_btn').click( up to until the }) outside the body of editFaculty function and get rid of onclick in html!
Variant 2 get rid of click method there and use just the onclick.

How to implement manual click event on dynamically generated element

i have a mainbox inside which some more boxes are dynamically generated.
// first time retrive
$.post("dataretrive.php", {
}, function(data, status) {
document.getElementById('mainbox').innerHTML = data;
timer();
});
then on click on these subboxes some i am implementing some functionality
$('.boxes-main').unbind('click').on('click', '.subbox', function(e){
var value1 = $(this).attr('data');
var value2 = $(this).attr('data2');
var value3 = $(this).attr('data3');
var value11 = $(this).attr('data4');
var value12 = $(this).attr('data5');
var value13 = $(this).attr('data6');
...... // some more functionality with these data which i think doesn't matter for this question for this question
});
As i want to implement shortcuts to these subbox like when user press 1 it trigger a click event on that box. I also have ID's associated with that. like box1 , box2, box3 and so on. and i am trying to put a click event of that box when key 1 is pressed.
$(document).keypress(function(e) {
if(e.charCode == 49) {
$('#box1').click();
}
});
I had also tried trigger function , $("boxes-main #box1').click(); but nothing works because contents are dynamically generated. someone tell me please how to implement manual click event on dynamically generated element.
and don't get confused between boxes-main and mainbox both are class and id of same div element.
Based on your comment:
and don't get confused between boxes-main and mainbox both are class
and id of same div element.
It is not the click generation that is broken, but you are targeting the wrong ancestor in your delegated click event handler. Go higher up the ancestors to a non-changing element. document is the best default if nothing else is closer.
$(document).on('click', '.subbox', function(e){
Notes:
Don't mix bind with on. Use off instead
You don't need off/unbind at all in this example

how an event can be expired or disapear by any other event

var foo = new function(){
$scope.MessageSpan="Item added successfully";}
The above function is called when clicking on Add button for example. Now, for any other button click, If I want to hide this message, I have to update the span text in all other buttons in the page, but that is too much work.
So, once the span is filled with "Item added successfully", can the text at that span be automatically updated/removed when I click on any other event? Instead of doing that explicit?
Thank you
You can create directive which will display your message, then will set event listener for mouse click on $window, and unregister this listener when you click something.
Sketch:
var handler = function(){
$scope.MessageSpan = undefined;
angular.element($window).off('click',handler)
};
$scope.MessageSpan = "Item added successfully";
angular.element($window).on('click', handler);

Titanium: Auto-select first row of dynamically created rows

I have a two tab layout. When the first tab button is clicked the rows are filled using data retrieved remotely. This is the same for the second tab but the layout of the data is different.
My problem is when you switch between tabs I need to fire a click event on the first row of each tab.
I am building this app for android only.
Any help is greatly appreciated...
EDIT: This is dummy code of the top of head, hope it makes a bit more sense.
leftTableView = Ti.UI.createTableView({
data: populateTableView(0),
allowsSelection:true
});
function populateTableView(byType)
{
for(length of array loop){
var tableViewRow=Ti.UI.createTableViewRow({
my_obj:myObj[i]
});
tabledata=[]
tableViewRow.addEventListener('click',function(e){
e.row.setBackgroundImage('/images/selected-row-background.png');
}
if byType 0
loop array display row for each object element
tableData.push(tableViewRow);
return tabledata
if byType 1
loop array display row for each object element, display differently
tableData.push(tableViewRow);
return tabledata
}
}
tab 1 click event listener
populateTableView(0);
leftTableView.data[0].rows[0].fireEvent('click');//this fires but says e.row.setBackgroundImage is undefined
tab 2 click event listener
populateTableView(1)
leftTableView.data[0].rows[0].fireEvent('click');//this fires but says e.row.setBackgroundImage is undefined
Listen for the blur event on the tabGroup and take action as each one of the tabs become the active tab
http://docs.appcelerator.com/titanium/latest/#!/api/Titanium.UI.TabGroup-event-blur
tabGroup.addEventListener('blur', function(_event) {
var activeTab = _event.tab;
// now that you have the activeTab, get the window, then the
// table and call a method to simulate a click on the first
// row
});
passing data when firing event
var row = leftTableView.data[0].rows[0];
row.fireEvent('click', { row : row } )

last button of dynamic list not always firing click event with jQuery

I have a simple div that I dynamically append buttons to, now all the the button click events fire except for the last element in the list, which sometimes it does fire sometimes it doesn't. If I click on the left or right icon in the button it works just fine, if I click on the text or middle of the button sometimes it fires sometimes it doesn't.
<div id="btn-list"></div>
on page load after my dom is loaded I append a random number of buttons and I add the on click event listener to the buttons.
$( function () {
for (var i=0;i<arr.length;i++) {
var item = arr[i];
var btn = $(document.createElement('button'));
btn.text(item['description']);
btn.attr('id', i);
$("#btn-list").append(btn);
}
$('#btn-list').on('click', 'button', function (e) {
e.preventDefault();
e.stopPropagation();
window.location.replace('blah.html');
});
}
I'm using jQuery 2.0.
Without extra code, this snippet shouldn't fail. Have in mind that a reference to the last button added is kept in btn, thus if at some other part of the code the element or its events are modified it will alter the expected behavior.
Have you added some debug output to confirm the click event is not fired? http://jsfiddle.net/AstDerek/gKJNe/
$('#btn-list').on('click', 'button', function (e) {
e.preventDefault();
e.stopPropagation();
alert('blah.html');
})
Added a simple test, it doesn't fail at the browser I tested, maybe its limited to your browser? http://jsfiddle.net/AstDerek/gKJNe/1/
Now, what happens if you encapsulate the button creation into its own function?
function create_button (index,properties) {
var btn = $(document.createElement('button'));
btn.text(properties.description);
btn.attr('id',index);
$("#btn-list").append(btn);
return btn;
}
for (var i=0;i<arr.length;i++) {
create_button(i,arr[i]);
}
Finally, just as a workaround, why not add a hidden button as last step?
for (var i=0;i<arr.length;i++) {
create_button(i,arr[i]);
}
create_button(-1,{description:''}).hide();

Categories

Resources