Using jquery in make a dropdown - javascript

I have this program which make a dropdown-content appear after clicking the ... button and disappear after clicking it again
So, I want the dropdown-content to disappear after clicking anywhere in the body
I tried a lot of ways but with every one of them the button stop working
The Code :-
JavaScript :
$(document).ready( function() {
$(".commentdropdown .dropbtn").on("click", function(e){
$(this).next('.dropdown-content').toggleClass("apear");
});
});
CSS :
.commentdropdown{
float: right;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
}
.apear{
display: block;
}
HTML :
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="commentdropdown pr-3">
<button class="dropbtn btn p-0 m-0 bg-white">btn 1</button>
<div class="dropdown-content">
Edit 1
Delete 1
</div>
<button class="dropbtn btn p-0 m-0 bg-white">btn 2</button>
<div class="dropdown-content">
Edit 2
Delete 2
</div>
<button class="dropbtn btn p-0 m-0 bg-white">btn 3</button>
<div class="dropdown-content">
Edit 3
Delete 3
</div>
</div>

Heres a quick example. You dont really need the trigger to be a button as its not submitting anything. If you wrap each element in a parent container, its easier to target child elements.
$(function(){
var dropdown = $('.dropdown');
var toggle = dropdown.find('.dropdown__trigger');
toggle.click(function(event){
event.preventDefault();
$(this).siblings().slideToggle();
});
});
.dropdown__content{
display:none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="dropdown">
<div class="dropdown__trigger p-0 m-0 bg-white">btn 1</div>
<div class="dropdown__content">
Edit 1
Delete 1
</div>
</div>
<div class="dropdown">
<div class="dropdown__trigger p-0 m-0 bg-white">btn 2</div>
<div class="dropdown__content">
Edit 1
Delete 1
</div>
</div>
<div class="dropdown">
<div class="dropdown__trigger p-0 m-0 bg-white">btn 3</div>
<div class="dropdown__content">
Edit 1
Delete 1
</div>
</div>

Related

Maximum call stack size exceeded when click on the card to trigger button inside div

I have a card detail order, I want the whole card to be clickable and it will trigger a button inside the card to bring up the modal details. I've made the code as below but there is a Maximum call stack size exceeded error and also my console.log('clicked') is triggered hundred times.
how to handle this? please help me
$(document).ready(function(){
$(".order-list-detail-container").each(function() {
$(this).on("click", function() {
console.log('clicked')
$(this).find('.order-detail-trigger').click()
})
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="order-list-detail-container" style="margin-bottom:30px;">
<button class="hidden order-detail-trigger" hx-get="/order-detail" hx-trigger="click" hx-target="#orderDetailModal">Detail Trigger</button>
<!-- Date -->
<div class="date-container">
<span style="display: inline-block; width: 33%" class="date">9 Nov 2021</span>
<div style="width: 33%;"></div>
<div style="width: 33%;"></div>
</div>
<!-- SO Number, Status, Price -->
<div class="order-info-container" style="display:flex; border-bottom: 1px solid gainsboro; margin-bottom: 5px;">
<div class="order-info with-margin-right" style="width: 33%">
<div class="label">Shipping Order Number</div>
<div class="value no-order-value" style="color: #cb4645;">T123456</div>
</div>
<div class="order-info" style="width: 33%">
<div class="label">Status</div>
<div class="value" style="color: #cb4645;">
In Process
</div>
</div>
<div class="order-info-grand-total" style="width: 33%; text-align: right;">
<div class="label">Total</div>
<div class="value">$1200</div>
</div>
</div>
<div class="products-list">
<div class="product-container">
<div class="product-inner-container">
<div class="product-info-container">
<div class="product-name">Grinder 6", RBG6</div>
<div class="product-catalog-code">RBG6</div>
<div class="product-detail-info">
<div class="product-metadata">
<span class="product-qty">3 Product</span>
<div class="product-weight">(8 kg)</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="order-list-detail-container">
<button class="hidden order-detail-trigger" hx-get="/order-detail" hx-trigger="click" hx-target="#orderDetailModal">Detail Trigger</button>
<!-- Date -->
<div class="date-container">
<span style="display: inline-block; width: 33%" class="date">9 Nov 2021</span>
<div style="width: 33%;"></div>
<div style="width: 33%;"></div>
</div>
<!-- SO Number, Status, Price -->
<div class="order-info-container" style="display:flex; border-bottom: 1px solid gainsboro; margin-bottom: 5px;">
<div class="order-info with-margin-right" style="width: 33%">
<div class="label">Shipping Order Number</div>
<div class="value no-order-value" style="color: #cb4645;">T127890</div>
</div>
<div class="order-info" style="width: 33%">
<div class="label">Status</div>
<div class="value" style="color: #cb4645;">
In Process
</div>
</div>
<div class="order-info-grand-total" style="width: 33%; text-align: right;">
<div class="label">Total</div>
<div class="value">$1800</div>
</div>
</div>
<div class="products-list">
<div class="product-container">
<div class="product-inner-container">
<div class="product-info-container">
<div class="product-name">Grinder 8", RBG8</div>
<div class="product-catalog-code">RBG8</div>
<div class="product-detail-info">
<div class="product-metadata">
<span class="product-qty">2 Product</span>
<div class="product-weight">(3 kg)</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Working example. You only need to make trigger for a button when you click Container. And when you click button - it's default button behavior. In both ways you will now have hx-get working.
$(document).ready(function() {
$('.order-list-detail-container').on('click.div', function() {
$('.order-detail-trigger').trigger('click.button');
console.log('clicked');
});
Update 1: If you want different buttons and cards to do different stuff, add numbered ID's for buttons and DIV's use this code:
$('#order-list-detail-container-1').on('click.div',function(){
$('#order-detail-trigger-1').trigger('click.button' );
console.log('1 button or DIV clicked');
});
$('#order-list-detail-container-2').on('click.div',function(){
$('#order-detail-trigger-2').trigger('click.button' );
console.log('2 button or DIV clicked');
});
// duplicate the code block for amount of buttons with Divs you are going to have
Update 2: Added functionality to create ID dynamically to every button and DIV. So you won't need to add any ID's manually when you will create more cards! Also, every button or div click will be counted as individual click and button 1 click won't trigger button 2 clicks:
$('.order-detail-trigger').each(function(index) {
$(this).attr('id', 'button-' + index);
});
$('.order-list-detail-container').each(function(index) {
$(this).attr('id', 'container-' + index);
});
$( document ).ready(function() {
$('.order-list-detail-container').each(function(index) {
$('#container-' + index).on('click.div',function() {
$('#button-' + index).trigger('click.button');
let test = $('#container-' + index).attr('id');
let test2 = $('#button-' + index).attr('id');
//console.log('clicked');
console.log(test + ' clicked!');
console.log(test2 + ' AUTO clicked!');
});
});
});
Uncomment //console.log('clicked'); to see that clicking DIV or Button - it only happens 1 time:

How to write a "this" - Function

I would like to reduce my Javascript code, maybe with variables or with "this"? It's to much code for a little bit of intention.
$("#Linkitem1").click(function() {
$("#item1").fadeIn(2500);
$("#item2").hide();
$("#item3").hide();
$("#Linkitem3").removeClass("active btn-warning");
$("#Linkitem2").removeClass("active btn-warning");
$("#Linkitem1").addClass("active btn-warning");
});
$("#Linkitem2").click(function() {
$("#item2").fadeIn(2500);
$("#item1").hide();
$("#item3").hide();
$("#Linkitem1").removeClass("active btn-warning");
$("#Linkitem3").removeClass("active btn-warning");
$("#Linkitem2").addClass("active btn-warning");
});
$("#Linkitem3").click(function() {
$("#item3").fadeIn(2500);
$("#item2").hide();
$("#item1").hide();
$("#Linkitem1").removeClass("active btn-warning");
$("#Linkitem2").removeClass("active btn-warning");
$("#Linkitem3").addClass("active btn-warning");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<main role="main">
<div id="card-content" class="container">
<div class="card border-warning text-center">
<div class="card-header">
<ul class="nav nav-pills card-header-pills">
<li class="nav-item">
<a id="Linkitem1" data-toggle="collapse" href="#item1" role="button" aria-expanded="true" aria-controls="collapseOne" title="" class="nav-link text-white btn-warning active">item1</a>
</li>
<li class="nav-item">
<a id="Linkitem2" data-toggle="collapse" href="#item2" role="button" aria-expanded="true" title="" class="nav-link collapsed text-white">item2</a>
</li>
<li class="nav-item">
<a id="Linkitem3" data-toggle="collapse" href="#item3" role="button" aria-expanded="true" title="" class="nav-link collapsed text-white">item3</a>
</li>
</ul>
</div>
<!--Content item1-->
<div id="item1" class="animated fadeIn collapse show card-body" data-parent="#card-content">
<h5 class="card-title">title for item 1</h5>
<p class="card-text">content item 1.</p>
</div>
<!--content item 2-->
<div id="item2" class="animated fadeIn collapse card-body" data-parent="#card-content">
<h5 class="card-title">title item 2</h5>
<p class="card-text">content item 2</p>
<!--content 3-->
<div id="item 3" class="collapse card-body" data-parent="#card-content">
<h5 class="card-title">title item 3</h5>
<p class="card-text">content item 3</p>
</div>
</div>
</main>
This code is working. I am clicking in the navigation of linkitem1 and in the card-body is just content of item 1. if am clicking on linkitem2, I can see the content of item2.
You can use that way if it is possible. add class "Linkitem" with nav-item anchor tag and add class "item" with content item
$(".Linkitem").click(function(){
let dataId = $(".Linkitem").index(this);
$('.item:eq('+dataId+')').fadeIn(500);
$('.item:not(:eq('+dataId+'))').fadeOut(500);
$('.Linkitem:eq('+dataId+')').addClass("active btn-warning");
$('.Linkitem:not(:eq('+dataId+'))').removeClass("active btn-warning");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<main role="main">
<div id="card-content" class="container">
<div class="card border-warning text-center">
<div class="card-header">
<ul class="nav nav-pills card-header-pills">
<li class="nav-item">
<a id="Linkitem1" class="Linkitem" data-toggle="collapse" href="#item1" role="button" aria-expanded="true" aria-controls="collapseOne" title="" class="nav-link text-white btn-warning active">item1</a>
</li>
<li class="nav-item">
<a id="Linkitem2" class="Linkitem" data-toggle="collapse" href="#item2" role="button" aria-expanded="true" title="" class="nav-link collapsed text-white">item2</a>
</li>
<li class="nav-item">
<a id="Linkitem3" class="Linkitem" data-toggle="collapse" href="#item3" role="button" aria-expanded="true" title="" class="nav-link collapsed text-white">item3</a>
</li>
</ul>
</div>
<!--Content item1-->
<div id="item1" class="item animated fadeIn collapse show card-body" data-parent="#card-content">
<h5 class="card-title">title for item 1</h5>
<p class="card-text">content item 1.</p>
</div>
<!--content item 2-->
<div id="item2" class="item animated fadeIn collapse card-body" data-parent="#card-content">
<h5 class="card-title">title item 2</h5>
<p class="card-text">content item 2</p>
</div>
<!--content 3-->
<div id="item3" class="item collapse card-body" data-parent="#card-content">
<h5 class="card-title">title item 3</h5>
<p class="card-text">content item 3</p>
</div>
</div>
</main>
You can apply for loop, but you need to change attribute id on class. Otherwise, you should use additional attributes like a data-.
$(()=>{
$(".item").each(function(){
$(this).hide();
});
for (let i = 0; i < 3; i++){
$(".Linkitem").eq(i).click(function(){
$(".item").each(function(){
$(this).hide();
});
$(".item").eq(i).fadeIn(2500);
$(".Linkitem").each(function(){
$(this).removeClass("active btn-warning");
});
$(this).addClass("active btn-warning");
});
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a class='Linkitem otherclass'>Linkitem11111111</a> <br>
<a class='Linkitem otherclass'>Linkitem22222222</a> <br>
<a class='Linkitem otherclass'>Linkitem33333333</a> <br>
<br><br><br>
<div class='item other'>1 1 1 1 1 1 1</div>
<div class='item other'>2 2 2 2 2 2 2</div>
<div class='item other'>3 3 3 3 3 3 3</div>
Here's a solution that uses event.target instead of this (or $(this)).
JQuery is still used for .fadeIn and .hide, although this could be accomplished without JQuery, too.
A click listener distinguishes between clicks on "link" buttons and all other clicks, and loops through the item divs, hiding them and showing only the "active" one.
// Calls `changeActiveItem` when something is clicked
document.addEventListener("click", changeActiveItem);
// Defines a listener (with automatic access to the triggering event)
function changeActiveItem(event){
const clickedElement = event.target; // `target` property holds the clicked element
// Makes sure the clicked element is a link before proceeding
if(!clickedElement.classList.contains("link")){
return; // Function will stop here if a non-link element was clicked
}
// Gets the item id stored in the link's "data-linked-item-id" attribute
const linkedItemId = clickedElement.dataset["linkedItemId"]; // Magic name conversion
// Deactivates and hides all items
const items = document.getElementsByClassName("item");
for(let item of items){
item.classList.remove("active");
item.classList.remove("btn-warning"); // This class currently has no effect
$(item).hide(); // Hides item
// Activates and animates the selected item
if(item.id === linkedItemId){
$(item).fadeIn(2500);
item.classList.add("active");
item.classList.add("btn-warning");
}
}
}
div{ margin-bottom: 15px; }
.item{ display: none; font-size: 3em; }
.active{ display: block; color: darkred; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="item1Link" class="link" data-linked-item-id="item1">activate item 1</button>
<div>
<div id="item1" class="item active">Item 1</div>
</div>
<button id="item2Link" class="link" data-linked-item-id="item2">activate item 2</button>
<div>
<div id="item2" class="item">Item 2</div>
</div>
<button id="item3Link" class="link" data-linked-item-id="item3">activate item 3</button>
<div>
<div id="item3" class="item">Item 3</div>
</div>

How do I toggle the content of the other bootstrap buttons?

I'm using bootstrap and scss to create a wordpress page but i'm having some issues trying to create a collapsable content. I have four buttons and I want that only the content of one of them is displayed while the others are collapsed. If I click the second button for example the buttons 1, 3 & 4 should display nothing.
Also I have a active class to show in a clear way which one is pressed that it's not working properly. Any help would be really nice, thanks!
var mainStarter = {
initialize: function() {
this.buttonActive();
this.toggleButton();
},
buttonActive: function() {
$(".btn.btn-bg-md").on("click", function() {
$(this).toggleClass('active');
});
},
toggleButton: function() {
$('.column button').click(function() {
$(".collapse:visible").add($(this).next()).slideToggle();
});
},
$(function() {
mainStarter.initialize();
});
.row {
display: flex;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<!-- Item 1 -->
<div class="column">
<button type="button" class="btn btn-bg-md" data-toggle="collapse" data-target="#btn1" aria-pressed="false" autocomplete="off">
<h6>Day 1</h6>
</button>
</div>
<!-- Item 2 -->
<div class="column">
<button type="button" class="btn btn-bg-md" data-toggle="collapse" data-target="#btn2" aria-pressed="false" autocomplete="off">
<h6>Day 2</h6>
</button>
</div>
<!-- Item 3 -->
<div class="column">
<button type="button" class="btn btn-bg-md" data-toggle="collapse" data-target="#btn3" aria-pressed="false" autocomplete="off">
<h6>Day 3</h6>
</button>
</div>
<!-- Item 4 -->
<div class="column">
<button type="button" class="btn btn-bg-md" data-toggle="collapse" data-target="#btn4" aria-pressed="false" autocomplete="off">
<h6>Day 4</h6>
</button>
</div>
<div class="container">
<div class="collapse" id="btn1">
<h1>Something 1</h1>
</div>
</div>
<div class="container">
<div class="collapse" id="btn2">
<h1>Something 2</h1>
</div>
</div>
<div class="container">
<div class="collapse" id="btn3">
<h1>Something 3</h1>
</div>
</div>
<div class="container">
<div class="collapse" id="btn4">
<h1>Something 4</h1>
</div>
</div>
</div>
I am not really sure what you really want (your message is not that clear). What I understood, is that you want 2 buttons. When you click the first one, it shows the 1st message and hide the second. When you click the second, it shows the second message and hides the first one. If i understood correctly, you could use jquery, using the correct ids on the divs
$("#button1").click(function() {
if ($("#collapsebutton2").is(":visible")) {
$("#collapsebutton2").toggle( "slow", function() {
});
}
$("#collapsebutton1").toggle( "slow", function() {
});
});
$("#button2").click(function() {
$("#collapsebutton2").toggle( "slow", function() {
});
if ($("#collapsebutton2").is(":visible")) {
$("#collapsebutton1").toggle( "slow", function() {
});
}
});

whats the best way to control showing and hiding multiple charts and divs in a page

I am new in javascript,i have a page consist of different Card layouts and each card has its own chart or buttons or grids,some of them should be hidden by default and some of them should be hide or visible by click,since the page is growing by more demands ,controlling these hid/e/show is becoming a nightmare,i would like you tell me whats the best way to do this?for example i have a following div which has a chart:
<section style="width:100%;margin-top:2%;" >
<div id="btnCurrentStatID" class="card ShowHide" style="float:right;width:20%;height:350px;display:none;">
<div class="wrapper">
<div class="containerBtns" style="width:100%;float:right" >
<button type="button" id="btnErrorStat" class="btnsForCrew-Common "></button>
<button type="button" id="btnIdle" class="btnsForCrew-Common "></button>
<button type="button" id="btnService" class="btnsForCrew-Common "></button>
<button type="button" id="btnLinkDn" class="btnsForCrew-Common"></button>
<button type="button" id="btnDataIn" class="btnsForCrew-Common" ></button>
<button type="button" id="btnrepOff" class="btnsForCrew-Common"></button>
</div>
</div>
</div>
<div id="faultStatChartID" class="card ShowHide" >
<div id="chart">
</div>
</div>
<div id="pieChartID" class="card ShowHide">
<div id="pieChart"></div>
</div>
</section>
<section style="width:100%;float:left;margin-top:3%;" id="faultStatSubGroupsSec">
<div id="subcatNameChartSectionID" class="card" style="width:49%;float:left;display:none">
<div class="container">
<div id="subcatNameChart"></div>
</div>
</div>
<div id="subcatErrorChartSectionID" class="card" style="width:49%;float:right;display:none">
<div class="container">
<div id="subcatErrorChart"></div>
</div>
</div>
<div id="subCatIdnameSectionID" class="card" style="width:49%;float:left;display:none">
<div class="container">
<div id="subCatIdname"></div>
</div>
</div>
<div id="subCatITurNameSectionID" class="card"style="width:49%;float:right;display:none">
<div class="container">
<div id="subCatITurName"></div>
</div>
</div>
<div></div>
<div></div>
</section>
i gave it showhide class,and by default its hidden,when i click on filter button it will be visible,and other divs should be hidden,it this continues,imagine how many time i should do it and manage to control them all,
$(".ShowHide").css("display", "block");
$("#subcatNameChartSectionID").hide();
$("#subcatErrorChartSectionID").hide();
$("#subCatIdnameSectionID").hide();
$("#subCatITurNameSectionID").hide();
A way would be to use a class for hiding.
.hide {
display: none;
}
And a hideable class for accessing every item that should be able to be hidden. The class hide can be added to hide the element.
<div class="hideable">1 hideable</div>
jQuery offers methods for class manipulation:
$('.hideable').toggleClass('hide');
$('#unique4').removeClass('hide');
$('#unique5').addClass('hide');
Here is the full snippet code:
$('.hideable').toggleClass('hide');
$('#unique4').removeClass('hide');
$('#unique5').addClass('hide');
.hide {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="unique1" class="hideable">
1 hideable
</div>
<div id="unique2" class="hideable">
2 hideable
</div>
<div id="unique3" class="hideable hide">
3 hideable
</div>
<div id="unique4" class="hideable hide">
4 hideable
</div>
<div id="unique5" class="hide">
5 other
</div>

Active all data id and # when Onclick

Problem going wrong is when i Onclick for "c-1" btn in div=mark-container, the same id will be active in the same time,but the another button which also is "c-1" in the div = second-mark , wouldn't active together,how to make" it to be active together?
$('.c-1').click(function() {
var tab = $(this).attr('data-id');
$('.c-1').removeClass('active');
$(".c-1-details").removeClass('active');
$(this).addClass('active');
$("[id='" + tab + "']").addClass('active');
});
.c-1-details {
display: none;
}
.c-1-details.active {
display: block;
}
.active {
color: green;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="mark-container">
<button class="c-1 active" data-id="tab-1">
<p>for 1 btn</p>
</button>
<button class="c-1" data-id="tab-2">
<p>for 2 btn</p>
</button>
<div class="c-1-details active" id="tab-1">
<p>for 1 details</p>
</div>
<div class="c-1-details" id="tab-2">
<p>for 2 details</p>
</div>
</div>
<div class="second-mark">
<ul>
<button class="c-1 active" data-id="tab-1">current btn 1</button>
<button class="c-1" data-id="tab-2">current btn2</button>
</ul>
<div class="c-1-details active" id="tab-1">
display content 1
</div>
<div class="c-1-details" id="tab-2">
display content 2
</div>
</div>
As mentioned in the comments id should be unique to an element. Common elements can always be indicated with same class. The code below is self-explanatory.
$('.c-1').click(function() {
var tab = $(this).attr('data-id');
$('.c-1,.c-1-details').removeClass('active');
$('.' + tab + ', .details-' + tab).addClass('active');
});
.c-1-details {
display: none;
}
.c-1-details.active {
display: block;
}
.active {
color: green;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="mark-container">
<button class="c-1 tab-1 active" data-id="tab-1">
<p>for 1 btn</p>
</button>
<button class="c-1 tab-2" data-id="tab-2">
<p>for 2 btn</p>
</button>
<div class="c-1-details details-tab-1 active" data-id="tab-1">
<p>for 1 details</p>
</div>
<div class="c-1-details details-tab-2" data-id="tab-2">
<p>for 2 details</p>
</div>
</div>
<div class="second-mark">
<ul>
<button class="c-1 tab-1 active" data-id="tab-1">current btn 1</button>
<button class="c-1 tab-2" data-id="tab-2">current btn2</button>
</ul>
<div class="c-1-details details-tab-1 active" data-id="tab-1">
display content 1
</div>
<div class="c-1-details details-tab-2 " data-id="tab-2">
display content 2
</div>
</div>

Categories