Two tab menus on one page conflicting with eachother - javascript

I feel like the solution to this must be obvious but I just cannot figure it out...
I have some very simple vanilla javascript with two tab menus. The issue is that I cannot figure out how to control the two menus independently of each other without creating conflicts. The end goal is to have the two menus initialized and controlled separately from each other.
The codepen is here: https://codepen.io/trevor3999/pen/gOPPoYB
In that codepen, I am selecting elements using shared classes, which clearly is an issue. So I've initialized separates IDs for each tab group, but I just can't figure out how to utilize them...
Any help would be much appreciated – thank you!
HTML
<section class="section">
<div class="container">
<div class="columns">
<div class="column">
<h2 class="title is-2 has-text-centered is-rift has-margin-top">Featured <span
class="has-text-primary">Sensors</span>
</h2>
</div>
</div>
<div class="columns">
<div class="column is-offset-1">
<div class="tabs is-medium is-uppercase" id="sensor-tabs">
<ul>
<li class="is-active" data-tab="1">
<a>
<span>EO/IR</span>
</a>
</li>
<li data-tab="2">
<a>
<span>Radar</span>
</a>
</li>
<li data-tab="3">
<a>
<span>Other Sensors</span>
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="columns is-centered">
<div class="column is-10">
<div id="sensor-tab-content" class="tab-content">
<menu class="is-active" data-content="1">
<div class="columns is-multiline">
EO/IR
</div>
</menu>
<menu data-content="2">
<div class="columns is-multiline">
Radar
</div>
</menu>
<menu data-content="3">
<div class="columns is-multiline">
Other
</div>
</menu>
</div>
</div>
</div>
</div>
</section>
<div class="container">
<div class="columns">
<div class="column">
<hr>
</div>
</div>
</div>
<section class="section">
<div class="container">
<div class="columns">
<div class="column">
<h2 class="title is-2 has-text-centered is-rift has-margin-top">Featured <span
class="has-text-primary">Platforms</span>
</h2>
</div>
</div>
<div class="columns">
<div class="column is-offset-1">
<div class="tabs is-medium is-uppercase" id="platform-tabs">
<ul>
<li class="is-active" data-tab="uas">
<a>
<span>UAS/RPAS</span>
</a>
</li>
<li data-tab="fixed">
<a>
<span>Fixed Wing</span>
</a>
</li>
<li data-tab="rotary">
<a>
<span>Rotary Wing</span>
</a>
</li>
<li data-tab="land">
<a>
<span>Land</span>
</a>
</li>
<li data-tab="naval">
<a>
<span>Naval</span>
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="columns is-centered">
<div class="column is-10">
<div id="platform-tab-content" class="tab-content">
<menu class="is-active" data-content="uas">
<div class="columns is-multiline">
UAS
</div>
</menu>
<menu data-content="fixed">
<div class="columns is-multiline">
Fixed Wing
</div>
</menu>
<menu data-content="rotary">
<div class="columns is-multiline">
Rotary Wing
</div>
</menu>
<menu data-content="land">
<div class="columns is-multiline">
Land
</div>
</menu>
<menu data-content="naval">
<div class="columns is-multiline">
Naval
</div>
</menu>
</div>
</div>
</div>
</div>
</section>
CSS
.tab-content menu {
display: none;
}
.tab-content menu.is-active {
display: block;
}
Javascript
const TABS = [...document.querySelectorAll('.tabs li')];
const CONTENT = [...document.querySelectorAll('.tab-content menu')];
const ACTIVE_CLASS = 'is-active';
function initTabs() {
TABS.forEach((tab) => {
tab.addEventListener('click', (e) => {
let selected = tab.getAttribute('data-tab');
updateActiveTab(tab);
updateActiveContent(selected);
})
})
}
function updateActiveTab(selected) {
TABS.forEach((tab) => {
if (tab && tab.classList.contains(ACTIVE_CLASS)) {
tab.classList.remove(ACTIVE_CLASS);
}
});
selected.classList.add(ACTIVE_CLASS);
}
function updateActiveContent(selected) {
CONTENT.forEach((item) => {
if (item && item.classList.contains(ACTIVE_CLASS)) {
item.classList.remove(ACTIVE_CLASS);
}
let data = item.getAttribute('data-content');
if (data === selected) {
item.classList.add(ACTIVE_CLASS);
}
});
}
initTabs();

