I can't add or remove a class - javascript

I am trying to remove a class and add a class within one function. But when I click on the button nothing is happening.
This is my code
function unlikeVerhaal(unlike) {
unlike.preventDefault;
document.querySelector('#unliked').classList.add('onzichtbaar');
document.querySelector('#liked').classList.remove('onzichtbaar');
}
document.querySelector('.likebutton').addEventListener('submit', unlikeVerhaal);
.onzichtbaar {
display: none;
}
<li>
<button type="submit" class="likebutton">
<img src="icons/lined.png" alt="lined heart" class="unliked" id="unliked">
<img src="icons/solid.png" alt="solid heart" id="liked" class="onzichtbaar">
</button> 777
</li>
What I am trying to get is that the class is added to the first image and removed by the second image.

You just need to use a combination of the three methods .contains(), .add() and .remove() from the element.classList property along with a simple if/else statement (or a ternary operator if you prefer that) as can be seen in the Code Snippet below:
var btn = document.querySelector('.likebutton');
function unlikeVerhaal() {
var ul = document.getElementById("unliked");
var l = document.getElementById("liked");
if (ul.classList.contains("onzichtbaar")) {
ul.classList.remove("onzichtbaar");
l.classList.add("onzichtbaar");
console.log("Inspect your elements to see the class switching!")
} else {
l.classList.remove("onzichtbaar");
ul.classList.add("onzichtbaar");
console.log("Inspect your elements to see the class switching!")
}
}
btn.addEventListener("click", unlikeVerhaal)
.onzichtbaar {background-color: green;}
<li>
<button type="button" class="likebutton">
<div class="unliked" id="unliked">A</div>
<div id="liked" class="onzichtbaar">B</div>
</button> 777
</li>
You can either inspect the elements to see the class switching between the two or you can just watch the green background styling which is applied to an element with the onzichtbaar class name switching between the two.

This will works as you expect:
function unlikeVerhaal(e) {
e.preventDefault;
document.getElementById('unliked').classList.add('onzichtbaar');
document.getElementById('liked').classList.remove('onzichtbaar');
}
document.getElementById('likebutton').addEventListener('click', unlikeVerhaal);
Just change submit to click and remove type from button
Fiddle
Update:
Updated fiddle

Related

when i scroll down the window it is not removing or adding the active class

I am not able to use the classList.remove('active')when scroll down despite my code is same as shown in the tutorial i am following
also when i click #search-btn it is not removing the active class from navbar
let searchForm = document.querySelector('.search-form');
document.querySelector('#search-btn').onclick = () => {
searchForm.classList.toggle('active');
navbar.classList.remove('active');
}
let navbar = document.querySelector('.nav_bar');
document.querySelector('#menu-btn').onclick = () => {
navbar.classList.toggle('active');
searchForm.classList.remove('active');
}
window.onscroll = () => {
searchForm.classList.remove('active');
navbar.classList.remove('active');
{
if (window.scrollY > 0) {
document.querySelector('.header').classList.add('active');
} else {
document.querySelector('.header').classList.remove('active');
}
}
}
I am not able to use the classList.remove('active')when scroll down despite my code is same as shown in the tutorial i am following
also when i click #search-btn it is not removing the active class from navbar
the html code i use contain nav_bar class in nav and search-form class in form in these classes i am not able to add .active class by using queryselector
<nav class="nav_bar">
home
offers
destinations
packages
contact
</nav>
<div class="icons">
<div id="menu-btn" class="fas fa-solid fa-bars"></div>
<div id="search-btn" class="fas fa-solid fa-search"></div>
<div class="fas fa-solid fa-shopping-cart"></div>
<div class="fas fa-solid fa-user"></div>
</div>
<form action="" class="search-form">
<input type="search" placeholder="search here ...."
id="input-
box">
<label for="input-box" class="fas fa-search"></label>
</form>
</header>
First of all I need more context (html) to know why your button clicking is not working correctly. Nonetheless I can give you an answer why the scrolling part doesnt work.
First you need to change if (window.screenY > 0) to window.scrollY > 0 to get the actual position of the scrolling.
Then change document.querySelectorAll('.header') to document.querySelector('.header') because querySelectorAll gives you a list of nodes wich you would have to change all separately to achieve your goal.
As I said, if you give me more context I can look in to your second problem as well.
You have a problem with this:
if (window.screenY > 0) {
document.querySelectorAll('.header').classList.add('active');
} else {
document.querySelectorAll('.header').classList.remove('active');
}
querySelectorAll returns a collection of all the elements with class header.
If you know you only have one such element then you can use document.querySelector('.header') as this selects the first one it comes across.
However, if you have several and you want to select them all you need to go through each one in the collection, for example using:
document.querySelectorAll('.header').forEach
Using your browser's dev tools inspection facility you will see that your code gives an error because it was trying to find the classList of a null element given querySelectorAll returns a collection not a single element.

