Bootstrap Collapsible w/ion-icons that change on click - javascript

I'm using bootstraps collapsible containers on a website to display some info, I am also using ion-icons to have a + & - to indicate when the container is open or closed, for some reason I am struggling to target the icons to be able to change them, I've tried this thus far.
html
<div class="accordion-item">
<div class="accordion-header w-100" id="headingOne">
<a class="collapsed w-100 d-flex justify-content-between align-items-center" id="toggle" data-bs-toggle="collapse" data-bs-target="#collapse-One" aria-expanded="true" aria-controls="collapse-One">
Title <ion-icon itemid="iconChange" name="add"></ion-icon>
</a>
</div>
<div id="collapse-One" class="accordion-collapse collapse" aria-labelledby="headingOne" data-bs-parent="#accordionProductInfo">
<div class="accordion-body">
Info
</div>
</div>
</div>
js
var myCollapsible = document.getElementById('#toggle')
myCollapsible.addEventListener('show.bs.collapse', function () {
var icon = $("#iconChange");
icon.attr('name', 'remove-outline');
console.log(icon[0]);
});
I know this is only to change it one way so far but I cant even get a message out of the console log.

Related

I cannot solve a Uncaught TypeError: Cannot read properties of undefined (reading 'remove') for a Change event

I need to make a change on the icons passing the class .fa-plus to .fa-minus thats for this menu
<div class="accordion-menu">
<h2 class="accordion-header" id="subseccOne">
<button class="accordion-button-m" type="button" >
<i class="fa-solid fa-plus" data-bs-toggle="collapse" data-bs-target="#subsecollapseOne" aria-expanded="true" aria-controls="subsecollapseOne"></i> <a class="item-section" href="">SEGUNDO NIVEL </a>
</button>
</h2>
<div id="subsecollapseOne" class="accordion-collapse collapse" aria-labelledby="subseccOne" data-bs-parent="#subsecc">
<div class="accordion-body">
<div class="accordion" id="accordionExample">
<div class="accordion-menu">
<h2 class="accordion-header" id="headingOne">
<button class="accordion-button-m" type="button" >
<i class="fa-solid fa-plus" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne" ></i> <a class="item-section" href=""> TERCER NIVEL </a>
</button>
</h2>
<div id="collapseOne" class="accordion-collapse collapse" aria-labelledby="headingOne" data-bs-parent="#accordionExample">
<div class="accordion-body">
<strong>This is the first item's accordion body.</strong> It is shown by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the <code>.accordion-body</code>, though the transition does limit overflow.
</div>
</div>
</div>
<div class="accordion-menu">
<h2 class="accordion-header" id="headingTwo">
<button class="accordion-button-m collapsed" type="button" >
<i class="fa-solid fa-plus" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></i> <a class="item-section" href=""> TERCER NIVEL </a>
</button>
</h2>
<div id="collapseTwo" class="accordion-collapse collapse" aria-labelledby="headingTwo" data-bs-parent="#accordionExample">
<div class="accordion-body">
<strong>This is the second item's accordion body.</strong> It is hidden by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the <code>.accordion-body</code>, though the transition does limit overflow.
</div>
</div>
</div>
<div class="accordion-menu">
<h2 class="accordion-header" id="headingThree">
<button class="accordion-button-m collapsed" type="button" >
<i class="fa-solid fa-plus" data-bs-toggle="collapse" data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree"></i> <a class="item-section" href=""> TERCER NIVEL </a>
</button>
</h2>
<div id="collapseThree" class="accordion-collapse collapse" aria-labelledby="headingThree" data-bs-parent="#accordionExample">
<div class="accordion-body">
<strong>This is the third item's accordion body.</strong> It is hidden by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the <code>.accordion-body</code>, though the transition does limit overflow.
</div>
</div>
</div>
</div>
</div>
</div>
</div>
my JavaScript function is this
const icon= document.querySelectorAll(".fa-solid");
const plusIcon = document.querySelectorAll(".fa-plus");
for (i =0; i < plusIcon.length; i++){
plusIcon[i].addEventListener("click", function (){
icon.classList.remove("fa-plus");
icon.classList.add("fa-minus")
});
}
I dont know why the console print this error, When the click event run on tghe function
menu_funcionalidad.js:29 Uncaught TypeError: Cannot read properties of undefined (reading 'remove')
at HTMLElement.
You are getting the error because you already assigned icon to a nodeList, so when trying to change the classes, icon is not an individual element. I would suggest using event.target to manipulate the element that has been clicked.
const icon= document.querySelectorAll(".fa-solid");
const plusIcon = document.querySelectorAll(".fa-plus");
for (i =0; i < plusIcon.length; i++){
plusIcon[i].addEventListener("click", e => {
e.target.classList.remove("fa-plus");
e.target.classList.add("fa-minus");
plusIcon.forEach(item => {
if (item !== e.target) item.classList.add('//class-name');
});
});
}
document.querySelectorAll(".fa-solid") will return a nodeList, meaning that when you attempt to access the classList inside your loop, you're attempting to access the classList of a nodeList, which is not possible.
If you want to add/remove the icons for each item in that node list, you can iterate over that list with .forEach() (See more here).
If you want to add/remove the icon from the element you're currently iterating over, replace icon.classList... with i.classList.
If the second route is what you're looking for, you could also add in a check inside the loop like:
for (i =0; i < plusIcon.length; i++){
plusIcon[i].addEventListener("click", function (){
if (i.classList.contains("fa-plus") {
icon.classList.remove("fa-plus");
} else
icon.classList.add("fa-minus");
}
});
}

