Jquery unable to assign onclick on button array - javascript

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");
});

Related

Using JS How to call click function once only which will be equivalent to .one jQuery

Hello could someone help me? I'm having trouble transforming this part of my code to JS:
$(".custom-select-trigger").on("click", function() {
$('html').one('click',function() {
$(".custom-select").removeClass("opened");
});
$(this).parents(".custom-select").toggleClass("opened");
event.stopPropagation();
});
I have it so far:
const customSelectTrigger = document.querySelector(".custom-select-trigger");
const customSelect = document.querySelector(".custom-select");
function showOptions(e) {
e.preventDefault();
customSelect.classList.toggle("opened");
e.stopPropagation();
}
but I'm not able to do this part for javascript:
$('html').one('click',function() {
$(".custom-select").removeClass("opened");
});
Here is working code for to remove class opened from your custom select when you press anywhere in the DOM.
You need to use JS addEventListener and click function to do this.
To remove class from an element we can use .remove function and getting the classList of your element by querySelector which will .custom-select
Edit: If you just want to use the click function once only per DOM load. Then setting setting the args { once: true } will only invoke the function once.
I have recreated your example and its working.
Run snippet below.
//Getting HTML element
const htmlElement = document.querySelector("html");
//Getting element where to remove the class from
const customSelect = document.querySelector(".custom-select");
//Adding eventlistener to remove class opened from classList
htmlElement.addEventListener("click", function(e) {
customSelect.classList.remove("opened");
console.log('Class Removed')
e.preventDefault();
},{ once: true });
.opened {
background-color: red;
}
<html>
<h3>
Click anywhere on the DOM to remove class from Custom select
</h3>
<div class="custom-select opened">
My Custom Select
</div>
</html>

Can I catch element on click if is already used in Wordpress Plugin mmenu?

I need to catch if element is clicked in javascript function, but element class is already used in plugin named "mmenu" on showing hidden header content. Is that event possible, or I need to change implementation without using plugin ?
Element I use in HTML :
<a class="custom-search-mobile" id="mobile-nav-toggle" aria-label="Toggle mobile menu"><span class="fas fa-bars"></span></a>
function on find out if element is clicked:
$(document).ready(function () {
$('.custom-search-mobile').on('click', function (event) {
console.log("it is clicked!!!!!!");
});
});
Screen of plugin, where I use my CLASS :
If you want to know what element was clicked
$(document).ready(function () {
$('.custom-search-mobile').on('click', function (event) {
var el = $(this)
console.log(el);
//manipulate with element
});
});

Combining / Refining two identical blocks of jQuery

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>

html div onclick event