Here's a lazy solution with only a few changes:
https://codepen.io/watofundefined/pen/KKVVROW
console.log("I don't know what kind of code snippet to put here to make the validation happy, sorry!")

Related

Creating a new href attribute using getAttribute & innerText with Javascript

I've got a list of products and what i want to do is to make the price of the product clickable just like the product title linking to the same product URL.
I've created a for loop to try and do this, but the issue i have is each href link for each product is being created per product where i only need the one price with the corresponding href link. How do i correct this?
Note: I don't have access to change the original html which is why i'm trying to make these changes in javascript
var getAllLinks = document.querySelectorAll('.productTitle').forEach(function(el){
var createNewLinks = document.querySelectorAll('.productPrice').forEach(function (elem){
elem.insertAdjacentHTML("afterend", ""+ elem.innerText +"");
})
});
.container {padding-bottom: 20px;}
<article class="container" data-ga-product="04245">
<div class="productContent">
<a class="productTitle" href="#product1">Product 1</a>
<div class="productPriceContainer">
<div class="productPrimary">
<span class="productPrice">€ 5,90</span>
</div>
</div>
</div>
</article>
<article class="container" data-ga-product="05395">
<div class="productContent">
<a class="productTitle" href="#product2">Product 2</a>
<div class="productPriceContainer">
<div class="productPrimary">
<span class="productPrice">€ 145,90</span>
</div>
</div>
</div>
</article>
<article class="container" data-ga-product="263743">
<div class="productContent">
<a class="productTitle" href="#product3">Product 3</a>
<div class="productPriceContainer">
<div class="productPrimary">
<span class="productPrice">€ 35,90</span>
</div>
</div>
</div>
</article>
<article class="container" data-ga-product="60493">
<div class="productContent">
<a class="productTitle" href="#product4">Product 4</a>
<div class="productPriceContainer">
<div class="productPrimary">
<span class="productPrice">€ 125,90</span>
</div>
</div>
</div>
</article>
I'm not quite sure about your problem but I think maybe this is what you want.
Please let me know if I got it wrong :)
var getLink = document.querySelectorAll('.productTitle');
var newLink = document.querySelectorAll('.productPrice');
getLink.forEach((link, i) => {
newLink[i].insertAdjacentHTML("afterend", "" + newLink[i].innerText + "");
newLink[i].remove();
});
.container {padding-bottom: 20px;}
<article class="container" data-ga-product="04245">
<div class="productContent">
<a class="productTitle" href="#product1">Product 1</a>
<div class="productPriceContainer">
<div class="productPrimary">
<span class="productPrice">€ 5,90</span>
</div>
</div>
</div>
</article>
<article class="container" data-ga-product="05395">
<div class="productContent">
<a class="productTitle" href="#product2">Product 2</a>
<div class="productPriceContainer">
<div class="productPrimary">
<span class="productPrice">€ 145,90</span>
</div>
</div>
</div>
</article>
<article class="container" data-ga-product="263743">
<div class="productContent">
<a class="productTitle" href="#product3">Product 3</a>
<div class="productPriceContainer">
<div class="productPrimary">
<span class="productPrice">€ 35,90</span>
</div>
</div>
</div>
</article>
<article class="container" data-ga-product="60493">
<div class="productContent">
<a class="productTitle" href="#product4">Product 4</a>
<div class="productPriceContainer">
<div class="productPrimary">
<span class="productPrice">€ 125,90</span>
</div>
</div>
</div>
</article>
Why don't you just include the price within the a tag and forget about JavaScript all together?
<article class="container" data-ga-product="04245">
<div class="productContent">
<a class="productTitle" href="#product1">Product 1
<span class="productPriceContainer">
<span class="productPrimary">
<span class="productPrice">€ 5,90</span>
</span>
</span>
</a>
</div>
</article>
You'd need to change the inner divs to spans to be semantic HTML, and potentially some CSS changes to get the styling just right, but this seems like a way better solution.

Add created element after closest third div within the row