How to add active and remove existing active class collapse on bootsrap 4

Someone please help me, how to add "active" class after "careers-menu-container" class and remove existing another active class when click button(a)?.
please check my code below!.
Thanks a lot off.
<div class="container" id="myCollapse">
<div class="col-sm-12 col-md-4 order-sm-1 order-md-1">
<div class="careers-menu-container careers-menu-container__img1">
<a data-toggle="collapse" href="#collapseExtension1" role="button" aria-expanded="false" aria-controls="collapseExtension">APPLY NOW <i class="fas fa-caret-right"></i>
</a>
</div>
</div>
<div class="collapse" id="collapseExtension1" data-parent="#myCollapse">
<p>lorem ipsum</p>
</div>
<div class="col-sm-12 col-md-4 order-sm-3 order-md-2">
<div class="careers-menu-container careers-menu-container__img1">
<a data-toggle="collapse" href="#collapseExtension2" role="button" aria-expanded="false" aria-controls="collapseExtension">APPLY NOW <i class="fas fa-caret-right"></i>
</a>
</div>
</div>
<div class="collapse" id="collapseExtension2" data-parent="#myCollapse">
<p>lorem ipsum</p>
</div>
</div>
$(".collapse.show").each(function(){
// show active class here
});
// Toggle plus minus icon on show hide of collapse element
$(".collapse").on('show.bs.collapse', function(){
// show active class and remove another active class
}).on('hide.bs.collapse', function(){
// remove class here and show another active class
});
You can access .careers-menu-container via .collapse using .parent():
$(".collapse").on('show.bs.collapse', function(){
$(this).parent().addClass('active')
}).on('hide.bs.collapse', function(){
$(this).parent().removeClass('active')
});

Bootstrap data-toggle doesn't work with ember component

I have a jquery plugin that creates following html
<div class="panel-heading">
<h4 class="">
<a data-toggle="collapse" href="#collapse2" class="collapsible-title display-inline full-width bold">Select Gigs</a>
</h4>
</div>
<div id="collapse2" class="panel-collapse collapse">
<div class="panel-body">
<div class="row">
<div class="col-xs-12">
<input type="text" class="input-text-field margin-medium-bottom" placeholder="Search" />
</div>
</div>
...... and some other divs here .....
I want to toggle div with id collapse2 when click on <a></a> above it. It works fine if I add the html inside hbs file. But when I create above html inside jquery and insert into the DOM as follows it change the url to domain/#collapse2
_initializeAutoComplete: function () {
Ember.$('#' + this.get('divId')).setAutocomplete({
data: this.get('dataTree'),
multiSelect: true,
selectingType: 3
});
}.on('didInsertElement')
});
How can I make the toggling work without ember going to href as a url change?
Appreciate any help.
Move the bootstrap attributes to the div above (or h4 or create new as your need)
<div class="panel-heading" data-toggle="collapse" href="#collapse2" class="collapsible-title display-inline full-width bold">
<h4 class="">
Select Gigs
</h4>
</div>

collapse in hide or show do it from js

