Change Icon on Bootstrap 4.6 accordion - javascript

I want to have a 'plus' icon when the accordion is collapsed, and a 'minus' icon when the accordion is 'expanded'.
I have checked other answers on the internet, but what am I asking is can't I do something simple like this? (For learning purposes)
Say I place both the plus and minus icons on the accordion
<i class="fa-plus"> <i class="fa-minus">
As I see, when the accordion is collapsed, it has a collapsed class, so I'd like to hide and show both the icons as the collapsed class gets toggled on click. Why doesn't it work as the DOM gets updated when the accordion is clicked?
if(document.getElementById('candidateName').classList.contains('collapsed')) {
document.querySelector('.fa-minus').style.display = 'none';
document.querySelector('.fa-plus').style.display = 'block';
}
else {
document.querySelector('.fa-plus').style.display = 'none';
document.querySelector('.fa-minus').style.display = 'block';
}
Please note that this is just for learning purposes. I want to understand this, please don't get offended. Thankyou

Glad you are learning. Apologies if my response comes across in a different plane than your current level.
When you run JS, you're executing the code in the current state of the content. It appears that you are hoping for the icon to change from a + to a - and vice verse when the accordion is expanded/collapsed.
What you need to do, is watch the page for changes to the accordion - these are called event listeners. Bootstrap has some really convenient ones that you can use for this. Since the Accordion uses collapse events API. From there, you can watch the page for changes, and execute the change you want whenever that change happens.
const myCollapsible = document.getElementById('myCollapsible')
myCollapsible.addEventListener('hidden.bs.collapse', event => {
// do something...
})

Related

Controlling bootstrap accordion with jQuery

I'm currently implementing a bootstrap accordion widget, and would like to place an element on each panel's body that allows me to switch the currently open panel (expands another and hides the others). I'm currently doing this by using a jQuery wildcard selector to collapse all the panels, and then showing the one I need:
$(".displayPanel").click((e) => {
$("[id^='collapse']").collapse('hide');
$("#collapse" + e.target.text).collapse('show');
})
For some reason this seems to affect the default Bootstrap behavior of opening and closing panels (Panels end up getting left open, etc). Here is a minimal example to demonstrate the issue. Is there a better way to go about accomplishing something like this?
Thanks in advance.
You must to wait for "hide" and then you can run "show". Here the updated fiddle.
Probably it would be cleaner if there was an event to indicate when "Hide" is completed.
$(".displayPanel").click((e) => {
$("[id^='collapse']").collapse('hide');
setTimeout(function(){
$("#collapse" + e.target.text).collapse('show');
},1000);
});

Bootstrap Popover AND a Modal (hover and click)

