Too many click handlers being called - javascript

I am using the following function to dynamically populate a div with some text and a button using the array messages:
var populateMessages = function(messages){
for (var index in messages){
(function(){
var id = index;
$("#messages").append(messages[index]["title"])
$("#messages").append("<button>Open</button><br/>").click(function(){console.log(message["id"])})
}())
}
};
This code correctly populates the div with the text and the button. The problem is that if I click on ANY of the buttons, the click handlers for ALL of them fire. So with two buttons, it should log "0" if I click on the first one and "1" if I click on the second. Instead, if I click on either, it logs "0 1"
I'm not super up on Javascript so I don't know what the issue is.

The return value of
$("#messages").append("<button>Open</button><br/>")
is #messages, not the button that was added. So each time through the loop you're adding another click handler to #messages, not the button.
Try:
$.each(messages, function(index, message) {
$("#messages").append(message.title);
$("<button>Open</button>").click(function() {
console.log(message.id);
}).appendTo("#messages");
$("#messages").append("<br/>");
});

$("#messages").append("<button>Open</button><br/>")
Returns #messages not button so you are setting the click event to #message.
Try this:
$("#messages").append("<button>Open</button><br/>").find("button:last").click(/blabla/)

Related

Pass [Object object] to a function

Hi I have a button that passes this to a function as below:
<div class="itemRow">
Delete
</div>
For the sake of keeping this simple, I have removed other elements within the itemRow div. Essentially this div contains information about an item as well as a button to delete that item. Every item will have a itemRow div so there are many on the page. I want to determine which row the button call came from so that when the item is actually deleted, the correct row is removed.
function deleteMessage(row, itemNum){
$('#deleteMsgModal').modal('show');
//Change the modal buttons's onclick handler
$("#deleteConfirmBtn").click(function(){ deleteRow(row, itemNum);});
}
So the above function will display a modal that asks for confirmation. The onclick handler of the button in the modal takes in the this object and the item number which then goes to a seperate function deleteRow that actually deletes the row and removes the row.
function deleteRow(contentRow, itemNo){
var item = itemNo;
//do some ajax code to remove the row from the database...
...
//then once it is removed then to remove the div that is showing the row...
$(contentRow).parent().remove();
}
The problem is that when the #deleteConfirmBtn button's click handler takes in this as an argument, it displays it as [Object object] which will not work. Is there a way I can get around this so that the final function can delete the correct div?
you need to wrap 'this' in $ sign. so in your case would be $(row)
Please clarify,
"The problem is that when the #deleteConfirmBtn button's click handler takes in this as an argument, it displays it as [Object object] which will not work."
Where is the html for this and how are you passing in 'this' value to this function.
My concern, Why is it required to pass this, when you are already binding click event to the button. this value should be already passed along in the function.
Thanks
Ashish
You may use the event handling that comes with jQuery. If you register the click handlers in Javascript, you don't need to pass this to the function. jQuery gives you that reference automatically.
I have done several changes to your code to make a running example without using bootstrap:
Each delete button now haves a data property data-row="x" where x is the number of the row. I have also added a tag class to retrieve all these buttons: .btn-delete.
As you can see, the click handler is registered on Javascript. Once you click a delete button, the row number is retrieved from the previously set data porperty.
Each time you process a Confirm delete event, you need to unbind the click handler. If you don't do it, you may end with unexpected behaviours where the previous delete actions are triggered again.
// Event delegated subscription for all the delete events
$(document).on('click', '.btn-delete', function(event) {
// Prevent navigation event of the anchor
event.preventDefault();
// Get the info of the clicked event
let rowElement = $(this);
let rowNumber = rowElement.data('row');
// Show the confirmation message
$('#deleteMsgModal').show();
//Change the modal buttons's onclick handler
$("#deleteConfirmBtn").click( function(ev) {
// Prevent event propagation
ev.preventDefault();
// Remove the 'modal' message and unbind this click event handler
$('#deleteMsgModal').hide()
$(this).unbind('click');
deleteRow(rowElement, rowNumber);
});
});
function deleteRow(contentRow, itemNo){
let item = itemNo;
alert('Item #' + itemNo + ' removed succesfully');
// do some ajax code to remove the row from the database...
// ...
// then once it is removed then to remove the div that is showing the row...
contentRow.parent().remove();
}
#deleteMsgModal {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="itemRow">
<span>Row 1</span>
Delete
</div>
<div class="itemRow">
<span>Row 2</span>
Delete
</div>
<div class="itemRow">
<span>Row 3</span>
Delete
</div>
<div id="deleteMsgModal">
You are about to delete a row. Are you sure?
Confirm delete
<div>

How to simulate click event on DIV element with JS/jQuery

