Combining / Refining two identical blocks of jQuery - javascript

I have two blocks of code that function exactly the same but need to fired independently in order to prevent overlap of functionality.
//Block One
jQuery('.top_searchicon').on('click touchstart', (function(e) {
e.preventDefault();
jQuery(this).toggleClass('active');
jQuery('.top_blog_search').toggleClass('active');
}));
//Block Two
jQuery('.searchicon').on('click touchstart', (function(e) {
e.preventDefault();
jQuery(this).toggleClass('active');
jQuery('.blog_search').toggleClass('active');
}));
Thank you very much.

You can combine selectors using a comma (,). You can then use is() and a ternary to choose the relevant element to set the active class on. Try this:
jQuery(function($) {
$('.top_searchicon, .searchicon').on('click touchstart', (function(e) {
e.preventDefault();
var $el = $(this).toggleClass('active');
var targetClass = $el.is('.searchicon') ? '.blog_search' : '.top_blog_search';
$(targetClass).toggleClass('active');
});
});
Note the use of the parameter in the ready handler, this enables you to still use the $ to reference jQuery within the scope of your document.ready handler.

An alternative to using the same event handler and checking within the event handler is to pass parameters to the event handler.
jQuery('.top_searchicon').on('click touchstart', function() {
handleClickTouchStart(".top_blog_search");
});
jQuery('.searchicon').on('click touchstart', function() {
handleClickTouchStart(".blog_search");
});
function handleClickTouchStart(selector)
{
e.preventDefault();
jQuery(this).toggleClass('active');
jQuery(selector).toggleClass('active');
}
This lets you add new handlers without needing to change the handler code (which would become quite messy with more than 2 options using .is (which is ofc fine if you only have 2, maybe 3)), eg:
jQuery('.another_searchicon').on('click touchstart', function() {
handleClickTouchStart(".another_blog_search");
});
The next step would be to use -data attributes to link the two.
This gives you the benefit of being able to add new elements without needing to change any code!
jQuery('.searchhandler').on('click touchstart', function() {
e.preventDefault();
jQuery(this).toggleClass('active');
var other = jQuery(this).data("related");
jQuery(other).toggleClass('active');
});
and change your markup to add matching -data (speculating on the markup here) :
<button type='button' class='searchhandler' data-related='.top_blog_search'>top search</button>
<button type='button' class='searchhandler' data-related='.blog_search'>blog search</button>
<div class='top_blog_search'></div>
...etc
to add another:
<button type='button' class='searchhandler' data-related='.another_search'>another search</button>
<div class='another_search'></div>

Related

Jquery unable to assign onclick on button array

I am trying to adapt the commented out code at the bottom that works for a single button to work for more than one buttons.
So I changed the 'menu-toggle' being from an id to a class. And in the html I added class='menu-toggle' to the buttons.
I am getting an array of the elements using a jquery selector. Then looping on them, and assigning the onclick event.
// Toggles the sidebar
const buttons = $('.menu-toggle');
buttons.forEach(
function (element){
element.onclick(
function (event) {
event.preventDefault();
$("#wrapper").toggleClass("toggled");
}
)
}
)
/*
$("#menu-toggle").click(function (e) {
e.preventDefault();
$("#wrapper").toggleClass("toggled");
});
*/
Edit: I accepted Alireza's answer, as he fixed my code. But I actually used Zoli's answer, as it is more concise. Aside from the bug in the code, the actual problem was that the browser was caching the *.js file this code is in. So my changes were not reloading. I cleared the cache from privacy settings, and now it works.
It is as simple as changing the ID selector to a class selector.
$(".menu-toggle").click(function (e) {
e.preventDefault();
$("#wrapper").toggleClass("toggled");
});
jQuery will attach the event handler to all selected elements, whether that's a single element (in the case of an ID selector) or multiple elements (found by a class selector or other...).
Note that forEach functions exist on array, so you need to use spared operator (...) to convert buttons to array to make sure you can use forEach function. (Probably you get the error buttons.forEach is not a function now)
const buttons = $('.menu-toggle');
[...buttons].forEach(
function (element) {
element.onclick =
function (event) {
event.preventDefault();
$("#wrapper").toggleClass("toggled");
}
}
)
.toggled {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<button class="menu-toggle">button1</button>
<button class="menu-toggle">button2</button>
<button class="menu-toggle">button3</button>
<button class="menu-toggle">button4</button>
<p id="wrapper">this is p</p>
$("body").on("click", ".menu-toggle", function(e) {
e.preventDefault();
$("#wrapper").toggleClass("toggled");
});

I'm trying to attach events using on() based on changing selectors

I have a button that can be in 2 different states (lets say Lock and Unlock). When I click on the button, I update the class on the button to reflect the binary opposite state. Each class has a different event attachment function using on(string, callback). For some reason the event being triggered remains the first callback assigned based on the original class.
HTML:
<button class="lock">Lock</button>
<button class="unlock">Unlock</button>
JavaScript:
$(document).ready(function() {
$('.lock').on('click', function() {
// Perform some magic here
console.log('Lock!');
$(this).removeClass('lock')
.addClass('unlock')
.html('Unlock');
});
$('.unlock').on('click', function() {
// Perform some magic here
console.log('Unlock!');
$(this).removeClass('unlock')
.addClass('lock')
.html('Lock');
});
});
https://jsfiddle.net/c283uaog/ for testing.
Expected console output when clicking on the same button repeatedly:
Lock!
Unlock!
Lock!
Actual console output:
Lock!
Lock!
Lock!
Any assistance would be greatly desired
use event Delegation
$(document).on('click','.lock', function() {
$(document).on('click','.unlock', function() {
updated Demo
Or use in single function with toggleClass
$(document).on('click', '.lock,.unlock', function () {
$('#output').html($(this).attr('class'));
$(this).toggleClass('lock unlock').text($(this).attr('class'));
});
ToggleClass demo
I'd do it this way, attaching only one event: http://jsfiddle.net/jozu47tv/
$(".lock").on('click', function(e) {
e.preventDefault();
if($(this).hasClass("lock")) {
$(this).removeClass("lock").addClass("unlock");
console.log("lock -> unlock");
} else {
$(this).removeClass("unlock").addClass("lock");
console.log("unlock -> lock");
}
})
Use Event Delegation method, Try this updated fiddle,
$(document).ready(function() {
$(document).on('click', '.lock', function() {
$('#output').html('Lock!');
$(this).removeClass('lock')
.addClass('unlock')
.html('Unlock');
});
$(document).on('click', '.unlock', function() {
$('#output').html('Unlock!');
$(this).removeClass('unlock')
.addClass('lock')
.html('Lock');
});
});
Probably, this question could answer you in a better way:
jQuery .on function for future elements, as .live is deprecated
$(document).on(event, selector, handler)
Change your html to this:
<button class="locker lock" >Lock</button>
<button class="locker unlock"">Unlock</button>
<div id="output">Output</div>
and your Js to this:
$(document).ready(function() {
$('.locker').on('click', function() {
if($(this).hasClass("lock")){
$(this).removeClass("lock");
$(this).addClass("unlock");
$(this).html("unlock");
}
else if($(this).hasClass("unlock")){
$(this).removeClass("unlock");
$(this).addClass("lock");
$(this).html("lock");
}
});
});

Bypass onclick event and after excuting some code resume onclick

I have the below html button which have onclick event
<button onclick="alert('button');" type="button">Button</button>
and the following js:
$('button').on('click', function(){
alert('jquery');
});
After executing some js code by jQuery/Javascript, i want to continue with the button onclick handler e.g: jquery alert first and than button alert.
i tried so many things like "remove attr and append it after executing my code and trigger click (it stuck in loop, we know why :) )" and "off" click. but no luck.
is it possible via jQuery/javascript?
any suggestion much appreciated
Thanks
A little bit tricky. http://jsfiddle.net/tarabyte/t4eAL/
$(function() {
var button = $('#button'),
onclick = button.attr('onclick'); //get onclick value;
onclick = new Function(onclick); //manually convert it to a function (unsafe)
button.attr('onclick', null); //clear onclick
button.click(function() { //bind your own handler
alert('jquery');
onclick.call(this); //call original function
})
});
Though there is a better way to pass params. You can use data attributes.
<button data-param="<%= paramValue %>"...
You can do it this way:
http://jsfiddle.net/8a2FE/
<button type="button" data-jspval="anything">Button</button>
$('button').on('click', function () {
var $this = $(this), //store this so we only need to get it once
dataVal = $this.data('jspval'); //get the value from the data attribute
//this bit will fire from the second click and each additional click
if ($this.hasClass('fired')) {
alert('jquery'+ dataVal);
}
//this will fire on the first click only
else {
alert('button');
$this.addClass('fired'); //this is what will add the class to stop this bit running again
}
});
Create a separate javascript function that contains what you want to do when the button is clicked (i.e. removing the onclick attribute and adding replacement code in its own function).
Then call that function at the end of
$('button').on('click', function(){
alert('jquery');
});
So you'll be left with something like this
function buttonFunction()
{
//Do stuff here
}
$('button').on('click', function()
{
alert('jquery');
buttonFunction();
});
<button type="button">Button</button>

Find Id of clicked button

I wanted to get the id of clicked button since i have 4-5 buttons on my form.
<button type="submit" style="height: 30px" id="btnHelp" name="btnHelp" onclick="ShowHelp(2);return false;">Help</button>
<button type="button" style="height: 30px" id="btnClose" name="btnClose" onclick="Close();return false;">Close</button>
<button type="button" style="height: 30px" id="btnSave" name="btnSave" onclick="Save();return false;">Close</button>
...............................
Whichever may be the button click, I just want to get id of that button.
$(function () {
var id = $(this).attr('id');
alert(id);
})
Also with
$("input").click(function (event) {
var urlid = $(this).attr('id')
alert(urlid);
})
but i am getting the alert as undefined.
How can i get id of button clicked?
Please help me.
Try
:button Selector
Selects all button elements and elements of type button.
$(":button").click(function (event) {
var urlid = this.id;
alert(urlid);
});
Fiddle Demo
Problem
$("input") --> selects elements with tag input eg. <input type="text"/> but not <button> tag .
I'd try to replace this with the event triggerer.
var urlid = $(event.target).attr("id");
Also, probably your onclick function is preventing your script to be executed, because it's handling the click event, not letting your function do it.
I ditched the onclick attributes of buttons you have, and hooked click events to button rather than input, and it worked. So check whether you are connecting to the right element.
See example here.
<script>
jQuery(":button").click(function (event) {
var urlid = $(this).attr('id')
alert(urlid);
})
</script>
Try this its work
very simply:
$("input").click(function (event) {
var urlid = this.id;
alert(urlid);
})
for button:
$("button").click(function (event) {
var urlid = this.id;
alert(urlid);
})
You might try use event passed as argument into any event handler instead of this for event.target is referring to element actually triggering your handler (being clicked) and event.delegateTarget being element handler has been attached to initially. In both cases you might have to use $() for using jQuery or simply stick with accessing .id in either case.
In your case this would be
$("input").click(function (event) {
var urlid = $(event.delegateTarget).attr('id');
alert(urlid);
});
to ensure handler is always accessing that it has been attached to, here.
Except for this quite simple scenario relying on this is sometimes trickier than using provided arguments.
EDIT : However, your case seems to be related to issues encountered by Tusha Gupta, for sure. Your buttons aren't "inputs" so that handlers are never attached, actually.
$(function () {
$("button").click(function () {
alert($(this).attr("id"));
});
});

click event not working when changing id or class

I'm starting with jquery, and have an issue here:
http://jsfiddle.net/8guzD/
$('#test.off').click(function(){
$(this).removeClass('off').addClass('on');
});
$('#test.on').click(function(){
$(this).removeClass('on').addClass('off');
alert('ok');
});
the first part of the code goes well, the class is apply, but when I attach an event in this element with its new class it won't work.
Can someone explain me what is the problem exactly?
I tried with javascript,
http://jsfiddle.net/R5NRz/
var element = document.getElementById('test');
element.addEventListener('click', function() {
this.id ='test2';
alert("ok");
}, false);
var element2 = document.getElementById('test2');
element2.addEventListener('click', function() {
alert("ok2");
}, false);
and it didn't really help me, having the same issue
try
$(document).on("click",'#test.on',function(){
$(this).removeClass('off').addClass('on');
alert('ok');
});
$(document).on("click",'#test.off',function(){
$(this).removeClass('off').addClass('on');
alert('ok passs');
});
Demo
In your jQuery example you are binding to DOM elements that exist at that time. That is why you see the first fire but not the second. It is not a match for your '#test.on' selector when the code is run. What you want to do instead is use delegation:
$('#test').on('click',function() {
var ele = $(this);
if (ele.hasClass('on')) {
ele.removeClass('on').addClass('off');
} else {
ele.removeClass('off').addClass('on');
}
});
This assumes that you are doing more than just toggling classes. If you want simply toggle classes then an easier solution is to pick one as the default and use the other as a flag. For example, .on is on but without .on it's off. Then you can just use toggle:
$('#test').on('click', function() {
$(this).toggleClass('on');
});
$("#test.on")
Doesn't bind to anything. Try this:
$('#test').click(function() {
if($(this)).hasClass('off') $(this).removeClass('off').addClass('on');
else $(this).removeClass('on').addClass('off');
});
You might consider using an 'active' class instead and just toggling that, instead of have two separate on/off classes. Then you can write:
$("#test").click(function() {
$(this).toggleClass('active');
});

Categories

Resources