How to manipulate css using javascript? - javascript

I was trying to manipulate the css when clicking on button using javascript . I want to just make a single button active the one which is recently clicked.
I am able to make it active but somehow i am not able to remove active for other which is not selected
here is what i tried in js
const myFunction = (event) => {
const clickedElem = event.target
const allBtns = document.querySelectorAll('.btn.lightblue')
allBtns.forEach(btn => btn.classList.remove('.btn.lightblue.active'))
clickedElem.classList.add('active')
}
<p>
<button onclick="myFunction(event)" class="btn lightblue">XASD</button>
<button onclick="myFunction(event)" class="btn lightblue">QWER</button>
<button onclick="myFunction(event)" class="btn lightblue">ASDF</button>
<button onclick="myFunction(event)" class="btn lightblue">ZXCV</button>
</p>

Look at the definition of the remove method:
tokenList.remove(token1[, token2[, ...tokenN]]);
It takes each class that you want to remove as a separate argument (strings with one class name in each).
It doesn't take a single argument with a CSS selector.
… and you probably only want to remove the active class anyway, not btn or lightblue.

When using remove function on btn.classList.remove, pls put className only.
const myFunction = (event) => {
const clickedElem = event.target
const allBtns = document.querySelectorAll('.btn.lightblue')
allBtns.forEach(btn => btn.classList.remove('active'))
clickedElem.classList.add('active')
}
.active {
background: red;
}
<p>
<button onclick="myFunction(event)" class="btn lightblue">XASD</button>
<button onclick="myFunction(event)" class="btn lightblue">QWER</button>
<button onclick="myFunction(event)" class="btn lightblue">ASDF</button>
<button onclick="myFunction(event)" class="btn lightblue">ZXCV</button>
</p>

you can use 1) Element.style = "..." or 2) Element.classList.add("...")
to
overwrite the css with the style attribute
add a class to the element to have it use a predefined styling. (note that elements can have multiple classes)

Related

javascript .closest to utilise either one of two selectors