I have one html div on my jsp page, on that i have put one anchor tag, please find code below for that,
<div class="expandable-panel-heading">
<h2>
<a id="ancherComplaint" href="#addComplaint"
onclick="markActiveLink(this);">ABC</a>
</h2>
</div>
js code
$('.expandable-panel-heading:not(#ancherComplaint)').click(function () {
alert('123');
});
function markActiveLink(el) {
alert($(el).attr("id"));
}
here I when I click on div I got alert with 123 message, its fine but when I click on ABC I want message I want to call markActiveLink method.
JSFiddle
what is wrong with my code? please help me out.
The problem was that clicking the anchor still triggered a click in your <div>. That's called "event bubbling".
In fact, there are multiple solutions:
Checking in the DIV click event handler whether the actual target element was the anchor
→ jsFiddle
$('.expandable-panel-heading').click(function (evt) {
if (evt.target.tagName != "A") {
alert('123');
}
// Also possible if conditions:
// - evt.target.id != "ancherComplaint"
// - !$(evt.target).is("#ancherComplaint")
});
$("#ancherComplaint").click(function () {
alert($(this).attr("id"));
});
Stopping the event propagation from the anchor click listener
→ jsFiddle
$("#ancherComplaint").click(function (evt) {
evt.stopPropagation();
alert($(this).attr("id"));
});
As you may have noticed, I have removed the following selector part from my examples:
:not(#ancherComplaint)
This was unnecessary because there is no element with the class .expandable-panel-heading which also have #ancherComplaint as its ID.
I assume that you wanted to suppress the event for the anchor. That cannot work in that manner because both selectors (yours and mine) select the exact same DIV. The selector has no influence on the listener when it is called; it only sets the list of elements to which the listeners should be registered. Since this list is the same in both versions, there exists no difference.
Try this
$('.expandable-panel-heading:not(#ancherComplaint)').click(function () {
alert('123');
});
$('#ancherComplaint').click(function (event) {
alert($(this).attr("id"));
event.stopPropagation()
})
DEMO
Try following :
$('.expandable-panel-heading').click(function (e) {
if(e.target.nodeName == 'A'){
markActiveLink(e.target)
return;
}else{
alert('123');
}
});
function markActiveLink(el) {
alert($(el).attr("id"));
}
Here is the working demo : http://jsfiddle.net/JVrNc/4/
Change your jQuery code with this. It will alert the id of the a.
$('.expandable-panel-heading:not(#ancherComplaint)').click(function () {
markActiveLink();
alert('123');
});
function markActiveLink(el) {
var el = $('a').attr("id")
alert(el);
}
Demo
You need to read up on event bubbling and for sure remove inline event handling if you have jQuery anyway
Test the click on the div and examine the target
Live Demo
$(".expandable-panel-heading").on("click",function (e) {
if (e.target.id =="ancherComplaint") { // or test the tag
e.preventDefault(); // or e.stopPropagation()
markActiveLink(e.target);
}
else alert('123');
});
function markActiveLink(el) {
alert(el.id);
}
I would have used stopPropagation like this:
$('.expandable-panel-heading:not(#ancherComplaint)').click(function () {
alert('123');
});
$('#ancherComplaint').on('click',function(e){
e.stopPropagation();
alert('hiiiiiiiiii');
});
Try out this example, the onclick is still called from your HTML, and event bubbling is stopped.
<div class="expandable-panel-heading">
<h2>
<a id="ancherComplaint" href="#addComplaint" onclick="markActiveLink(this);event.stopPropagation();">ABC</a>
</h2>
</div>
http://jsfiddle.net/NXML7/1/
put your jquery function inside ready function for call click event:
$(document).ready(function() {
$("#ancherComplaint").click(function () {
alert($(this).attr("id"));
});
});
when click on div alert key
$(document).delegate(".searchbtn", "click", function() {
var key=$.trim($('#txtkey').val());
alert(key);
});

jQuery toggle multiple elements

I can not make this piece of code work:
$("a.expand_all").on("click",function(){
$(this).text('Hide');
$('.answer').each(function () {
$(this).slideDown(150, function () {
$(this).show();
});
});
}, function () {
$(this).text('Expand');
$('.answer').each(function () {
$(this).slideUp(150, function () {
$(this).hide();
});
});
});
I'm trying to collapse expend multiple divs, but nothing happens on click event. I 'm using latest jQuery 1.10.1
It looks to me like you're using jQuery's .on method incorrectly. That method has some overloads, but none of them (sensibly) takes two functions.
If I understand what you're trying to do correctly, you just want to toggle some answer elements when a <a> tag is clicked. What you really need to do is have some way of determining if your answers are expanded or not. There are multiple ways to do that, but I've chosen to use a data element:
<a class="expand_all" href="#" data-collapsed="true">expand</a>
<p class="answer">I'm an answer!</a>
<p class="answer">Another answer</a>
Then your JavaScript can be simplified thusly:
$('a.expand_all').on("click",function(){
if( $(this).data('collapsed') ) {
$(this).text('hide').data('collapsed','');
$('.answer').slideDown(150);
} else {
$(this).text('expand').data('collapsed','true');
$('.answer').slideUp(150);
}
});
I simplified some of your constructs as well. In particular, in your code:
$('.answer').each(function () {
$(this).slideDown(150, function () {
$(this).show();
});
});
The .each is unnecessary. Just applying a jQuery method is essentially equivalent to calling .each. You rarely need to use .each. So that simplifies to this:
$('.answer').slideDown(150, function () {
$(this).show();
});
Then, .slideDown shows the element before it starts, so there's no need to call .show a second time. So we can get rid of the callback, simplifying all of this to:
$('.answer').slideDown(150);
You can see all of this in action here:
http://jsfiddle.net/Jammerwoch/sRnkw/5/
Lastly, the reason I asked whether any of your elements are dynamically added is because if they are, the way you are attaching them won't work. That is, the jQuery selectors run once, and then don't get re-run when you add new elements. So you have to be more clever. That's described in the jsfiddle above. Let me know if you need more clarification on that point.
That doesn't look like valid event binding to me, having the two functions there.
HTML - I added a div wrapper for event delegation
<div class="expando_content">
<a class="expand_all" href="#">Expand</a>
<p class="answer">I'm an answer!</a>
<p class="answer">Another answer</a>
<p>Dynamically added "expand more" goes below...it won't work :(</p>
<div id="thing"></div>
</p>
</p>
</div>
JS - moved the toggling functionality inside one function.
$(".expando_content").on("click", ".expand_all", function () {
if (!$('.answer').is(':visible')) {
$(this).text('Hide');
$('.answer').each(function () {
$(this).slideDown(150, function () {
$(this).show();
});
});
} else {
$(this).text('Expand');
$('.answer').each(function () {
$(this).slideUp(150, function () {
$(this).hide();
});
});
}
});
$('<a class="expand_all" href="#">expand more</a>').appendTo($('#thing'));
jsFiddle

Categories

Resources