how to attach onclick event to an array of elements (mootools) - javascript

Is there a syntax for the following thing:
$$('.a-lot-of-elems').addEvent('someevent',somefunction);

First off - the following will work just fine.
$$(selector).addEvents({
click: fn
});
Don't use for, to iterate through an element collection, use each instead:
$$(selector).each(function(el){
el.addEvents({
click: fn
});
});
Here's a working example: http://jsfiddle.net/EPYBx/

You are just missing the event type.
var someFunction = function(e) {
alert('clicked!');
}
$$('.a-lot-of-elems').addEvent('click', somefunction);
Alternatively, you can use
$$('.a-lot-of-elems').addEvent('click', function(e) {
alert('clicked!');
});

something like
var elements = $$('.a-lot-of-elems')
for(var i = 0 ; i < elements.length ; i = i + 1)
{
elements[i].addEvent(somefunction);
}
should do ya!

Related

How to generate dynamically events in jquery?

I'm trying to set event attributes on a group of drop-down generated dynamically but for some reason the events aren't working.
Heres's my code.
$(document).ready(function () {
var idRoomTypesList = $("#idRoomTypesList").attr('value').split("_");
for (var i = 0; i < idRoomTypesList.length; i++) {
$("#roomTypeID-" + idRoomTypesList[i] + "_nRentedRooms").attr("onchange", generatePrice);
}
});
var generatePrice = function () {
alert(this.value().toString());
}
I think this must work for you
$(document).ready(function () {
var idRoomTypesList = $("#idRoomTypesList").attr('value').split("_");
for (var i = 0; i < idRoomTypesList.length; i++) {
$("#roomTypeID-" + idRoomTypesList[i] + "_nRentedRooms").on("change", generatePrice);
}
});
var generatePrice = function () {
alert($(this).val());
}
And have a look at this:
How to use the jQuery Selector in this web application?
HTML:
<select class="dynamicSelects">
....
</select>
JS:
var generatePrice = function () {
alert(this.value);
};
$(document).ready(function () {
$('body').on('change', '.dynamicSelects', generatePrice);
});
This is an example of using the on method provided by jQuery and delegating the events. This means that even if those drop downs are not in the DOM yet you can still attach the event to it and whenever they exist in the DOM the event will fire. It basically says attach these events to body but fire on elements with the class dynamicSelects. This covers adding any other dynamically generated drop downs with this class later as well.
Setting attributes to attach events, while it may work, should really be done using the on method or in plain JS the addEventListener, in my opinion.
Also when operating on plain DOM elements the value property is not a function so no value() is needed. Just this.value. And you don't need to convert it to a string because value returns a string. If it were a jquery object then you can do $(this).val() which is a function.
I only suggest this change of course because if you are going to use a library like jQuery at least take advantage of the things it offers.
Did you search into the jQuery documentation?
$(document).ready(function () {
var $idRoomTypesList = $("#idRoomTypesList").attr('value').split("_");
for (var i = 0; i < idRoomTypesList.length; i++) {
$("#roomTypeID-" + idRoomTypesList[i] + "_nRentedRooms").attr("onchange", generatePrice);
}
$( "#idRoomTypesList" ).change(generatePrice());
});
var generatePrice = function () {
alert(this.value().toString());
}

Passing this to a method?