I have six blocks, each block has a click function to trigger the contentBlock() snippet.
I'm trying to get the contentBlock() to create the element and display the created div after the closest third item (After the third within the row), currently, the below creates the div and displays after every third item on both rows.
How do I get the created element to sit after the closest third item? E.G The first three triggers would display content under the first row and the next three under the next row.
Any and all suggestions would be appreciated.
function contentBlock() {
const items = document.querySelectorAll('.js-item');
items.forEach(function (item, index) {
if((index + 1) % 3 === 0) {
/* Create Element */
const elem = document.createElement('div');
elem.classList.add('js-content-block', 'col-12');
elem.innerText = 'Content Block';
item.parentNode.insertBefore(elem, item.nextSibling);
}
})
}
<div class="row">
<div class="col-12 col-lg-4 js-item">
<div class="card">
<div class="card__thumbnail">
<img src="#" alt="#">
</div>
<div class="card__title">
<h3>Name</h3>
</div>
<div class="card__body">
<p>role</p>
</div>
<div class="card__actions">
<div>
<ul>
<li>
Number
</li>
<li>
Email
</li>
</ul>
</div>
<div>
<button class="js-toggle" data-count="0" aria-label="#">+</button>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-4 js-item">
<div class="card">
<div class="card__thumbnail">
<img src="#" alt="#">
</div>
<div class="card__title">
<h3>Name</h3>
</div>
<div class="card__body">
<p>role</p>
</div>
<div class="card__actions">
<div>
<ul>
<li>
Number
</li>
<li>
Email
</li>
</ul>
</div>
<div>
<button class="js-toggle" data-count="1" aria-label="#">+</button>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-4 js-item">
<div class="card">
<div class="card__thumbnail">
<img src="#" alt="#">
</div>
<div class="card__title">
<h3>Name</h3>
</div>
<div class="card__body">
<p>role</p>
</div>
<div class="card__actions">
<div>
<ul>
<li>
Number
</li>
<li>
Email
</li>
</ul>
</div>
<div>
<button class="js-toggle" data-count="2" aria-label="#">+</button>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-4 js-item">
<div class="card">
<div class="card__thumbnail">
<img src="#" alt="#">
</div>
<div class="card__title">
<h3>Name</h3>
</div>
<div class="card__body">
<p>role</p>
</div>
<div class="card__actions">
<div>
<ul>
<li>
Number
</li>
<li>
Email
</li>
</ul>
</div>
<div>
<button class="js-toggle" data-count="3" aria-label="#">+</button>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-4 js-item">
<div class="card">
<div class="card__thumbnail">
<img src="#" alt="#">
</div>
<div class="card__title">
<h3>Name</h3>
</div>
<div class="card__body">
<p>role</p>
</div>
<div class="card__actions">
<div>
<ul>
<li>
Number
</li>
<li>
Email
</li>
</ul>
</div>
<div>
<button class="js-toggle" data-count="4" aria-label="#">+</button>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-4 js-item">
<div class="card">
<div class="card__thumbnail">
<img src="#" alt="#">
</div>
<div class="card__title">
<h3>Name</h3>
</div>
<div class="card__body">
<p>role</p>
</div>
<div class="card__actions">
<div>
<ul>
<li>
Number
</li>
<li>
Email
</li>
</ul>
</div>
<div>
<button class="js-toggle" data-count="5" aria-label="#">+</button>
</div>
</div>
</div>
</div>
</div>

Can I hide the text and button of my mean-menu jquery?

