Same click event for multiple elements, specific case - javascript

I don't want to repeat my code so I am trying to figure out how to work with a click event on multiple elements:
$(document).ready(function() {
var realStateBtn = $('#real-estate-center').parent();
var link = $('#real-estate-center > .linkwidth');
realStateBtn.css('zIndex', 9999);
realStateBtn.click(function() {
console.log('TRIGGERED');
window.location.href='http://realestatecenter.bankofamerica.com/';
});
link.click(function() {
window.location.href="http://realestatecenter.bankofamerica.com/";
});
});
as you see the vars realStateBtn and link take you to the same place/has the same function applied so what can I do in order to put the same code into one function?
I know I can do something like this:
$('.class1, class2').click(...)
but in this case I have this elements:
$('#real-estate-center').parent();
$('#real-estate-center > .linkwidth');
Suggestions?

You can use the .add() method to combine jQuery objects.
realStatebtn.add(link).click(function() {
console.log('TRIGGERED');
window.location.href='http://realestatecenter.bankofamerica.com/';
}

It's exactly as you said: move the code into a single function:
function move() {
window.location.href='http://realestatecenter.bankofamerica.com/';
}
realStateBtn.click(move);
link.click(move);
Here is a jsfiddle showing the concept: https://jsfiddle.net/b0ynfnmn/

You could add a common class and listen the click event on this class:
// Store the elements you want to an array
var elems = [];
elem.push(realStateBtn);
elem.push(link);
// You can add more elements ...
Now iterate the array and add the same class:
for(var elem in elems) {
elems[elem].addClass('my-element');
}
Add the appropriate event listener (using event delegation in order to work):
// Add event listener using event delegation
$(document).on('click', '.my-element', function() {
window.location.href="http://realestatecenter.bankofamerica.com/";
});

Related

Turn on() event back after apply off

How can I turn an on('click') event back on after I apply event off()?
$('#btn-aluno').on('click', function() {
$('.new-step-email-aluno').toggle();
$('#btn-familiar').off();
});
$('#btn-familiar').on('click', function() {
$('.new-step-email-familiar').toggle();
$('#btn-aluno').off();
});
new-step-email-familiar and new-step-email-aluno = <input>
btn-aluno and btn-familiar = <span> (used as a button)
Instead of turning off the event listener, you could do the same thing by using event delegation,
$(document).on('click',"#btn-aluno.active", function() {
$('.new-step-email-aluno').toggle();
$('#btn-familiar').removeClass("active");
});
$(document).on('click',"#btn-familiar.active", function() {
$('.new-step-email-familiar').toggle();
$('#btn-aluno').removeClass("active");
});
And whenever you want to activate the event listeners, just add the class active to the relevant elements. Also in the place of document try to use any closest static parent of the element on which the event gonna be bound.
As per your requirement, you have edit your logic like below,
$(document).on('click',"#btn-aluno.active", function() {
$('.new-step-email-aluno').toggle();
$('#btn-familiar').toggleClass("active");
});
$(document).on('click',"#btn-familiar.active", function() {
$('.new-step-email-familiar').toggle();
$('#btn-aluno').toggleClass("active");
});
DEMO

Can't apply for on click function on each of the checkboxes

I want to apply for onclick function on each of the checkbox that is being added in a datatable row.
Here's the image:
Now the issue is that I am writing a code like this
var tablei = $('#domains_list').DataTable();
$('#domains_list').find("input[name='chk[]']:checked").each(function()
{
$(this).on('click',function ()
{
// make a class change to the parent tr having the checkbox;
} );
}
});
But the problem is, I can't write the rest of the code.
You don't need each to bind event. Also you should check checked in the click handler
Use
$('#domains_list').find("input[name='chk[]']").on('click', function() {
//Perform your operation
if (this.checked) {
$(this).closest('tr').addClass('smclass');
} else {
$(this).closest('tr').removeClass('smclass');
}
});
OR
$('#domains_list').find("input[name='chk[]']").on('click', function() {
//Perform your operation
$(this).closest('tr').toggleClass('smclass', this.checked);
});
You do not need to iterate over elements individually to bind the event:
$('#domains_list').find("input[name='chk[]']:checked").click(function(){
$(this).closest('tr').addClass('smclass');
});
I think what you want is to use on()...
var tablei = $('#domains_list').DataTable();
$('#domains_list').on('click', "input[name='chk[]']", function () {
// Verify here if the checkbox is checked or not, but you could prefer the change event
// make a class change to the parent tr having the checkbox;
});
But the better way is to attach then event when you add the row (if you are able to do that).
The manual: http://api.jquery.com/on/
Because all of your checkboxes have the same function attach to it, so you dont need to loop all the element using each. An easier way to do that
$('document').on('click', "input[name='chk[]']:checked", function(){
//make sure you reset all tr before applying new class
$(this).closest('tr').addClass('custom-class');
});

