I'm trying to add a clickable helping zone in my Bootstrap 5 accordion, as you can see in this screenshot :
I want the user to be capable of clicking the question mark, that will open a Bootstrap modal with some helping text.
However, when doing so, the modal is opening but the accordion is collapsing (or opening if closed).
I've used the following JavaScript code to achieve this goal :
const categHelpBtns = document.querySelectorAll('.categ_help');
for (let i = 0; i < categHelpBtns.length; i++) {
const btn = categHelpBtns[i];
if(btn) {
btn.addEventListener("click", function(e) {
e.stopPropagation();
const modal = document.getElementById(btn.dataset.modalId)
if(modal) {
new bootstrap.Modal(modal).show();
}
});
}
}
Any clues how I can prevent the accordion to collapse/open when clicking the help icon ?
const categHelpBtns = document.querySelectorAll('.categ_help');
for (let i = 0; i < categHelpBtns.length; i++) {
const btn = categHelpBtns[i];
if(btn) {
btn.addEventListener("click", function(e) {
e.stopPropagation();
const modal = document.getElementById(btn.dataset.modalId)
if(modal) {
new bootstrap.Modal(modal).show();
}
});
}
}
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w==" crossorigin="anonymous" referrerpolicy="no-referrer"/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
</head>
<body>
<div class="accordion">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button onglet-header" type="button" data-bs-toggle="collapse" data-bs-target="#nom_pays" aria-expanded="true" aria-controls="nom_pays">
Accordion <i class="fas fa-question-circle categ_help" data-modal-id="modal" aria-hidden="true"></i>
</button>
</h2>
<div id="nom_pays" class="accordion-collapse collapse show" aria-labelledby="nom_pays_header" data-bs-parent="#fiche_bois">
<div class="accordion-body">
Accordion Body
</div>
</div>
</div>
</div>
<div class="modal fade" id="modal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Data</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"/>
</div>
<div class="modal-body">
Modal body
</div>
</div>
</div>
</div>
</body>
</html>
You do not have to write extra JavaScript to trigger modal.
You can easily do it with the bootstrap html attributes.
In order to trigger your modal, by clicking the question mark
Replace:
<i class="fas fa-question-circle categ_help" data-modal-id="modal" aria-hidden="true"></i>
With:
<i class="fas fa-question-circle categ_help" data-modal-id="modal" aria-hidden="true" data-bs-toggle="modal" data-bs-target="#modal"></i>
Related
I have two different dropdown options I'm using. One is for some search options, and the other is for a navigation menu.
Currently, I'm unable to open a single menu at one time. They both open, one on top of the other. I'm unable to figure out how to keep only one menu open at a time.
If the navigation menu is open and I click the search option, then the navigation menu should close. If I have the search option open and I click the navigation menu, then search should close.
How can I accomplish this with JavaScript?
//icon switch
const hamburgerMenuBtnContainer = document.querySelector('.hamburger-toggle');
const hamburgerMenuBtn = document.querySelector('.hamburger-toggle i');
const magnifyingGlassBtnContainer = document.querySelector('.search-toggle');
const magnifyingGlassBtn = document.querySelector('.search-toggle i');
hamburgerMenuBtnContainer.addEventListener('click', function() {
hamburgerMenuBtn.classList.toggle('fa-x');
hamburgerMenuBtn.classList.toggle('fa-bars');
});
magnifyingGlassBtnContainer.addEventListener('click', function() {
magnifyingGlassBtn.classList.toggle('fa-x');
magnifyingGlassBtn.classList.toggle('fa-magnifying-glass');
})
.search-collapse {
flex-basis: 100%;
flex-grow: 1;
padding: 1rem 0;
min-height: 1px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"></script>
<nav class="navbar navbar-expand-lg navbar-light shadow">
<div class="container-fluid nav-container">
<h3 class="logo">Logo Here</h3>
<div class="navbar-right">
<!-- Two -->
<button class="btn border-0 collapsed nav-btn me-3" type="button" data-bs-toggle="collapse" data-bs-target="#search-content">
<div class="search-toggle">
<div class="search">
<i class="fa-solid fa-magnifying-glass"></i>
</div>
</div>
</button>
<!-- Three -->
<button type="button" class="navbar-toggler collapsed nav-btn" data-bs-toggle="collapse" data-bs-target="#navbar-content">
<div class="hamburger-toggle">
<div class="hamburger">
<i class="fa-sharp fa-solid fa-bars"></i>
</div>
</div>
</button>
</div>
<!-- Nav Content -->
<div class="collapse search-collapse" id="search-content">
<h4>Search Options</h4>
</div>
<div class="collapse navbar-collapse" id="navbar-content">
<h4>Navigation Options</h4>
</div>
</div>
</nav>
I have a bottom offcanvas in my webpage, i would open it on a card click, by trying to set the needed attributes or by using the code from the docs it's not working as the offcanvas shows only the backdrop and dismiss it immedialty.
Here is what i've tried:
const products = document.getElementsByClassName("card product");
var productClick = function (event) {
event.preventDefault()
var myOffcanvas = document.getElementById('offcanvasBottom')
var bsOffcanvas = new bootstrap.Offcanvas(myOffcanvas)
bsOffcanvas.show();
};
Array.from(products).forEach(function (element) {
element.addEventListener("click", productClick);
});
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta3/dist/js/bootstrap.bundle.min.js" integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf" crossorigin="anonymous"></script>
<div class="card product" style="width: 18rem">
<div class="card-body text-center">
<h2 class="card-title fw-bolder">TEST</h2>
<p class="card-text fw-bolder">TEST</p>
</div>
</div>
<div
class="offcanvas offcanvas-bottom"
tabindex="-1"
id="offcanvasBottom"
>
<div class="offcanvas-header">
<button
type="button"
class="btn-close text-reset"
data-bs-dismiss="offcanvas"
aria-label="Close"
></button>
</div>
<div class="offcanvas-body">
BODY
</div>
</div>
The problem is the card click event is propagating to inside elements. Instead use event.stopPropagation()...
const products = document.getElementsByClassName("product");
var myOffcanvas = document.getElementById('offcanvasBottom')
var productClick = function (event) {
//event.preventDefault()
event.stopPropagation()
var bsOffcanvas = new bootstrap.Offcanvas(myOffcanvas)
bsOffcanvas.show()
}
Array.from(products).forEach(function (element) {
element.addEventListener("click", productClick);
})
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta3/dist/js/bootstrap.bundle.min.js" integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf" crossorigin="anonymous"></script>
<div class="card product" style="width: 18rem">
<div class="card-body text-center">
<h2 class="card-title fw-bolder">TEST</h2>
<p class="card-text fw-bolder">TEST</p>
</div>
</div>
<div
class="offcanvas offcanvas-bottom"
tabindex="-1"
id="offcanvasBottom"
>
<div class="offcanvas-header">
<button
type="button"
class="btn-close text-reset"
data-bs-dismiss="offcanvas"
aria-label="Close"
></button>
</div>
<div class="offcanvas-body">
BODY
</div>
</div>
I'm trying to toggle between plus and minus icon for bootstrap accordion. On default, plus icon is showing. When accordion collapses, it shows the minus icons and hides the plus icon. I don't know if what I'm saying makes sense but it's really basic for some of you. I'm just a beginner.
I've tried doing it with css with :after and content "+" and content "-" but this is not what I want. I need to use font awesome. I've also tried the js way.
<script>
$(document).ready(function(){
// 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");
});
});
</script>
<body>
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Main content -->
<section class="content container-fluid">
<legend><?php echo $header_title; ?></legend>
<br>
<div class="row">
<div class="col-md-12 accordion-container">
<div class="accordion" id="accordionExample">
<div class="card">
<div class="card-header" id="headingTwo">
<h2 class="mb-0" style="margin: 10px !important">
<button id="btnCollapse" class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
<i class="fa fa-plus"></i>
Card Info
</button>
</h2>
</div>
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordionExample">
<div class="card-body">
<!-- SOME CONTENT -->
</div>
</div>
</div>
</div>
</div>
</div>
</section>
I don't know how to check where I went wrong. All I want is to show the plus and minus icon
$(document).ready(function() {
// 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");
});
});
/*$("#btnCollapse").on("click", function() {
$(".fa-plus").toggleClass("fa-minus");
})
*/
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<body>
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Main content -->
<section class="content container-fluid">
<legend>
<?php echo $header_title; ?>
</legend>
<br>
<div class="row">
<div class="col-md-12 accordion-container">
<div class="accordion" id="accordionExample">
<div class="card">
<div class="card-header" id="headingTwo">
<h2 class="mb-0" style="margin: 10px !important">
<button id="btnCollapse" class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
Card Info
<i class="fa fa-plus"></i>
</button>
</h2>
</div>
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordionExample">
<div class="card-body">
<!-- SOME CONTENT -->
</div>
</div>
</div>
</div>
</div>
</div>
</section>
You can use alternate solution as follow:
$(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");
});
});
Alex, your code is working fine. Please check this fiddle.
[https://jsfiddle.net/boilerplate/bootstrap][1]
Please make sure your js code must be written after the jquery.js and bootstrap.js loaded.
I have a php page. I try to open a modal with the buttons in a list (created by loop). In this list there are many items with different parameters and several buttons for each section of the list. With the button "Fahrzeuganwendungen", My following code opens a modal covering entire page, it is transparent, no header / footer / ... sections. It contains the data only:
<?php
...
?>
<div class='results'>
<input type="hidden" class="test1" name="metin2" value="<?php echo $parcano;?>" />
<input type="hidden" class="brand" name="brandname" value="<?php echo $marka;?>" />
<input type="hidden" class="artnr" name="skunr" value="<?php echo $parcano;?>" />
<button class="btn_mrt"><i class="fa fa-search" style="color:lightseagreen;"></i> weitere suche für <?php echo $parcano;?></button>
<button class="btn_additionalnumbers"><i class="far fa-list-alt" style="color:lightseagreen;"></i> zusätzliche Nummern</button>
<button class="btn_vehicles"><i class="fas fa-car" style="color:lightseagreen;"></i> Fahrzeuganwendungen</button>
<div class="additionalnumbers" name="additionalnumbers" style="background-color: #aaa; border: 0px solid green; padding: 2px; margin: 10px;"></div>
<div class="container">
<h2>Activate Modal with JavaScript</h2>
<!-- Trigger the modal with a button: <button type="button" class="btn_vehicles" id="myBtn">Open Modal</button> -->
<!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body"></div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
<?php
...
?>
<script>
$(function() { // when page loads
$(".btn_mrt").on("click", function() { // click any class="single_add_to_cart_button button alt"
var metin2 = $(this).closest('.results').find('input[name="metin2"]').val();
$('input[name=metin]').val(metin2);
$.post('/wp-content/plugins/ajax-test/SearchByNumberNew.php', {yazi2: metin2}, function (gelen_cevap) {
$('.cevap').html(gelen_cevap);
});
});
});
$(function() { // when page loads
$(".btn_additionalnumbers").on("click", function() { // click any class="single_add_to_cart_button button alt"
var brandname = $(this).closest('.results').find('input[name="brandname"]').val();
var skunr = $(this).closest('.results').find('input[name="skunr"]').val();
var numberdiv = "additionalnumbers" + brandname + skunr;
var $nd = $(this).closest('.results').find('div.additionalnumbers');
$.post('/wp-content/plugins/ajax-test/GetAdditionalNumbers.php', {brand: brandname, sku: skunr}, function (gelen_cevap2) {
$nd.html(gelen_cevap2);
});
});
});
//$(document).ready(function(){
$(function() { // when page loads
$(".btn_vehicles").on("click", function() {
var brandname = $(this).closest('.results').find('input[name="brandname"]').val();
var skunr = $(this).closest('.results').find('input[name="skunr"]').val();
$.post('/wp-content/plugins/ajax-test/GetArticleVehicles.php', {brand: brandname, sku: skunr}, function (gelen_cevap2) {
$("#myModal").modal().html(gelen_cevap2);
});
});
});
</script>
I have the following code in the <head>...</head> of course:
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
What is wrong here? I would appeciate for your kind help.
Many thanks,
Murat
The problem is here
$("#myModal").modal().html(gelen_cevap2);
You're replacing the content of the entire modal. Try something like this
$("#myModal .modal-body").html('<h1>test</h1>');
$("#myModal").modal();
I want to use JQuery noConflict() in my load page.
This is my javascript to load the page:
<script src="plugins/jQuery/jQuery-2.1.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function($) {
// initial page load
$('#area').load('pages/home/home.php');
$("ul.sidebar-menu li a.Dashboard").addClass("hidups");
$('ul.sidebar-menu li a').click(function() {
var page = $(this).attr('href');
document.title = "Admin | " + page;
$("ul.sidebar-menu li a").removeClass("hidups");
$(this).addClass("hidups");
$('#area').load('pages/' + page + '/' + page + '.php', '', function(response, status, xhr) {
if (status == 'error') {
$("#area").load('pages/error/404.php');
}
});
return false;
});
});
</script>
and this is script on my page after load (product.php) :
<link rel="stylesheet" href="build/css/alertify.core.css" />
<link rel="stylesheet" href="build/css/alertify.default.css" id="toggleCSS" />
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="dist/css/AdminLTE.min.css">
<style type="text/css">
.modal-body2 {
height: 300px;
overflow-y: scroll;
padding: 15px;
position: relative;
}
.centerd {
bottom: 0;
left: 0;
margin: auto;
position: static;
right: 0;
top: 0;
width: 50%;
}
</style>
<script src="plugins/jQuery/jquery-1.8.3.min.js"></script>
<script src="build/js/alertify.min.js"></script>
<script type="text/javascript" src="plugins/tinymce/tinymce.min.js"</script>
<script type="text/javascript" src="pages/produk/aplikasi.js"></script>
<?php
// memanggil berkas koneksi.php
require '../../config/koneksi.php';
?>
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
Jammin
<small>Data</small>
</h1>
<ol class="breadcrumb">
<li><i class="fa fa-dashboard"></i> Home</li>
<li>Tables</li>
<li class="active">Data Produk</li>
</ol>
</section>
<!-- tempat untuk menampilkan data mahasiswa -->
<section class="content">
<div class="row">
<div class="col-xs-12">
<div class="box">
<div class="box-header">
<h3 class="box-title">Data Produk</h3>
<a href="#myModal" id="0" class="tambah btn btn-default" data-toggle="modal" style="color:black">
Tambah Data </a>
<button type="button" class="btn btn-danger" id="delete-all">
<i class="icon-plus"></i> Hapus Semua Data
</button>
</div>
<div class="box-body">
<div id="data-produk"> </div>
</div>
</div>
</div>
</div>
</section>
</div>
<!-- awal untuk modal dialog -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">Tambah Data Produk</h3>
</div>
<div class="modal-body2">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Batal</button>
<button id="simpan-produk" class="btn btn-success" data-dismiss="modal" aria-hidden="true" >Simpan Data</button>
</div>
</div>
</div>
</div>
But this won't work because JQuery.min has "crashed". I think I should use jquery.noConflict to fix it but I don't know how to use jquery.noConflict to my load page.
There's a few ways of approaching this, my favourite is a closure.
;(function($){
//$ is now safe here eg. $.('.selector');
})(jQuery);
Or
Just use $.noConflict before using the other libraries that require the dollar sign such as prototype
OR
Just use jQuery instead of $ everywhere, this will make your code less portable and less pretty :)
Use this for jQuerynoConflict
<script type="text/javascript">
JQuery(document).ready(function($) {
// initial page load
JQuery('#area').load('pages/home/home.php');
JQuery("ul.sidebar-menu li a.Dashboard").addClass("hidups");
JQuery('ul.sidebar-menu li a').click(function(){
var page = JQuery(this).attr('href');
document.title="Admin | "+page;
JQuery("ul.sidebar-menu li a").removeClass("hidups");
JQuery(this).addClass("hidups");
JQuery('#area').load('pages/'+page+'/'+ page +'.php' , '', function(response, status, xhr) {
if (status == 'error') {
JQuery("#area").load('pages/error/404.php');
}
});
return false;
});
});
</script>