I write some control unit that switch couple of containers by using "collapse" class from bootstrap like list with anchors that has special for my hidden containers "href" attribute, here is example of two list elements that can describe behaviour:
<div id="my_list">
<ul>
<li class="active">
<a onclick="return false" data-parent="#switch_tables" href="#collapse1">One</a>
</li>
<li>
<a onclick="return false" data-parent="#switch_tables" href="#collapse2">Two</a>
</li>
</div>
Then in html code i use some container:
<div id="switch_tables" class="panel">
<div id="collapse1" class="collapse in"> SOME IN HERE </div>
<div id="collapse2" class="collapse"> SOMETHING ELSE</div>
</div>
So when i use this stuff and first elemet of list is active the first container is shown too because i add "in" class after "collapse" class. When I switch to the other list element, then first container should dissappear and the second one should be shown. Of course I has more list links and more hidden containers than just 2 but it's just an example. The thing that I want to do is to prevent default behaviour and to forbid active elemet to hide by clicking on it.
So I switch the "active" list element by clicking on list items and also show or hide exact container that has same id that the list has, so the containers is linked with list items, this thing is done by js code:
$(function(){
$('ul li a').on('click', function(){
$(this).parent().addClass('active').siblings().removeClass('active');
var to_toggle = $(this).attr('href');
$('.collapse.in').collapse('hide');
$(to_toggle+':not(".in")').collapse('show');
});
});
And now I see when I switch between list items, the containers appear and hide correctly.
When I click on second link, I see how first container is hiding and the second one is appear, and vice versa.
Idea is that if there is open containers, the ones that has "collapse in" class should be closed by js, but how to forbid closing an active container?
For example I click on second link in list, my first container is hiding, second one is appear, I click on second link again and second container dissappear so I dont see anything on screen. but the list item is active.
So the question is how to modify js so only one container can have "collapse in" class at a time, and nothing can remove it until the user will switch it to other container so class "in" will move to other container that is coming from anchor attribute "href" and can't be removed in this place?
If you are using bootstrap , so you can use bootstrap collapse feature for example:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Collapse</title>
<link rel="stylesheet" href="../../../dist/css/bootstrap.min.css">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<div class="page-header">
<h1>Collapse <small>Bootstrap Visual Test</small></h1>
</div>
<div class="panel-group" id="accordion">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne">
Collapsible Group Item #1
</a>
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse in">
<div class="panel-body">
Collapse one content
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo">
Collapsible Group Item #2
</a>
</h4>
</div>
<div id="collapseTwo" class="panel-collapse collapse">
<div class="panel-body">
Collapse two content
</div>
</div>
</div>
</div>
</div>
<!-- JavaScript Includes -->
<script src="../vendor/jquery.min.js"></script>
<script src="../../transition.js"></script>
<script src="../../collapse.js"></script>
</body>
</html>
So I solve my problem by point from #Zigri2612 but use little different approach:
$(function(){
$('ul li a').on('click', function(){
$(this).parent().addClass('active').siblings().removeClass('active');
var to_toggle = $(this).attr('href');
$("#switch_tables").find('div').each(function(){
if ( ('#'+$(this).attr("id")) != to_toggle )
$(this).filter('.collapse.in').collapse('hide');
});
$(to_toggle+':not(".in")').collapse('show');
});
});
Here is a working example for collapse hide and show. here the plus and minus icons are changing. you can alter it for your need.
$(document).ready(function(){
// Add minus icon for collapse element which is open by default
$(".collapse.show").each(function(){
$(this).prev(".card-header").find(".fa").addClass("fa-minus").removeClass("fa-plus");
});
// Toggle plus minus icon on show hide of collapse element
$(".collapse").on('show.bs.collapse', function(){
$(this).prev(".card-header").find(".fa").removeClass("fa-plus").addClass("fa-minus");
}).on('hide.bs.collapse', function(){
$(this).prev(".card-header").find(".fa").removeClass("fa-minus").addClass("fa-plus");
});
});
.bs-example{
margin: 20px;
}
.accordion .fa{
margin-right: 0.5rem;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.1/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<style>
</style>
<div class="bs-example">
<div class="accordion" id="accordionExample">
<div class="card">
<div class="card-header" id="headingOne">
<h2 class="mb-0">
<button type="button" class="btn btn-link" data-toggle="collapse" data-target="#collapseOne"><i class="fa fa-plus"></i> What is HTML?</button>
</h2>
</div>
<div id="collapseOne" class="collapse" aria-labelledby="headingOne" data-parent="#accordionExample">
<div class="card-body">
<p>HTML stands for HyperText Markup Language. HTML is the standard markup language for describing the structure of web pages. Learn more.</p>
</div>
</div>
</div>
<div class="card">
<div class="card-header" id="headingTwo">
<h2 class="mb-0">
<button type="button" class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapseTwo"><i class="fa fa-plus"></i> What is Bootstrap?</button>
</h2>
</div>
<div id="collapseTwo" class="collapse show" aria-labelledby="headingTwo" data-parent="#accordionExample">
<div class="card-body">
<p>Bootstrap is a sleek, intuitive, and powerful front-end framework for faster and easier web development. It is a collection of CSS and HTML conventions. Learn more.</p>
</div>
</div>
</div>
<div class="card">
<div class="card-header" id="headingThree">
<h2 class="mb-0">
<button type="button" class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapseThree"><i class="fa fa-plus"></i> What is CSS?</button>
</h2>
</div>
<div id="collapseThree" class="collapse" aria-labelledby="headingThree" data-parent="#accordionExample">
<div class="card-body">
<p>CSS stands for Cascading Style Sheet. CSS allows you to specify various style properties for a given HTML element such as colors, backgrounds, fonts etc. Learn more.</p>
</div>
</div>
</div>
</div>
</div>

Bootstrap Collapse doesn't toggle after you show, hide or toggle from code

My HTML is:
<div id="accordion-container">
<div class="accordion" id="navaccordion">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#navaccordion" href="#collapseMenu">
<strong>My Menus</strong>
</a>
</div>
<div id="collapseMenu" class="accordion-body collapse in">
<div class="accordion-inner">
<div class="navigation" id="navigationcontainer">
<span id="menutree">
MenuTree
</span>
</div>
</div>
</div>
</div>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#navaccordion" href="#collapseQuickLinks">
<strong>Quick Links</strong>
</a>
</div>
<div id="collapseQuickLinks" class="accordion-body collapse">
<div class="accordion-inner">
<div class="quicklinks" id="quicklinkscontainer">
<span id="quicklinkslist">
QuickLinks
</span>
</div>
</div>
</div>
</div>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#navaccordion" href="#collapseQueue">
<strong>Queue</strong>
</a>
</div>
<div id="collapseQueue" class="accordion-body collapse">
<div class="accordion-inner">
<div class="queue" id="queuecontainer">
<span id="queuetree">
Queue
</span>
</div>
</div>
</div>
</div>
</div>
</div>
My example is here: http://jsfiddle.net/pdavis68/Xut4C/2/
If you remove the JavaScript code, you'll notice that the toggling of the collapse operates properly. If you click "Quick Links", "My Menus" closes and "Quick Links" opens.
If you leave the JS in, you'll notice that opening "My Menus" or "Quick Links" doesn't cause anything else to collapse, but if you open "Queue", it will still cause the others to collapse.
It doesn't seem to matter if I use "toggle", "show" or "hide" command in the collapse, it will break the toggling functionality.
Also, in the example, what ought to happen (by my reckoning, at least) is that that "My Menus" should toggle closed (which it does) and then "Quick Links" ought to toggle open (which it does NOT do.)
So, 2 questions:
How do I programmatically show/hide groups without breaking the toggle functionality?
How do I toggle things open?
1.Try to use collapse() with options, the 'parent' is important
$("#collapseMenu").collapse({"toggle": true, 'parent': '#navaccordion'});
$("#collapseQuickLinks").collapse({"toggle": true, 'parent': '#navaccordion' });
Fiddle: http://jsfiddle.net/hieuh25/Xut4C/6/
2.Basically you have 2 ways:
Add class in to that div, e.g: <div id="collapseMenu" class="accordion-body collapse in"> cause that div to open.
Use collapse() with option 'toggle': true as above, when the div is closed.
Hope it helps.
Try activating your content as a collapsible element first. I skimmed over this part when reading the documentation and it really stumped me.
$('#myCollapsible').collapse({
toggle: false
})
After you activate it you can hide and show it as usual.
$('#myCollapsible').collapse('hide');
$('#myCollapsible').collapse('show');
http://getbootstrap.com/javascript/#collapse-methods
You also can add data-parent="#navaccordion" to <div id="collapseMenu" class="accordion-body collapse" data-parent="#navaccordion"> and call without addional key 'parent' like .collapse({"toggle": true});

Categories

Resources