How to delete HTML section using a function of js?

I need to remove a HTML section using a button. The button is in the HTML section I want to remove. And the section I want to remove was previously added by a button.
With Add section button I add a section below the first section, but I can't create a function to remove a section, I can't select the section I want to remove.
image of web
You're able to use the remove() method in order to do that.
Example:
HTML:
<div id="testID">your stuff.</div>
<button onclick="deleteDiv()">Delete</button>
JS:
function deleteDiv() {
var selectedDiv = document.getElementById("testID");
selectedDiv.remove();
}
try this code:-
<p id ="remove" style = "color: green; font-size: 24px; font-weight: bold;">
on click remove this section
</p>
<button onClick = "remove()">
click here
</button>
var htmlElement = document.getElementById('remove'); //use getElemeyId or getElementsByClassName According to your need;
function remove() {
htmlElement.remove();
}

Add class to parent div if any of the child elements has a certain class, remove if not (jQuery or Javascript)

I have a selections of dropdowns each with several buttons styled as checkboxes. When one of the buttons is clicked, it gets the class "active". What I would like to do is to add class "active" to the parent dropdown if any of the child elements (buttons) has class active (either with jQuery or Javascript).
HTML
<div class="dropdown dropdown-checkboxes">
<div class="dropdown-toggle">Brand</div>
<div class="dropdown-menu" data-filter-group="brand">
<button class="control-condition custom-checkbox" data-toggle=".volvo"><span class="checkmark"></span>Volvo</button>
<button class="control-condition custom-checkbox" data-toggle=".bmw"><span class="checkmark"></span>BMW</button>
<button class="control-condition custom-checkbox" data-toggle=".fiat"><span class="checkmark"></span>Fiat</button>
...
</div>
</div>
What I've tried
$(".control-condition").click(function () {
if ($('.dropdown-menu:has(.active)')) {
$(this).parent().parent().addClass('active');
}
else {
$(this).parent().parent().removeClass('active');
}
});
This adds class "active" to the parent dropdown just as it should, but it does not remove the class when the buttons are "unchecked" (no class active).
Any advice or guidance would be much appreciated! :)
I'd go with vanilla Javascript, as in 99.99% of cases.
const buttons = [...document.querySelectorAll('.dropdown-checkboxes .control-condition')];
document.querySelector('.dropdown-checkboxes')
.addEventListener('click',
({target}) => {
if (buttons.includes(target.closest('button'))) {
target.closest('button').classList.toggle('active');
target
.closest('.dropdown') // get the parent you need
.classList[buttons.some(btn =>
btn.classList.contains('active')) // if any button has class active
? 'add' // add .active
: 'remove' // otherwise remove .active
]
('active');
}
}
)
.checkmark::before {
content: '✓';
opacity: 0;
transition: opacity .2s ease-out;
}
button.active>.checkmark::before {
opacity: 1;
}
.dropdown {
transition: background-color .3s ease-in-out;
}
.dropdown.active {
background-color: lightgreen;
}
<div class="dropdown dropdown-checkboxes">
<div class="dropdown-toggle">Brand</div>
<div class="dropdown-menu" data-filter-group="brand">
<button class="control-condition custom-checkbox" data-toggle=".volvo"><span class="checkmark"></span>Volvo</button>
<button class="control-condition custom-checkbox" data-toggle=".bmw"><span class="checkmark"></span>BMW</button>
<button class="control-condition custom-checkbox" data-toggle=".fiat"><span class="checkmark"></span>Fiat</button>
</div>
</div>
The problem is that $('.dropdown-menu:has(.active)') will always be true, you'll have to change the check to something like this:
if ($('.dropdown-menu:has(.active)').length) { ... }
But it will be more appropriate to use .toggleClass in this case, here is an example:
$(this).parent().parent().toggleClass('active', !!$('.dropdown-menu:has(.active)').length);
You can use .hasClass()
$(".control-condition").click(function () {
if (!$('.dropdown-menu').hasClass("active")) {
$(this).parent().addClass('active');
}
else {
$(this).parent().removeClass('active');
}
});
But note there is a problem with your logic. You check if .dropdown-menu has the class active but the active class is being set on dropdown-checkboxes because of this $(this).parent().parent().addClass('active');
So either change $(this).parent().parent().addClass('active'); to $(this).parent().addClass('active');
or change $('.dropdown-menu').hasClass("active") to $('.dropdown-checkboxes').hasClass("active")
Demo
$(".control-condition").click(function () {
if (!$('.dropdown-menu').hasClass("active")) {
$(this).parent().addClass('active');
}
else {
$(this).parent().removeClass('active');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="dropdown dropdown-checkboxes">
<div class="dropdown-toggle">Brand</div>
<div class="dropdown-menu" data-filter-group="brand">
<button class="control-condition custom-checkbox" data-toggle=".volvo"><span class="checkmark"></span>Volvo</button>
<button class="control-condition custom-checkbox" data-toggle=".bmw"><span class="checkmark"></span>BMW</button>
<button class="control-condition custom-checkbox" data-toggle=".fiat"><span class="checkmark"></span>Fiat</button>
</div>
</div>
You can iterate trought all the elements with the dropdown class, and if it has some active element make it active (First remove all active class from the parent if not it will be duplicated):
$(".control-condition").click(function () {
$( "dropdown-menu" ).each(function( index ) {
var element = $(this)
// first we remove the class in case it already exist
element.removeClass('active')
// then we check if element with class active exist inside the menu
if(element.find('.active').length == 1){
element.addClass('active')
}
});
});
$('.dropdown').on('click', '.control-condition', function() {
const parent = $(this).closest('.dropdown-menu');
parent.toggleClass(
'active',
$('.control-condition.active', parent).is('.control-condition.active')
);
})
If you want the active class on .dropdown, change .dropdown-menu to .dropdown.
This will work cross-browser, on all current and future children of .dropdown-menu (because it binds to the dropdown).
If you want something that works for current and any .dropdown not yet added in DOM, change first line to:
$('body').on('click', '.dropdown .control-condition', function() {
Note on event delegation: delegating a large amount of events to 'body' can and will affect the page performance. Do not delegate to 'body' events with high frequency, such as scroll or mousemove. Read more on event-performance.

Add class to elments with same matching class as per clicked element

I need to add an .active class to any button which matches any of the classes as per the div I am clicking:
<button class="valueA"></button>
<button class="valueB"></button>
<button class="valueC valueB"></button>
<div class="DYNAMIC CLASS"></div>
$("div.valueB").on("click", function() {
...
});
The result should be:
<button class="valueB active"></button>
<button class="valueC valueB active"></button>
I tried using .each() but I'm stack with the comparison of the classes.
The thing is that my div has dynamic class just as well as those buttons, so I don't know what matches until they are in the DOM.
One version is to create a click function for every single class that you have in your document. This would look something like this:
$('.valueA').click(function() {
$('.valueA').addClass('active')
})
$('.valueB').click(function() {
$('.valueB').addClass('active')
})
$('.valueC').click(function() {
$('.valueC').addClass('active')
})
This is repetitive code however and should be avoided. So instead you can create a function that adds click handlers to all buttons (that's the example I wrote) and then retrieves the classes attached to the element. It then loops over the array of classes and adds to every element with that class another one.
$('button').click(function() {
var classes = $(this).attr('class').split(' ')
classes.forEach(function(elem) {
$('.' + elem).addClass('active');
})
})
Now if you want to limit the application of said class then you add the element type that the class should be applied to before the .
$('button.' + elem).addClass('active');
or
$('div.' + elem).addClass('active');
You need to get class name of div using .attr() and use class name in selector.
$("div").on("click", function() {
var className = $(this).attr("class");
$('button.'+ className).addClass('active');
});
.active { color: red }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="valueA">A</button>
<button class="valueB">B</button>
<button class="valueC valueB">CB</button>
<div class="valueB">B</div>
You don't need to use .each(). You can do it like following.
$("div").on("click", function() {
$('button.active').removeClass('active');
$('button.' + this.className).addClass('active');
});
.active {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="valueA">A</button>
<button class="valueB">B</button>
<button class="valueC valueB">C</button>
<div class="valueA">DIV A</div>
<div class="valueB">DIV B</div>
<div class="valueC">DIV C</div>
Get the name of your divs class and add your .active class to all of your buttons by using the corret selector $('button.valueB').
So a dynamic solution could look like this
$("div.valueB").on("click", function(e) {
var className = e.target.className;
$('button.' + className).addClass('active');
});
Demo

Display elements in order of click

How can I have elements .show in the order they're clicked and not the order they're appear in the HTML using jquery?
E.g.
Css code:
.sq{
display:none;
}
Html Code:
A
B
C
<span class="sq" id="01">a</span>
<span class="sq" id="02">b</span>
<span class="sq" id="03">c</span>
JavaScript code:
$("#1").click(function(){
$("#01").show();
});
$("#2").click(function(){
$("#02").show();
});
$("#3").click(function(){
$("#03").show();
});
Using this code if I click C,B,A the output will arrange "a b c"
What I would like is if I click C,B,A the output should arrange "c b a"
I've tried various CSS positioning rules to do this, but the best I can do is have them arrange in the same position as each other. I realize I could make a new class for each but would rather not do it that way in the interest of minimal code and I'm learning right now so it would be useful to know a better way around the issue.
Here's a fiddle: http://jsfiddle.net/xuxsuagg/4/
You can do something like
$(".myclass").one('click', function() {
$($(this).data('target')).appendTo('.output').show();
});
a {
text-decoration: none;
}
.sq {
display: none;
}
.output {}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
A
B
C
D
E
F
<p class="output">
<span class="sq" id="01">A</span>
<span class="sq" id="02">B</span>
<span class="sq" id="03">C</span>
<span class="sq" id="04">D</span>
<span class="sq" id="05">E</span>
<span class="sq" id="06">F</span>
</p>
Notes
Used a common event handler instead of using different handlers for each link
Before shown the element the target is moved to the last position of the parent
Used .one() to register the handler so that one element is shown only once
There is a very simple trick: use .append(). When you append a selected element that is already present in the DOM, you are actually moving it around. Also, I recommend that to optimize your code, you can:
Use a common class for the <a> elements
Assigned a HTML5 data- attribute, say data-target, to specify the ID of its intended target
Listen to click events triggered on the common class
An example of the proposed new markup:
A
B
<!-- and more -->
Here is the code (and the demo fiddle here—http://jsfiddle.net/teddyrised/xuxsuagg/9/)
$('.sq-click').click(function(e) {
// Prevent default action
e.preventDefault();
// Use .append() to move element
var $out = $('.output');
$out.find('#'+$(this).attr('data-target')).appendTo($out).show();
});
On a side note, if you do not want the users to rearrange the order after an anchor has been clicked, you will have to rely on the .one() method for listening to click events. Also, it will help that you style the disabled anchors appropriately so the users can see it—see proof-of-concept demo: http://jsfiddle.net/teddyrised/xuxsuagg/26/
$('.sq-click').one('click', function(e) {
// Prevent default action
e.preventDefault();
// Use .append() to move element
var $out = $('.output');
$out.find('#'+$(this).attr('data-target')).appendTo($out).show();
// Add class to change appearance of disabled <a>
$(this).addClass('disabled');
});
And your CSS can look like this:
.disabled {
cursor: default;
opacity: 0.2;
}
You can simplify this code to:
var a = document.getElementsByTagName('a');
for (i = 0; i < a.length; i++) {
a[i].addEventListener('click', function() {
var span = document.createElement('span');
var text = document.createTextNode(this.innerHTML + " ");
span.appendChild(text);
document.getElementsByClassName('output')[0].appendChild(span);
})
}
a {
text-decoration: none;
}
.sq {
display: none;
}
A
B
C
D
E
F
<p class="output">
</p>
Bind the click event to the class that they share and not their own unique id.
In the function scope of clickClosure 'this' is referring to the current element.
$(".sq").click(function clickClosure(){
$(this).show();
});
Using styles to achieve this might range from painful to very hard, depending on the exact way you want them displayed. I'd suggest instead to re-order them in DOM. That might look something like this:
<a id="link-1">...</a>
...
<div style="display: none" id="hidden-items">
<span id="item-1">...</span>
</div>
<div id="visible-items"></div>
&
$('#link-1').click(function () {
$('#visible-items').append($('#item-1'));
});
As other respondents suggested, you could also optimize your code in various ways, but that's outside the scope of the question.
Try this: You can put empty <p class="output"> and remove display:none; from CSS .sq{... In jQuery, create a <span> on the basis of clicked link and append it to <p class="output">
HTML:
A
B
C
D
E
F
<p class="output">
</p>
CSS:
.sq{
/*display:none;*/
color: green;
margin-right: 10px;
}
jQuery
$("a[href='#']").click(function(e){
e.preventDefault();
var text = '<span class="sq" id="0'+$(this).prop('id')+'">'
+$(this).text()+'</span>';
$(text).appendTo('p.output');
});
DEMO

Categories

Resources