JQuery - using .on with element insertion

I have a function which creates a tooltip for specific objects. Currently, I am running a tooltip function after ajax insertions to create and append the new tooltip objects. I am curious if there is a way to use .on() to auto-run the tooltip function on insertion, rather than manually running it.
For instance:
$('[title]').on('inserted', function(){
tooltip(this);
});
I did some reading and it looks like custom triggers might be the way to go, but I'd love if it something like this existed :)
Here's the pseudo code as per request.
$(document).ready(function() {
$('body').on('added','*',function() {
console.log($(this),'has been added');
});
$('body').append('<div>This is the first div</div>');
});
(function($) {
fncs = {
append:$.fn.append,
appendTo:$.fn.appendTo
// etc.
}
// we're assigning the original functions in this
// object to be executed (applied) later
$.fn.append = function() {
fncs.append.apply(this,arguments);
$(this).children().last().trigger('added');
return $(this);
}
$.fn.appendTo = function() {
fncs.appendTo.apply(this,arguments);
return $(this);
// no need to trigger because this function calls the one
// above for some reason, and it's taking care of the
// triggering the right element(s I think)
}
})(jQuery);
This is not the response you're looking for, but I would not attach tooltips directly on elements. Instead I would use a class for the ones I want the tooltip to show on mouseover and use the .on() event handler in the following way:
$('body').on('mouseover','.tooltip',function() {
// show tooltip
console.log($(this).data('tooltip'));
return false;
}).on('mouseout','.tooltip',function() {
// hide tooltip
return false;
});
So that whatever you add to the body (not necessarily as a direct child) will trigger this event handler.
I would probably just create an additional function to assign the tooltip data to each element along with the class.
$.fn.extend({
tooltip:function(text) {
text = text || '';
return $(this).each(function() {
$(this).data('tooltip',text).addClass('tooltip');
});
}
});
$('#someID').tooltip("Click me!");
$('button').tooltip("I'm a button");

By JQuery, how to specify on function as onClick handler for many radio buttons?