I'm currently utilizing .closest in vanilla js to find a div(modal container) with a certain class, then on click of the button closes that div(modal container). all works fine, but the issue i'm running into now is I need to find either one of two divs(two different types of modals). So depending which one of these "div (modal containers)" are closest to the button - close that modal.
<div class="modal-a">
<div class="modal__header">
<button class="btn" data-close-btn>close</button>
</div>
</div>
<div class="modal-b">
<button class="btn" data-close-btn>close</button>
</div>
//-------------- Javacript
const closeBtn = querySelectorAll(['data-close-btn]);
closeBtn.forEach(button => {
const modal = button.closest('.modal-a'); // works as expected
button.addEventListener('click', (e)=> closeModal(modal));
});
function closeModal(modal) {
modal.classList.remove('.active');
}
what im trying to achieve
const modal = button.closest('.modal-a') || button.closest('.modal-b');
const modal = button.closest('.modal-a, .modal-b');
both these obviously fails the first time but works thereafter although in the console there is always a failure on click, so how do i write this to only use the relevant selector?
Hope this makes sense what im trying to explain.
You can use a single eventlistener and event delegation for that:
document.addEventListener("click", e => {
target = e.target.closest(".modal-a, .modal-b")
if(!target || !e.target.matches("[data-close-btn]")) return;
alert("You clicked a modal-Button")
})
<div class="modal-a">
<button class="btn" data-close-btn>close</button>
</div>
<div class="modal-b">
<button class="btn" data-close-btn>close</button>
</div>
<h2>Button outside of any Modal</h2>
<button class="btn" data-close-btn>close</button>

Show and hide different elements by class with the same JS function

I want to create a js or jq function to hide and show items by class with two variables, the class of the items to be shown and the class of the items to be hidden.
I can't make it works. Do anyone know what happens?
function ShowHide(ShowClass, HideClass) {
document.getElementsByClassName(ShowClass).show();
document.getElementsByClassName(HideClass).hide();
}
.ABChidden,
.DEFhidden {
display: none;
}
<button class="ABCvisible" type="button" onclick="ShowHide('ABChidden', 'ABCvisible');">
Click Me to show ABC
</button>
<p class="ABChidden">I'm ABC</p>
<button class="ABChidden" type="button" onclick="ShowHide('ABCvisible', 'ABChidden');">Click Me to hide ABC</button>
<hr>
<button class="DEFvisible" type="button" onclick="ShowHide('DEFhidden', 'DEFvisible');">
Click Me to show CGE
</button>
<p class="DEFhidden">I'm DEF</p>
<button class="DEFhidden" type="button" onclick="ShowHide('DEFvisible', 'DEFhidden');">Click Me to hide CGE</button>
You can't use jQuery methods like .css() with DOM objects, you need to create a jQuery collection object with $().
function ShowHide(ShowClass, HideClass) {
$(`.${ShowClass}`).show();
$(`.${HideClass}`).hide();
}
.ABChidden,
.DEFhidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="ABCvisible" type="button" onclick="ShowHide('ABChidden', 'ABCvisible');">
Click Me to show ABC
</button>
<p class="ABChidden">I'm ABC</p>
<button class="ABChidden" type="button" onclick="ShowHide('ABCvisible', 'ABChidden');">Click Me to hide ABC</button>
<hr>
<button class="DEFvisible" type="button" onclick="ShowHide('DEFhidden', 'DEFvisible');">
Click Me to show CGE
</button>
<p class="DEFhidden">I'm DEF</p>
<button class="DEFhidden" type="button" onclick="ShowHide('DEFvisible', 'DEFhidden');">Click Me to hide CGE</button>
or use ordinary JavaScript DOM methods and set the style property of all the selected elements.
function ShowHide(ShowClass, HideClass) {
Array.from(document.getElementsByClassName(ShowClass)).forEach(el =>
el.style.display = 'block');
Array.from(document.getElementsByClassName(HideClass)).forEach(el =>
el.style.display = 'none');
}
.ABChidden,
.DEFhidden {
display: none;
}
<button class="ABCvisible" type="button" onclick="ShowHide('ABChidden', 'ABCvisible');">
Click Me to show ABC
</button>
<p class="ABChidden">I'm ABC</p>
<button class="ABChidden" type="button" onclick="ShowHide('ABCvisible', 'ABChidden');">Click Me to hide ABC</button>
<hr>
<button class="DEFvisible" type="button" onclick="ShowHide('DEFhidden', 'DEFvisible');">
Click Me to show CGE
</button>
<p class="DEFhidden">I'm DEF</p>
<button class="DEFhidden" type="button" onclick="ShowHide('DEFvisible', 'DEFhidden');">Click Me to hide CGE</button>
You have to set the display property of the ShowClass and HideClass elements one by one. It can be easily done using loop.
function ShowHide(ShowClass, HideClass) {
elementsToDisplay = document.getElementsByClassName(ShowClass);
elementsToHide = document.getElementsByClassName(HideClass);
[...elementsToDisplay].forEach(elem => (elem.style.display = "block"));
[...elementsToHide].forEach(elem => (elem.style.display = "none"));
}
Firstly, if you run
document.getElementsByClassName('ABChidden')
it returns a list.
Secondly, show and hide are both not functions, so it won't run anyway
Try this:
function ShowHide(showClass,hideClass){
document.getElementsByClassName(showClass)[0].hidden='false';
document.getElementsByClassName(hideClass)[0].hidden='true';
}
Place each section in a container.
In the onclick listener, send in the clicked element with 'this' (this = the button element).
In the method toggleVisibility, go up a node to the parent element - the .container and toggle it's class.
Set CSS classes to .show and .hide, based on if the parent have the class .hidden.
function toggleVisibility(element) {
element.parentNode.classList.toggle("hidden");
}
.hide {
display: none;
}
.container.hidden > .show {
display: none;
}
.container.hidden > .hide {
display: block;
}
<div class="container">
<button class="show" type="button" onclick="toggleVisibility(this)">
Click Me to show ABC
</button>
<p class="hide">I'm ABC</p>
<button class="hide" type="button" onclick="toggleVisibility(this)">Click Me to hide ABC</button>
</div>
<hr>
<div class="container">
<button class="show" type="button" onclick="toggleVisibility(this)">
Click Me to show CGE
</button>
<p class="hide">I'm DEF</p>
<button class="hide" type="button" onclick="toggleVisibility(this)">Click Me to hide CGE</button>
</div>

How to capture two same id but different class in addEventListener

first of all, thank you for your time to read this question, and two things, I'm using ES5 and I don't use jQuery.
Right now I'm struggling a lot to figure what's the correct solution for the addEventListener, because for some reason it does not trigger for the second button which is only for the mobile screen dimensions, the problem is that the second button have the same id but different class, for example this:
<div class="product-bg-container product-general-info variation-info">
<input type="hidden" name="sku" value="Something-15892290" id="selected-option">
{/* Desktop screen button */}
<button id="buy-now" class="btn btn-lg hidden-sm-down btn-primary">
Add to Cart
</button>
{/* Mobile screen button */}
<button id="buy-now" class="btn btn-lg hidden-md-up btn-primary">
Add to Cart
</button>
</div>
Where I am trying to trigger the second button but it does not where I don't understand why it does, if the id is the same, should not matter, so I'm trying to figure how to trigger from the first button if it's clicked and also with the second if it's clicked, but I'm out of ideas...
var button = document.getElementById('buy-now');
if (!button) {
return;
}
button.addEventListener('click', function trackAddToCart() {
// more code for the event
}
I thought an idea to capture the attribute of the button, but it works in the first button but not for the second one:
var button = document.getElementById('buy-now');
var att = button.getAttribute('class');
button.addEventListener('click', function() {
console.log('class ' + att); //shows: class: btn btn-lg hidden-sm-down btn-primary
console.log('button class? '+ button); //shows: button element: [object HTMLButtonElement]
});
But when I click the second button... does not trigger or happening nothing, not sure why... and I can't change the id value (which it should be easy but I can't "company standard")
Can anyone help me to have an idea how to capture and trigger the event for the second button ??
The attribute id must be unique in a document. You can use attributeStartsWith selector or class with querySelectorAll(). Then loop through all the button to attach the event (click) individually:
//var button = document.querySelectorAll('.btn.btn-primary');
var button = document.querySelectorAll('[id^=buy-now]');
button.forEach(function(btn){
btn.addEventListener('click', function() {
console.log('class ' + this.classList);
console.log('button class? '+ this.id);
});
});
<div class="product-bg-container product-general-info variation-info">
<input type="hidden" name="sku" value="Something-15892290" id="selected-option">
<button id="buy-now" class="btn btn-lg hidden-sm-down btn-primary">
Add to Cart
</button>
<button id="buy-now2" class="btn btn-lg hidden-md-up btn-primary">
Add to Cart
</button>
</div>
nextElementSibling seems working in this case.
var btn1 = document.getElementById("btn");
var btn2 = btn1.nextElementSibling;
btn1.addEventListener("click",function(e){
console.log("btn1");
});
btn2.addEventListener("click",function(e){
console.log("btn2");
});
<div>
<button id="btn" class="btn1">butotn 1</button>
<button id="btn" class="btn2">butotn 2</button>
</div>

How do I toggle a class in Angular

I have a button that I want to be able to toggle a class on a div to hide and show the div how would I do that in Angular?
HTML
<div id="chatsidebar">
<app-chatsidebar></app-chatsidebar>
</div>
<div>
<button type="button" id="sidebarCollapse" class="btn btn-info" (click)="togglesideBar()">
<i class="glyphicon glyphicon-align-right"></i>
Toggle Sidebar
</button>
</div>
I want to add the class "active" onto the #chatsidebar div
app.component.ts
togglesideBar() {
}
Thanks
I'm answering this part of your question:
I want to add the class "active" onto the #chatsidebar div
To do it, you can use NgClass. NgClass allows you to add or remove any class to or from an element based on the given condition. Your code will looks something like this:
HTML
<div id="chatsidebar" [ngClass]="{'active': isSideBarActive}"> <!-- this ngClass will add or remove `active` class based on the `isSideBarActive` value -->
<app-chatsidebar></app-chatsidebar>
</div>
<div>
<button type="button" id="sidebarCollapse" class="btn btn-info" (click)="togglesideBar()">
<i class="glyphicon glyphicon-align-right"></i>
Toggle Sidebar
</button>
</div>
Component
isSideBarActive: boolean = true; // initial value can be set to either `false` or `true`, depends on our need
togglesideBar() {
this.isSideBarActive = !this.isSideBarActive;
}
HTML
<div id="chatsidebar" *ngIf="status">
<app-chatsidebar></app-chatsidebar>
</div>
<div>
<button type="button" id="sidebarCollapse" class="btn btn-info" (click)="togglesideBar()">
<i class="glyphicon glyphicon-align-right"></i>
Toggle Sidebar
</button>
</div>
app.component.ts:
status:boolean=true;
togglesideBar() {
if(this.status == true) this.status=false;
else this.status = true;
}
Demo:
https://plnkr.co/edit/fNoXWhUhMaUoeMihbGYd?p=preview
you can try below.
<div id="chatsidebar" class="{{activeClass}}"> ... </div>
and on your component define a property and set the class value on toggle function
// On Component
activeClass : string = "";
...
togglesideBar() {
this.activeClass = 'active'
}
it shall work, but may not the ideal solution.
Assuming you have a class named hide:
<div [class.hide]="hide">
<app-chatsidebar></app-chatsidebar>
</div>
<div>
<button type="button" class="btn btn-info" (click)="togglesideBar()">
<i class="glyphicon glyphicon-align-right"></i>
Toggle Sidebar
</button>
</div>
togglesideBar() { this.hide = !this.hide; }
This will hide the element in question, while leaving it in the DOM. The other solutions using *ngIf will add and remove the element to and from the DOM. There are subtle reasons in specific cases to prefer one over the other, well described in the on-line documentation you have already read. In this case, it doesn't really matter.
The [class.className]=boolean format is just one of several ways to control classes in Angular. For instance, you could also have said:
[ngClass]="{'hide': hide}"
This is slightly more flexible because you can add/remove multiple classes at once.
Since you are using glyphicons, you are probably using Bootstrap, so you most likely already have the hide class defined.
As an aside, you rarely need IDs, and using them is pretty much of an anti-pattern in Angular.
Take a variable in your component something like
isShowChatSidebar:boolean=true;
then modify your method and html
togglesideBar() {
this.isShowChatSidebar=!this.isShowChatSidebar
}
<div id="chatsidebar" [ngClass]="{'active': isShowChatSidebar}">>
<app-chatsidebar></app-chatsidebar>
</div>

getElementById with multiple buttons

I'm struggling to get my links to enable their respective buttons. For instance the first link should enable the first button and the second should enable button 2.
Can anyone help?
Link 1
Link 2
<button disabled class="btn btn-primary pull-left" id="butt1">Button 1</button>
<button disabled class="btn btn-primary pull-left" id="butt2">Button 2</button>
Your problem is your use of quotation marks. There are two options:
Use single quotes
Use " or \22 instead of your double quotes
Explanation
Your onclick is wrapped in double quotes. As soon as you use a double quote, it's the end of the onclick.
Solution
Link 1
Link 2
Demonstration
See this fiddle (Thanks #JamesThorpe for updating the escaped quote option)
Note, I removed the href because it doesn't make sense to link somewhere if you're going to do something on the current page.
removeAttribute(:attribute) can do the trick as well.
Link 1
<button disabled class="btn btn-primary pull-left" id="butt1">Button 1</button>
Just change the quatation marks for the id from double to single ones:
document.getElementById('butt1').disabled=false;
If the anchor is just for the activation, add an return false at the end:
document.getElementById('butt1').disabled=false; return false;
Change the "butt*" with 'butt*' , otherwise the browser read this
onclick="document.getElementById("
and edit the href="link" with href="#" (this is not mandatory, but the question as it is now is a little strange)
Link 1
Link 2
<button disabled class="btn btn-primary pull-left" id="butt1">Button 1</button>
<button disabled class="btn btn-primary pull-left" id="butt2">Button 2</button>
you problem in this string
"document.getElementById("butt1").disabled=false"
it should be
"document.getElementById('butt1').disabled=false"
Fiddle here
With a bit more work you start enabling a bit more elements, or add functionality that you could expand on easier in the future.
As a simple example, i added a small javascript file where you could set the elements that upon click activate/deactivate the other elements.
Currently i am preventing the default action, so you wouldn't be navigating towards the link you are actually setting, but that is entirely up to you ;)
;(function (ns) {
var actionElements = {
l1: ['butt1'],
l2: ['butt2']
};
function bootstrap() {
var prop, value, element;
for (prop in actionElements) {
if (actionElements.hasOwnProperty(prop)) {
element = document.getElementById(prop);
value = actionElements[prop];
if (element) {
element.addEventListener('click', function(e) {
if (typeof e === 'undefined') {
var e = window.event;
}
e.preventDefault();
for (var i = 0; i < this.length; i++) {
var el = document.getElementById(this[i]);
el.disabled = false;
}
return false;
}.bind(value));
}
}
}
}
ns.addEventListener('load', bootstrap);
}(window));
Link 1
Link 2
<button disabled class="btn btn-primary pull-left" id="butt1">Button 1</button>
<button disabled class="btn btn-primary pull-left" id="butt2">Button 2</button>

Categories