So basically I'm using a template for my site and adjusting accordingly. The site defines the menu-bar to be hidden on start and it appears on scroll down.
The text and menu button however, always appear on start. I cant understand how I can also tell the text (email and phonenumber) to stay hidden with the rest of the menu-bar.
<header id="sticky-header" class="header-fixed">
<div class="header-area">
<div class="container sm-120">
<div class="row">
<div class="col-md-9 col-sm-10" style="height: 70px; width: 930px">
<div class="col-md-4 col-sm-6">
<div class="logo text-upper">
<h6>xxxx / xxx 004 x8 / info#testsite.de</h6>
</div>
</div>
<div class="menu-area hidden-xs">
<div class="hamburger hamburger--collapse">
<div class="hamburger-box">
<div class="hamburger-inner"></div>
</div>
</div>
<nav class="hamburger-menu">
<ul class="basic-menu clearfix">
<li>Home</li>
<li>About</li>
<li>Portfolio</li>
<li>Kontakt</li>
<li>Impressum</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
</div>
</header>
/* menu last class added */
$('ul.basic-menu>li').slice(-2).addClass('menu-p-right');
/* TOP Menu Stick */
win.on('scroll',function() {
if ($(this).scrollTop() > 1){
$('#sticky-header').addClass("sticky");
}
else{
$('#sticky-header').removeClass("sticky");
}
});
/* meanmenu */
$('#mobile-nav').meanmenu({
meanMenuContainer: '.basic-mobile-menu',
meanScreenWidth: "767"
});
/* hamburgers menu option */
$('.hamburger').on('click', function() {
$(this).toggleClass('is-active');
$(this).next().toggleClass('nav-menu-show');
});
$(document).on('scroll',function(){
$(".hamburger-menu").slideDown(); //i have used slide down function for animation, you can change class or add css display type changing properties
})
.makescroll{height:1000px;}
.hamburger-menu{display:none}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header id="sticky-header" class="header-fixed">
<div class="header-area">
<div class="container sm-120">
<div class="row">
<div class="col-md-9 col-sm-10" style="height: 70px; width: 930px">
<div class="col-md-4 col-sm-6">
<div class="logo text-upper">
<h6>xxxx / xxx 004 x8 / info#testsite.de</h6>
</div>
</div>
<div class="menu-area hidden-xs">
<div class="hamburger hamburger--collapse">
<div class="hamburger-box">
<div class="hamburger-inner"></div>
</div>
</div>
<nav class="hamburger-menu">
<ul class="basic-menu clearfix">
<li>Home</li>
<li>About</li>
<li>Portfolio</li>
<li>Kontakt</li>
<li>Impressum</li>
</ul>
</nav>
<div class="makescroll">Extended scroll</div>
</div>
</div>
</div>
</div>
</div>
</header>

Prevent Expand/Collapse from nested Links

I have a web page that uses Bootstrap. In this page, I am using the Collapse component to toggle visibility of some elements. In each collapse component, I have some links and buttons. If a user clicks one of these links or buttons, I do NOT want the related content to expand collapse.
I have a Fiddle here, which contains the following:
<div class="container">
<div class="row" data-toggle="collapse" data-target="#parent1">
<div class="col-xs-8">
<h2>Parent 1</h2>
</div>
<div class="col-xs-4">
<ul class="list-inline">
<li>details</li>
<li><button onclick="return onRunClick()">Run</button></li>
</ul>
</div>
</div>
<div class="row" id="parent1" class="collapse">
<div class="col-xs-12">
<h3><small>Children</small></h3>
</div>
</div>
<div class="row" data-toggle="collapse" data-target="#parent2">
<div class="col-xs-8">
<h2>Parent 2</h2>
</div>
<div class="col-xs-4">
<ul class="list-inline">
<li>details</li>
<li><button onclick="return onRunClick()">Run</button></li>
</ul>
</div>
</div>
<div class="row" id="parent2" class="collapse">
<div class="col-xs-12">
<h3><small>Children</small></h3>
</div>
</div>
<div class="row" data-toggle="collapse" data-target="#parent3">
<div class="col-xs-8">
<h2>Parent 3</h2>
</div>
<div class="col-xs-4">
<ul class="list-inline">
<li>details</li>
<li><button onclick="return onRunClick()">Run</button></li>
</ul>
</div>
</div>
<div class="row" id="parent3" class="collapse">
<div class="col-xs-12">
<h3><small>Children</small></h3>
</div>
</div>
</div>
Somehow the event seems to be going up the chain even though I'm returning false in the event handlers. I'm not sure how to remedy this. Any help is appreciated it.
You just need to move "collapsing attributs" to the h2 rather than the div container that include you links, like that:
<div class="container">
<div class="row">
<div class="col-xs-8">
<h2 data-toggle="collapse" data-target="#parent1">Parent 1</h2>
</div>
<div class="col-xs-8">
<ul class="list-inline">
<li>details</li>
<li><button onclick="return onRunClick()">Run</button></li>
</ul>
</div>
</div>
</div>
You must remove the toggle attributes of each row and start the effect manually with JavaScript, then prevent the <button> and <a> elements from taking any action.
All your code would look like this
HTML
<div class="container">
<div class="row row1">
<div class="col-xs-8">
<h2>Parent 1</h2>
</div>
<div class="col-xs-4">
<ul class="list-inline">
<li>details</li>
<li><button>Run</button></li>
</ul>
</div>
</div>
<div class="row" id="parent1">
<div class="col-xs-12">
<h3><small>Children</small></h3>
</div>
</div>
<div class="row row2">
<div class="col-xs-8">
<h2>Parent 2</h2>
</div>
<div class="col-xs-4">
<ul class="list-inline">
<li>details</li>
<li><button>Run</button></li>
</ul>
</div>
</div>
<div class="row" id="parent2">
<div class="col-xs-12">
<h3><small>Children</small></h3>
</div>
</div>
<div class="row row3">
<div class="col-xs-8">
<h2>Parent 3</h2>
</div>
<div class="col-xs-4">
<ul class="list-inline">
<li>details</li>
<li><button>Run</button></li>
</ul>
</div>
</div>
<div class="row" id="parent3">
<div class="col-xs-12">
<h3><small>Children</small></h3>
</div>
</div>
JavaScript
$(document).ready(function(e) {
//on click in row1 class init toggle effect
$(".row1").on("click", function(){
//collapse content
$("#parent1").collapse('toggle');
});
$("div.row2").click(function(){
$("#parent2").collapse('toggle');
});
$("div.row3").click(function(){
$("#parent3").collapse('toggle');
});
//on click in button or a return false
$("button, a").on("click", function(){
return false;
});
});