p.num = 100;
$('body').on('click', '.del', this.delete.bind(this));
p.delete = function(e) {
console.log(this.num); //100
//how can I get the .del element?
}
I'm trying to get the element that produced the click, but I also need access to the num property.
How can I access both types of 'this' inside my delete method?
The callback for an event receives an Event object that you can use to retrieve the element on which the event was called.
function(e) {
var element = $(e.target); //This is the element that the event was called on.
}
Disclaimer : This is the my exact answer (adapted with the current code) taken from here : Pass additional arguments to event handler?
Yet, the question doesn't seem to be an exact duplicate (but i may be wrong).
As said in the documentation of .on, you can pass datas to your event.
.on( events [, selector ] [, data ], handler )
data
Type: Anything
Data to be passed to the handler in event.data when an event is triggered.
So your event could look like that :
p.num = 100;
$('body').on('click', '.del', {object : this}, this.delete);
p.delete = function(e) {
var myObj = e.data.object;
// [myObj] will be your plugin
// [this] will be the clicked element
// [e] will be you event
}
if you're using jquery, you can combine those functions all into one like below:
note: num is an attribute so you have to use .attr().
$(document).ready(function() {
$('body').on('click', '.del', function() {
var num = $(this).attr('num');
alert('click function and num = ' + num);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Delete
or if you really want to keep them separate functions....:
$(document).ready(function() {
$('.del').on('click', function() {
deleteThis($(this));
});
});
function deleteThis(element){
var num = element.attr('num');
alert('click function and num = ' + num);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Delete
also, if youre using separate functions for the click and the delete, pass the element from click to delete: pass element - callDeleteFunction($(this)), and retrieve element - myDeleteFunction(element aka $(this))
I'm not sure what you're asking about but maybe this is what you want:
var p = {};
p.num = 100;
$('body').on('click', '.del', p.delete); // don't bind to this
p.delete = function(e) {
console.log(p.num); // here you still can call p
// this is del DOM element
}

Adding click event listener to elements with the same class

I have a list view for delete id. I'd like to add a listener to all elements with a particular class and do a confirm alert.
My problem is that this seems to only add the listener to the first element with the class it finds. I tried to use querySelectorAll but it didn't work.
var deleteLink = document.querySelector('.delete');
deleteLink.addEventListener('click', function(event) {
event.preventDefault();
var choice = confirm("sure u want to delete?");
if (choice) {
return true;
}
});
List:
<?php
while($obj=$result->fetch_object())
{
echo '<li><a class="delete" href="removeTruck.php?tid='.$obj->id.'">'.$obj->id.'</a>'
. '
</li>'."\n";
}
/* free result set */
$result->close();
$mysqli->close();
?>
You should use querySelectorAll. It returns NodeList, however querySelector returns only the first found element:
var deleteLink = document.querySelectorAll('.delete');
Then you would loop:
for (var i = 0; i < deleteLink.length; i++) {
deleteLink[i].addEventListener('click', function(event) {
if (!confirm("sure u want to delete " + this.title)) {
event.preventDefault();
}
});
}
Also you should preventDefault only if confirm === false.
It's also worth noting that return false/true is only useful for event handlers bound with onclick = function() {...}. For addEventListening you should use event.preventDefault().
Demo: http://jsfiddle.net/Rc7jL/3/
ES6 version
You can make it a little cleaner (and safer closure-in-loop wise) by using Array.prototype.forEach iteration instead of for-loop:
var deleteLinks = document.querySelectorAll('.delete');
Array.from(deleteLinks).forEach(link => {
link.addEventListener('click', function(event) {
if (!confirm(`sure u want to delete ${this.title}`)) {
event.preventDefault();
}
});
});
Example above uses Array.from and template strings from ES2015 standard.
The problem with using querySelectorAll and a for loop is that it creates a whole new event handler for each element in the array.
Sometimes that is exactly what you want. But if you have many elements, it may be more efficient to create a single event handler and attach it to a container element. You can then use event.target to refer to the specific element which triggered the event:
document.body.addEventListener("click", function (event) {
if (event.target.classList.contains("delete")) {
var title = event.target.getAttribute("title");
if (!confirm("sure u want to delete " + title)) {
event.preventDefault();
}
}
});
In this example we only create one event handler which is attached to the body element. Whenever an element inside the body is clicked, the click event bubbles up to our event handler.
A short and sweet solution, using ES6:
document.querySelectorAll('.input')
.forEach(input => input.addEventListener('focus', this.onInputFocus));
You have to use querySelectorAll as you need to select all elements with the said class, again since querySelectorAll is an array you need to iterate it and add the event handlers
var deleteLinks = document.querySelectorAll('.delete');
for (var i = 0; i < deleteLinks.length; i++) {
deleteLinks[i].addEventListener('click', function (event) {
event.preventDefault();
var choice = confirm("sure u want to delete?");
if (choice) {
return true;
}
});
}
(ES5) I use forEach to iterate on the collection returned by querySelectorAll and it works well :
document.querySelectorAll('your_selector').forEach(item => { /* do the job with item element */ });

How to remove the selected value from the array using jquery

I want to remove particular value from the array. I have written code like:
$(".remove", document.getElementById("TXT")).live("click", function () {
$(this).parent().remove();
var removeitem = $(this).parent().attr('id');
pushvar.splice($.inArray(removeitem, pushvar), 1);
});
In the above code pushvar is an array. Suppose if it contains 3 elements.The function will repeat for three times when we click on one of the remove button. For eg the pushvar contains [5,6,7] elements. If i click on the remove button of 6. Then the function will repeat for three times. But the
pushvar.splice($.inArray(removeitem, pushvar), 1);
will remove all the three elements. But i want to remove only 6 from the array when i click on remove class. How can i do this.
Try this:
$(".remove", document.getElementById("TXT")).live("click", function () {
$(this).parent().remove();
var removeitem = $(this).parent().attr('id');
if ($.inArray(removeitem, pushvar) > 0) pushvar.splice($.inArray(removeitem, pushvar), 1);
});
You can do something like this:
var myArray = [10, 20, 30, 40, 50];
var removeThis = 30;
myArray = jQuery.grep(myArray, function(data){
return data != removeThis;
});
I'd do something like this:
$("#TXT").on("click", ".remove", function () {
var removeitem = $(this).parent().remove().attr('id');
pushvar.splice($.inArray(removeitem, pushvar)-1, 1);
});
As that seems to work for me -> FIDDLE , but without any HTML there's a lot of guessing ?
Try like this
pushvar = [5,6,7];
$('.remove').on("click", function () {
var removeitem = $(this).attr('id');
pushvar.splice($.inArray(parseInt(removeitem), pushvar), 1);
document.write(pushvar);
return false;
});
See Demo
live() is deprecated
jQueryversion deprecated: 1.7, removed: 1.9
so use on
$(".remove,#TXT").on("click", function () {
var removeitem = $(this).parent().attr('id'); //get parent id
$(this).parent().remove(); //remove later
pushvar.splice($.inArray(removeitem, pushvar), 1);
});
if in case your selector is added dynamically then use on delegate
$(document).on("click", ".remove,#TXT", function () {

jQuery events don't work when html is injected

I have something like this:
function SetTableBehavior() {
$(".displayData tr").hover(function(e) {
$(this).children().addClass('displayDataMouseOver');
}, function () {
$(this).children().removeClass('displayDataMouseOver');
});
$(".displayData tr td").click(function(e) {
var rowsSel = $(".displayData .displayDataRowSelected");
for (var i = 0; i < rowsSel.length; i++) {
var rowSel = rowsSel[i];
$(rowSel).children().removeClass("displayDataRowSelected");
}
$(this).parent().addClass('displayDataRowSelected');
var p = $(this).parent();
p.children().addClass('displayDataRowSelected');
});
}
When the body of the table is injected neither hover or click work.
If i use
$(".displayData tr td").live('click',function(e) {
the click event works but
$(".displayData tr").live('hover',function(e) {
doesn't work
What is the solution so that hover works.
Thanks.
It seems to work like this:
function SetTableBehavior() {
$(".displayData tr").live('mouseenter', function (e) {
$(this).children().addClass('displayDataMouseOver');
}).live('mouseleave', function(e) {
$(this).children().removeClass('displayDataMouseOver');
});
$(".displayData tr td").live('click',function(e) {
var rowsSel = $(".displayData .displayDataRowSelected");
for (var i = 0; i < rowsSel.length; i++) {
var rowSel = rowsSel[i];
$(rowSel).children().removeClass("displayDataRowSelected");
}
$(this).parent().addClass('displayDataRowSelected');
var p = $(this).parent();
p.children().addClass('displayDataRowSelected');
});
}
$(".hoverme").live("mouseover mouseout", function(event) {
if ( event.type == "mouseover" ) {
// do something on mouseover
} else {
// do something on mouseout
}
});
From here: http://api.jquery.com/live/
There is no event called "hover" so you can't use it with live or bind. It is just a "short-cut" that jQuery implemented for us.
You cannot use hover with live. You'll have to split it up in 2 separate event listeners: one for mouseenter, and another one for mouseleave.
Additionally, in your situation, you don't need live. Use delegate, which is much better for performance:
$(".displayData").delegate('tr', 'mouseeneter',function(e) {
$(this).children().addClass('displayDataMouseOver');
})
.delegate('tr', 'mouseleave',function(e) {
$(this).children().removeClass('displayDataMouseOver');
});
hover(a, b) is a shortcut for mouseenter(a).mouseleave(b) (which themselves, are shortcuts for bind('mouseenter', a).bind('mouseleave', b)), so try:
$(".displayData tr").live('mouseenter', function(e) {
// mouseenter handler
}).live('mouseleave', function (e) {
// mouseleave handler
});
For more info, see the hover() and live() docs.

Categories