I have a function called handleOnClickRadio(i, j); and lots of radio buttons named as id="something-radio[i][j]". All these radio buttons are in a table called "bigtable".
How could I attach the function handleOnClickRadio() to all these radio buttons? And call it correct with handleOnClickRadio(i,j).
Thanks.
I would not attach the click handler to the buttons at all. You say you have lots of them. Attaching the same event handler to each of them is a waste of memory and could even be a performance problem.
Use event delegation instead:
$('#tableID').delegate('input[type=radio]', 'click', function() {
// code here
});
Then you could extract the i and j via regular expression (you could also consider to change the pattern so that you can use something simpler like split()):
var exp = new RegExp("\\[(.+?)\\]\\[(.+?)\\]", 'g');
var match = exp.exec(this.id);
var i = match[1];
var j = match[2];
You could put this together like so:
$('#tableID').delegate('input[type=radio]', 'click', function() {
var match = this.id.match(/\[(.+?)\]\[(.+?)\]/)
var i = match[1]; // use parseInt(match[1]) if you need an integer
var j = match[2];
handleOnClickRadio(i,j);
});
edit: Made code a bit simpler.
If i and j correspond to column and row indicies, see #Caspar Kleijne's answer for an alternative way to retrieve them.
For accessibility, you should consider binding the handler to the change event. Then changes via the keyboard will be recognized too.
wire up the event like this
$("#bigtable input[type='radio']").bind("click", OnClickRadio);
and use the handler like
var OnClickRadio = function () {
var col = $(this).parent("td").index();
var row = $(this).parent("td").parent("tr").index();
handleOnClickRadio(col, row)
});
You can attach an onClick method to a collection of radio buttons within a table with a simple bit of jQuery. When you say 'table called "bigtable"', I'm assuming that you mean that it has id="bigtable" in the following code.
$(document).ready(function() {
$("#bigtable input:radio").click(function() {
// Your on click code here
});
});
However, I would usually give each of the radio buttons a specific class using class="magicRadioButton" and then your jQuery code becomes a little clearer and doesn't rely on all of those radio buttons being within a table;
$(document).ready(function() {
$(".magicRadioButton").click(function() {
// Your on click code here
});
});
Now, if you need to then plug this information into your current handleOnClickRadio method, you can do so with the following.
$(document).ready(function() {
$("#bigtable input:radio").click(function() {
var button_id = $(this).attr("id");
var re = new RegExp("\\[(.*?)\\]\\[(.*)\\]");
var matches = re.exec(button_id);
var i = matches[1];
var j = matches[2];
handleOnClickRadio(i,j);
});
});
Give them class names in conjunction with $(this) in your click trigger
I suggest using delegate if you have lot of radios: that way, only one Event listener will be attached
see http://api.jquery.com/delegate/
$("#globalContainer").delegate("input", "click", function(){
//Perform a string test / regex to test if the id matches something-radio[i][j]
//With a regex with capturing groups you can retrieve [i] and [j] values at the same time
if ( test($(this).attr("id")) ) {
}
});
Ideally, you'd have a onclick assigned to the big table rather than each and every radio button. Events in JavaScript bubble up so the table (which is the eventual parent of all these radio buttons) will receiving the event.
So in jQuery you would have code like this
$('#bigtable').click(handleOnClickRadio);
The signature of your handleOnClickRadio function would be
function handleOnClickRadio(evt) {
var radio = evt.target;
var id = $(radio).attr('id');
}
evt.target will identify the actual radio button that was clicked/checked and you can access other attributes of the radio as well. such as
$(radio).attr('id)
Will give you the id of the radio button.
<input type="radio" class="many-radio-buttons" ....
jQuery:
$('.many-radio-buttons').click(function() {
//your_code;
});

Is there an easier way to reference the source element for an event?

I'm new to the whole JavaScript and jQuery coding but I'm currently doing this is my HTML:
<a id="tog_table0"
href="javascript:toggle_table('#tog_table0', '#hideable_table0');">show</a>
And then I have some slightly ponderous code to tweak the element:
function toggle_table(button_id, table_id) {
// Find the elements we need
var table = $(table_id);
var button = $(button_id);
// Toggle the table
table.slideToggle("slow", function () {
if ($(this).is(":hidden"))
{
button.text("show");
} else {
button.text("hide");
}
});
}
I'm mainly wondering if there is a neater way to reference the source element rather than having to pass two IDs down to my function?
Use 'this' inside the event. Typically in jQuery this refers to the element that invoked the handler.
Also try and avoid inline script event handlers in tags. it is better to hook those events up in document ready.
NB The code below assumes the element invoking the handler (the link) is inside the table so it can traverse to it using closest. This may not be the case and you may need to use one of the other traversing options depending on your markup.
$(function(){
$('#tog_table0').click( toggle_table )
});
function toggle_table() {
//this refers to the element clicked
var $el = $(this);
// get the table - assuming the element is inside the table
var $table = $el.closest('table');
// Toggle the table
$table.slideToggle("slow", function () {
$el.is(":hidden") ? $el.text("show") : $el.text("hide");
}
}
You can do this:
show
and change your javascript to this:
$('a.tableHider').click(function() {
var table = $(this.name); // this refers to the link which was clicked
var button = $(this);
table.slideToggle("slow", function() {
if ($(this).is(':hidden')) { // this refers to the element being animated
button.html('show');
}
else {
button.html('hide');
}
});
return false;
});
edit: changed script to use the name attribute and added a return false to the click handler.
I'm sure this doesn't answer your question, but there's a nifty plugin for expanding table rows, might be useful to check it out:
http://www.jankoatwarpspeed.com/post/2009/07/20/Expand-table-rows-with-jQuery-jExpand-plugin.aspx

Categories

Resources