Add a class in an anchor tag within a div with jquery

does anyone know how Can I add a class in the A tag:
Subscribe
Here is my html:
<div class="module" id="prod-subscription">
<div class="entity entity-bean bean-ap-bl-instruct contextual-links-region block container">
<div class="contextual-links-wrapper contextual-links-processed">
<a class="contextual-links-trigger" href="#">Configure</a>
<ul class="contextual-links">
<li class="bean- first last">
bloc
</li>
</ul>
</div>
<div class="row">
<div class="col-md-3">
<h2>simple<span>in 3 </span></h2>
</div>
<div class="col-md-6">
<ol>
<li>
<span>1</span><p>text</p>
</li>
<li>
<span>2</span><p>texte testx</p>
</li>
<li>
<span>3</span><p>and text</p>
</li>
</ol>
</div>
<div class="col-md-3">
Subscribe
</div>
</div>
</div>
</div>
you can use
$('a[href="/souscription/digital-vie"]').addClass('classHere');
or
$('div#prod-subscription a[href="/souscription/digital-vie"]').addClass('classHere');
or
$('a[href="/souscription/digital-vie"]:contains("Subscribe")').addClass('classHere');
$('a[href="/souscription/digital-vie"]:contains("Subscribe")').addClass('classHere');
.classHere{
background : red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="module" id="prod-subscription">
<div class="entity entity-bean bean-ap-bl-instruct contextual-links-region block container">
<div class="contextual-links-wrapper contextual-links-processed">
<a class="contextual-links-trigger" href="#">Configure</a>
<ul class="contextual-links">
<li class="bean- first last">
bloc
</li>
</ul>
</div>
<div class="row">
<div class="col-md-3">
<h2>simple<span>in 3 </span></h2>
</div>
<div class="col-md-6">
<ol>
<li>
<span>1</span><p>text</p>
</li>
<li>
<span>2</span><p>texte testx</p>
</li>
<li>
<span>3</span><p>and text</p>
</li>
</ol>
</div>
<div class="col-md-3">
Subscribe
</div>
</div>
</div>
</div>
You could use jQuery's filter function and filter the link where the exact text is 'Subscribe' (this may cause problems if you have multiple links with that exact text)
$('a').filter(function() {
return $(this).text() === 'Subscribe';
}).addClass('new-class');
.new-class {color:red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Subscribe
Not sure I fully understand the question. Do you just want to give the anchor tag a class? That can be done as simply as <a class="your_class" href="your_link">Subscribe</a>

Categories

Resources