Scenario: user profile. I would like to be able to display a user name with a popover that displays a limited amount of information from the user profile. So far, I have that part working. I can build it on the fly and have it do what I need. The popover works perfectly.
What I would also like to do is have the user be able to click on the user name and bring up a Bootstrap modal form with more information about the user (if provided). The first problem I am seeing is that it appears the data-toggle attribute can only have a single setting:
echo '' . $user_row['user_name'] . '';
In that example, if I add the modal to the data-toggle attribute it doesn't seem to do me much good.
I have discovered by tinkering (and that is why the class 'userprof' in the code above), that a JavaScript click event can be triggered (right now all I'm doing is a basic JS alert dialog to test), but from there I would want to load the modal. I am not sure if I can make it all work.
I have a set of functions I've used successfully for another modal (calling this one 'userModal') that I got some help from someone here a while back with -- is it possible to call that from the click event?
// code to open the modal with the caption and description:
$('#userModal').on('show.bs.modal', function (event)
{
var button = $(event.relatedTarget); // Button that triggered the modal
var title = button.data('title'); // Extract info from data-* attributes
var body = button.data('body'); // Extract info from data-* attributes
var modal = $(this);
modal.find('.modal-title').text( title );
modal.find('.modal-body').append( body );
});
// when modal closes, clear out the body:
$('#userModal').on('hidden.bs.modal', function ()
{
$(this).find(".modal-body").text('');
});
Since these are "anonymous" functions I am not sure I can call them ... feeling a bit lost in the code here. Any help pointing me in the right direction would be great. I'd even be willing to consider a different idea, but I would like this kind of functionality (hover and click) for this situation and possibly something else. Thanks!
You're listening for the modal to show itself, when the DOM is showing the modal.
try using something like this, and use a button or a link with data-toggle="modal"
$(document).on('hidden.bs.modal', '#userModal', function ()
{
$(this).find(".modal-body").text('');
});
for reference https://jsfiddle.net/y063mu4t/1/
You can try:
$(document).on('click', 'a.userprof', function(){
$('#userModal').modal('show');
});
To make your callback function work, you need to add according data-* attribute to each of the <a> tag.

Prevent closing of a navbar with another element's trigger click

I am using jasny bootstrap offcanvas navbar ( http://jasny.github.io/bootstrap/components/#navmenu-offcanvas ) which will close whenever a click event occurs elsewhere on the page. However, we have a Twitter feed that has been modified to move between 3 different Twitter accounts. In order to switch between them a click is triggered. This is causing the navmenu to close each time the tweets switch and I cannot seem to prevent it.
Here is the twitter scroll code:
var tabCarousel = setInterval(function() {
var tabs = $('#twittertab > li'),
active = tabs.filter('.active'),
nextone = active.next('li'),
toClick = nextone.length ? nextone.find('a') : tabs.eq(0).find('a');
toClick.trigger('click');
}, 5000)
I've tried applying preventDefault() and stopPropagation() to the trigger('click') but I am very inexperienced with jQuery and am really just guessing where to put this.
For anyone having a similar issue, the answer is simple if you don't mind sacrificing the navbar closing with any click outside of the navbar itself. Ie, the solution means clicking outside the navbar will not close it.
Simply add 'data-autohide="false"'to the offcanvas element.
I then added a function to toggle the navbar state on click of a link within the navbar as follows;
$('#my-menu > li > a').click(function() {
$('.navmenu').offcanvas('toggle');
});
This means if you have links that do not go to another page, but an anchor somewhere on the same page, the menu will close when you click to move to that section.
If you are want to close the navmenu on inside link click then you must add "data-autohide="false"" on this
<div class="navmenu navmenu-default navmenu-fixed-right offcanvas">
and add this script $(document).ready(function(){$('.navmenu a').click(function() {
$('.navmenu').offcanvas('hide');
});})
in your code. that's it.
Note: It's work like charm in single page application.

How to synchronize toggle selections across pages with JQuery Mobile?

I have a need to have a multi-page html, with each page containing an identical toggle. When the user changes a toggle on one page, all the toggles on the other pages should change (or at least change on loading the other pages).
I've created a Fiddle to illustrate a simple scenario, with a two page example and identical toggles on each page. I'd LIKE to be able to change the toggle on page 2 by toggling the toggle on page 1
http://jsfiddle.net/vSr99/
I've tried a number of methods, and yes have included a refresh after attempting to manipulate with javascript, but have not even come close, no doubt due to my programatically challenged nature :-/
If anyone can suggest a simple solution I'd much appreciate it!
Thx
try setting a global attribute when the button is clicked and store this on $('html') like so:
$('html'). attr('toggleIs',true);
then you can check for this on pagebforeshow and add the toggled state to the buttons on all new pages being pulled into view depending on the button state.
EDIT
Here is a jsfiddle (ignore the first alert);
Here is the html:
$(document).on('change', '.your_select', function(){
// set
if( $(this).find('option:selected').val() == "on" ){
$('html').data('toggle', 'on');
} else {
$('html').data('toggle', 'off');
}
});
$(document).on('pagebeforeshow', '.ui-page', function(){
var that = $(this).find('.your_select');
// clear
that.find('option').removeAttr('selected');
// reset
if($('html').data('toggle') == "on" ){
alert("should be on")
that.find('select option[value="on"]').attr('selected', 'selected')
} else {
alert("should be off")
that.find('option[value="off"]').attr('selected', 'selected')
}
// refresh slider
...
});
please note:
took me a while to see you where using jquery 1.6.4, so my on-bindings didn't work. If you want to keep, you need to use live for the bindings to also capture pages being pulled in.
I gave a class to all sliders, to set them together
I cannot get the JQM slider('refresh') to work on the slider or any parent element... you will have to figure that out by yourself, but the synchronizing is working :-)

Superfish, 2 menus open at once - how to prevent?

I have a super fish menu, the delay is set to 800, but when I move from one drop-down to another it still shows the previous drop-down and the new drop-down at the same time. until the 800ms delay is over then the previous drop-down goes away. I do not want to change the delay, but if a new drop-down is opened, I want the previously opened drop-down to close right away without delay. I hope this makes sense.
Is there a way to do that?
Thanks!!
Click to view
On its website, delay is set to 800 and I guess it works fine, it doesn't display old popup. Did you make any other changes in its code?
http://users.tpg.com.au/j_birch/plugins/superfish/#examples
Edit:
Ok here is a solution if you don't want to modify your multiple UL menu structure to a single UL. Just give unique ids to each UL, then modify over = function() in superfish.js like this
over = function(){
var $$ = $(this), menu = getMenu($$);
$('.sf-menu').each(function(){
if ($(this).attr('id') != $(menu).attr('id')) {
$(this).hideSuperfishUl();
}
});
clearTimeout(menu.sfTimer);
$$.showSuperfishUl().siblings().hideSuperfishUl();
},
this may cause some other side effects but I don't see any for now.

Categories

Resources