http://services.groupes.be/ibrunet/ibrunet.aspx?lg=NL
I am trying to simulate click events on DIV elements with class="x-grid-cell-inner"(with text Ibrunet, Signaletiek..)
First I inserted jQuery.
javascript:var s=document.createElement('script');s.setAttribute('src', 'http://code.jquery.com/jquery.js');document.getElementsByTagName('body')[0].appendChild(s);alert("loaded");void(s);
Then I tried this
var bedragenDivClass = "x-grid-cell-inner ";
var bedragenDivText = "Bedragen";
var divs = document.getElementsByClassName(bedragenDivClass);
for (var i = 0, len = divs.length; i < len; i++) {
if(divs[i].innerText.localeCompare(bedragenDivText) == 0){
alert("found");
};
};
And I've got referrence to this DIV but then I tried several different functions to trigger click event without any success
.trigger()
.triggerHandler()
.click()
When I open Chrome Dev Tools I can see several handler bounded to that DIV but I dont know how to trigger them
Unusual thing is that I could simulate click on input elements on right panel
var contractTypeInputId = "Cmb_Type_Contrat_Ibrunet_PLus-inputEl";
var contractTypeInput = document.getElementById(contractTypeInputId);
contractTypeInput.click();
Also I could click on elemenets of that input that show after script click it.
Since those DIV's don't have id attribute and I thought I need id to trigger the event I've gave them inside Dev Tools and I could retrieve it after but again no success with triggering onClick event.
The strangest thing is when I run something like this:
$("div").click();
I can see many DIV's beign clicked but those with that class I specified are not affected.
If I can trigger the event as simple as clicking on that DIV why I failed simulating it?
Using jquery
$(".-grid-cell-inner:contains(Ibrunet, Signaletiek)").click(function () {
alert(1);
});
$(".-grid-cell-inner:contains(Ibrunet, Signaletiek)").trigger("click");

Event appears to only fire sometimes?

The Code
I set up a jsFiddle at http://jsfiddle.net/6vd5C/1/
The JavaScript code in question:
var global_loggedOnUser = "User1";
$(function(){
var viewmodel = (function(){
this.feedbacktype = ko.observable("None");
this.currentPage = ko.observable(location.href);
this.currentUsername = global_loggedOnUser;
this.updateFeedbackType = function(item, event)
{
var newText = $(event.target).children("span").text();
feedbacktype(newText);
};
return{
pageUserIsOn : currentPage,
theUser : currentUsername,
feedbackType: feedbacktype
};
})();
ko.applyBindings(viewmodel);
});
The Goal
Whenever someone clicks on the button of the submission, I'd like to see the "Current Type" bullet point update to indicate caption on the clicked button.
The Problem
Sometimes the text updates to the correct words; sometimes it updates but is a null value.
I cannot find a pattern or rhyme/reason; sometimes after being blank, clicking another element and then clicking the element that previously returned null now returned the correct text.
What am I doing wrong?
Instead of using $(event.target) use $(event.currentTarget).
I'd like to expand a bit and explain the difference, when you use event.target you're getting the element that dispatched the event (the actual element literally) - like in your case, if you click on the <i></i> element which is nested within the button element, it will return the <i></i> notice that if you return the code to event.target and you click on the edge of your button it will work as expected.
In the case of event.currentTarget you're getting the element you're binding your listener to (which in your case is the actual button).

Trigger onclick when page is loaded

I have a set of radio buttons with an onclick event that hides/shows an area of the website. The onclick also enables/disables spry validation.
The onclick is working great! However, not sure how to trigger the onclick when the page is loaded and the radio button is marked as clicked.
For example, the user may select radio button on the main page. Then later in the form process the user may want to edit the input that they put in. I would then check the radio button that the user had selected on the main page. Since the user has not clicked the radio button the hidden area still remains hidden.
window.onready=function()
{
if(document.getElementById('yourRadioButtonId').checked) {
//call your function, that you want to be triggered, as you will have the same call back function bounded for your onclick event
}
or
window.onready=function()
{
var radioButton=document.getElementById('yourRadioButtonId');
if(radioButton.checked) {
radioButton.click();
}
}
Note: Not not all browsers allow simulated events in this way. Please see the jQuery source for the trigger method to see how all the browser quirks are handled.
The best way to handle this is to write a helper function. Later, this helper function can be called by both of onClick (on radio button) and onLoad (on body element) events. This function will get the valu of your radio button and will do the stuff based on the result.
For example:
function handleRadioButtonStateAction() {
var radioButtons = document.getElementsByName('theRadioButtonName');
for (var x = 0; x < radioButtons.length; x ++) {
if (x == yourDesiredButton && radioButtons[x].checked) {
//do action
}
}
}

if statement around onclick

What is the best way to ignore running code when a button is clicked? I am trying the following but I currently get not reaction how I want it done.
if (!document.getElementById('btn_Cancel').getAttribute('onclick')) {
// code not to be ran when button is clicked
By default code gets ran when a textbox goes onblur so do not want that code ran when button gets clicked
}
You're going to want to make a reference to that element, so you don't end up looking it up each time it's clicked and you'll need a variable to keep track of whether it's been clicked or not:
var cancelButton = document.getElementById('btn_Cancel'),
clicked = false;
cancelButton.addEventListener('click', function() { clicked = !clicked; }, false);
// assuming this is in a loop or something:
if(!clicked) {
// running code
}
else {
// clicked, do nothing
}

Categories