Show Hide Subnav - javascript

How can I toggle the subnav for each item, and if one is open, hide the open one to show the current one? If there are none shown, just toggle. If you click one and show subnav then and click another hide previous and show current.
Here is my html -
<header>
<div class="content-wrapper">
<div class="user-menu-wrapper">
<div class="hsn-logo"></div>
<div class="user-greeting-wrapper">
<div class="user-greeting">Hi, Abraham</div>
</div>
<div class="user-menu">
<ul class="user-menu-items">
<li>#Html.ActionLink(" ", "Index", "Home", new { #class = "my-account" })</li>
<li>#Html.ActionLink(" ", "Index", "Home", new { #class = "my-favorites" })</li>
<li>#Html.ActionLink(" ", "Index", "Home", new { #class = "my-bag" })</li>
</ul>
</div>
</div>
<div class="hsn-nav-wrapper">
<div class="hsn-nav">
<ul class="hsn-nav-items">
<li style="width: 25%">
<a class="shop" href="#">
<span class="hsn-nav-item-wrap">
<span>SHOP</span><span class="drop-down-arrow"></span>
</span>
</a>
</li>
<li style="width: 25%">
<a class="watch" href="#">
<span class="hsn-nav-item-wrap">
<span>WATCH</span><span class="drop-down-arrow"></span>
</span>
</a>
</li>
<li style="width: 25%">
<a class="play" href="#">
<span class="hsn-nav-item-wrap">
<span>PLAY</span><span class="drop-down-arrow"></span>
</span>
</a>
</li>
<li style="width: 15%">
<a href=""><span class="hsn-search-icon"></span>
</a>
</li>
</ul>
</div>
<br class="clear" />
</div>
</div>
</header>
<subnav id="shop" class="shop-subnav">
<div class="hsn-subnav-wrapper">
<div class="hsn-subnav">
<div class="hsn-subnav-left">
<ul>
<li>SubnavItem</li>
<li>SubnavItem</li>
<li>SubnavItem</li>
<li>SubnavItem</li>
<li>SubnavItem</li>
<li>SubnavItem</li>
<li>SubnavItem</li>
<li><span class="hsn-subnav-callout">Deals</span></li>
</ul>
</div>
<div class="hsn-subnav-right">
<ul>
<li>SubnavItem</li>
<li>SubnavItem</li>
<li>SubnavItem</li>
<li>SubnavItem</li>
<li>SubnavItem</li>
<li>SubnavItem</li>
<li>SubnavItem</li>
<li><span class="hsn-subnav-callout">Clearance</span></li>
</ul>
</div>
</div>
</div>
</subnav>
<subnav id="watch" class="watch-subnav">
<div class="hsn-subnav-wrapper">
<div class="hsn-subnav">
<div class="hsn-subnav-left">
<ul>
<li>SubnavItem2</li>
<li>SubnavItem2</li>
<li>SubnavItem2</li>
<li>SubnavItem2</li>
</ul>
</div>
<div class="hsn-subnav-right">
<ul>
<li>SubnavItem2</li>
<li>SubnavItem2</li>
<li>SubnavItem2</li>
<li>SubnavItem2</li>
</ul>
</div>
</div>
</div>
</subnav>
Here is my Jquery / JS -
$(document).ready(function () {
$('ul.hsn-nav-items li a').click(function () {
var navitem = $(this).attr('id')
, id = $(this).attr('class')
, subnav = $('subnav.' + id + '-subnav');
$('a.selected').not(this).removeClass('selected');
$(this).toggleClass('selected');
$('#'+id).toggle();
});
});

Just glancing through your html - you have duplicate IDs. Your 'a' that links to 'play' also has an ID of 'play' - that element will be selected, not the subnav!
Also, two of your links are classed watch, none shop.

The simplest way to approach this is to hide all the <subnav> on each click. All your existing code will work just fine which already takes care of toggling the relevant <subnav>.
var $subNavs = $('subnav');
$subNavs.hide();
$('ul.hsn-nav-items li a').click(function () {
$subNavs.hide();
var navitem = $(this).attr('id')
, id = $(this).attr('class')
, subnav = $('subnav.' + id + '-subnav');
$('a.selected').not(this).removeClass('selected');
$(this).toggleClass('selected');
$('#'+id).toggle();
return false;
});
​I also added a return false; to stop the default click event on the <a> being executed, which could result in a page load since href="#".
That said, <subnav> is a non-standard element and you would be better off using a simpler markup to describe the data. It may also prove useful to give the each subnav a common class which makes finding them via jQuery simpler.
I have also made a small demo using the following simplified code
HTML
<a class="shop" href="#">
<span class="hsn-nav-item-wrap">
<span>SHOP</span><span class="drop-down-arrow"></span>
</span>
</a><br/>
<a class="watch" href="#">
<span class="hsn-nav-item-wrap">
<span>WATCH</span><span class="drop-down-arrow"></span>
</span>
</a><br/>
<a class="play" href="#">
<span class="hsn-nav-item-wrap">
<span>PLAY</span><span class="drop-down-arrow"></span>
</span>
</a>
<div id="shop" class="shop subnav">
shop
</div>
<div id="watch" class="watch subnav">
watch
</div>
<div id="play" class="play subnav">
play
</div>
JavaScript
var $subNavs = $('.subnav');
$subNavs.hide();
$('a').click(function () {
var $subNavToToggle = $('#' + ($(this).attr('class').split(' ')[0]));
var doToggle = $subNavToToggle.is(':not(:visible)');
$subNavs.hide();
$('a.selected').not(this).removeClass('selected');
$(this).toggleClass('selected');
$subNavToToggle.toggle(doToggle);
return false;
});

Related

Using Javascript and JQuery to create a filter button

I'm trying to make my button functional on my website but for some reason it isn't working. I have been working on it endlessly and need some outside. If you could help with figuring out what I am doing wrong I would really appreciate it. I am still learning JavaScript and JQuery so all of this is new to me.
HTML Code:
<div id="portfolio">
<div class="container">
<div class="row">
<div class="heading">
<h2>PORTFOLIO</h2>
</div>
<div class="filter">
<ul id="filters">
<li><button class="btn active" data-filter="all">ALL</a></li>
</ul>
</div>
<div class="itemsContainer">
<ul class="items">
<li>
<div class="item" div class="column apps">
<img src="triviastartthumbnail.jpg">
<h4>Movie Trivia App</h4>
<p>This app was created to test users knowledge on how well they know their movies
and actors/actresses</p>
</div>
<ul class="img-list">
<span class="link">
<a href="https://vshorty2003.github.io/movietrivia/"><i class="fa fa-link">
</i></a></span>
<span class="search">
<a href="movietriviaappstart.JPG" figcaption="Movie Trivia App" /><i
class="fa fa-search"></i></a>
</span>
<li class="img-item">
<img class='item-img' src="html5-logo.png" alt="HTML icon" />
</li>
<li class="img-item">
<img class='item-img' src="css-3-logo.png" alt="CSS icon"/>
</li>
<li class="img-item">
<img class='item-img' src="js-icon-26.jpg" alt="JavaScript icon" />
</li>
<li class="img-item">
<img class='item-imgjq' src="jquery-icon-16-revised.png" alt="JQuery icon"/>
</li>
</li>
</ul>
CSS code:
/*for filtered buttons*/
li{
display: inline;
list-style: none;
}
JavaScript code:
$("button").click(function(){
$("button").removeClass("btn active");
$(this).addClass("btn active");
var dataFilter = $(this).data('filter');
if(dataFilter == "all") {
$(".filter ul").show();
}
else
{
$(".filter ul").hide();
$("." + dataFilter).show();
}
});

jQuery get attibutes and values from all elements inside a class

I'm scraping a website where it has the following HTML structure
<div id="list" class="book-list">
<div id="stream_1" class="stream collapsed">
<h3 id="s-1" rel="1"><div><a name="st_1" class="st st_1">Version 1</a></div></h3>
<div class="volume last">
<h4 id="v-1-1">Volume 1<span class="range">Chapter 1</span></h4>
<ul class="chapter">
<li id="b-922893" class="new">
<span>
<a class="ch sts sts_1" target="_blank" href="link/1">vol.1 ch.1</a>
</span>
<i>Yesterday 08:27 am</i>
<em>
1
3
6
10
all
of 44 </em>
</li>
</ul>
</div>
</div>
<div id="stream_5" class="stream">
<h3 id="s-5" rel="5"><div><a name="st_5" class="st st_5">Version 2</a></div></h3>
<div class="volume last">
<h4 id="v-5-">Volume <i>[Null]</i><span class="range">Chapter 1</span></h4>
<ul class="chapter">
<li id="b-922873" class="new">
<span>
<a class="ch sts sts_5" target="_blank" href="links5/c1/1">ch.1</a>
</span>
<i>Yesterday 08:10 am</i>
<em>
1
3
6
10
all
of 44 </em>
</li>
</ul>
</div>
</div>
</div>
I want to use jQuery to get the links from the divs to get something like this
{
"vol.1 ch.1" : "link/1",
"ch.2" : "link/2"
}
As all the items i want has the class ch sts i wanted to get them with the selector, and trying to use each() but didn't work as it shows nodes...
Here's what how i'm trying:
$d('.ch').map(function(){
console.log('This: href',$(this).attr("href"));
}).get();
It is simpler than you thought. Since you've mentioned that you only want to parse links with ch sts classes, I changed the selector.
var map = {};
$(".ch.sts").each(function() {
map[$(this).text()] = $(this).attr("href");
});
console.log(map);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="list" class="book-list">
<div id="stream_1" class="stream collapsed">
<h3 id="s-1" rel="1"><div><a name="st_1" class="st st_1">Version 1</a></div></h3>
<div class="volume last">
<h4 id="v-1-1">Volume 1<span class="range">Chapter 1</span></h4>
<ul class="chapter">
<li id="b-922893" class="new">
<span>
<a class="ch sts sts_1" target="_blank" href="link/1">vol.1 ch.1</a>
</span>
<i>Yesterday 08:27 am</i>
<em>
1
3
6
10
all
of 44 </em>
</li>
</ul>
</div>
</div>
<div id="stream_5" class="stream">
<h3 id="s-5" rel="5"><div><a name="st_5" class="st st_5">Version 2</a></div></h3>
<div class="volume last">
<h4 id="v-5-">Volume <i>[Null]</i><span class="range">Chapter 1</span></h4>
<ul class="chapter">
<li id="b-922873" class="new">
<span>
<a class="ch sts sts_5" target="_blank" href="links5/c1/1">ch.1</a>
</span>
<i>Yesterday 08:10 am</i>
<em>
1
3
6
10
all
of 44 </em>
</li>
</ul>
</div>
</div>
</div>
Get all the Elements with class name.
Get the text value and "href" attribute.
x = document.getElementsByClassName("ch sts");
for(i =0; i<x.length; i++) {
console.log(x[i].text +" "+ x[i].getAttribute("href"));
}

add class on scroll in bootstrap tabing

i need a small help for add a class on scroll in bootstrap tabbing carousal.
so here is my page url
when i click on any point from tabing like 1,2,3.. active class is adding on tabing on same that is perfect i use this is script
$('#myCarousel').bind('mousewheel', function(e){$(this).carousel('next');});
$('.tab li').on('click', function(){
$('li.active').removeClass('active');
$(this).addClass('active');
});
it is working perfect as class is adding on li.active but i also want .active class on current tab when i scroll in tab container. i have added scroll code and working perfect but need class to add in .tab li when i scroll
here is HTML code as well
<div class="tab">
<div class="container-tab">
<ul class="list-inline nav">
<li data-target="#myCarousel" data-slide-to="0" class="active"> <a href="#">
<div class="round-tab-num"> 1 </div>
<p>Working Smart <small>not harder</small> </p>
</a> </li>
<li data-target="#myCarousel" data-slide-to="1"> <a href="#">
<div class="round-tab-num"> 2 </div>
<p>Working Smart <small>not harder</small> </p>
</a> </li>
<li data-target="#myCarousel" data-slide-to="2"> <a href="#">
<div class="round-tab-num"> 3 </div>
<p>Working Smart <small>not harder</small> </p>
</a> </li>
<li data-target="#myCarousel" data-slide-to="3"> <a href="#">
<div class="round-tab-num"> 4 </div>
<p>Working Smart <small>not harder</small></p>
</a> </li>
<li data-target="#myCarousel" data-slide-to="4"> <a href="#">
<div class="round-tab-num"> 5 </div>
<p>Working Smart <small>not harder</small></p>
</a> </li>
</ul>
<!--The main div for carousel-->
<div id="myCarousel" class="carousel horizantal slide" data-interval="false">
<!-- Sliding images statring here -->
<div class="carousel-inner">
<div class="item active">
<div class="carousel-caption">
<h3>test1</h3>
</div>
</div>
<div class="item">
<div class="carousel-caption">
<h3>test2</h3>
</div>
</div>
<div class="item">
<div class="carousel-caption">
<h3>test3</h3>
</div>
</div>
<div class="item">
<div class="carousel-caption">
<h3>test4</h3>
</div>
</div>
<div class="item">
<div class="carousel-caption">
<h3>test5</h3>
</div>
</div>
</div>
<!-- Next / Previous controls here -->
<div> </div>
</div>
</div>
</div>
this code is also added
$(document).ready( function() {
$('#myCarousel').carousel({
interval: 4000
});
var clickEvent = false;
$('#myCarousel').on('click', '.container-tab .nav a', function() {
clickEvent = true;
$('.container-tab .nav li').removeClass('active');
$(this).parent().addClass('active');
}).on('slid.bs.carousel', function(e) {
if(!clickEvent) {
var count = $('.container-tab .nav').children().length -1;
var current = $('.container-tab .nav li.active');
current.removeClass('active').next().addClass('active');
var id = parseInt(current.data('slide-to'));
if(count == id) {
$('.container-tab .nav li').first().addClass('active');
}
}
clickEvent = false;
});
});
change your code as below simply remove class from currently active li and add active class to next li as below
$('#myCarousel').bind('mousewheel', function(e) {
$(this).carousel('next');
var $currentlyactive =$('li.active');
$currentlyactive.removeClass('active');
$currentlyactive.next().addClass('active');
});
Updated
$(document).ready(function() {
$('.carousel').carousel('pause');
});
$('#myCarousel').bind('mousewheel', function(e){$(this).carousel('next');});
$('.tab li').on('click', function(){
$('li.active').removeClass('active');
$(this).addClass('active');
});
this is the code in your html page remove this all carousel related code has been done in custom.js..

siblings() in jQuery is not working

I tried to achieve tabs using jQuery. Making the current tab class active is working, but to make its sibling's class null is not working.
jQuery(document).ready(function() {
jQuery('.container .tab-links a').on('click', function(e) {
var currentAttrValue = jQuery(this).attr('href');
console.log(currentAttrValue);
// jQuery(this).addClass('active').siblings.removeClass('active');
// Show/Hide Tabs
//jQuery(currentAttrValue).show().siblings().hide();
// Change/remove current tab to active
jQuery(this).addClass('active');
jQuery(this).siblings().find('a').removeClass('active');
jQuery('each_tab').not(currentAttrValue).css("display", "none");
jQuery(currentAttrValue).css("display", "block");
e.preventDefault();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section id="features">
<header>
<div class="features-switcher">
<div class="container">
<ul class="tab-links">
<li>
<a class="active" href="#tab1">
<span>tab one</span>
</a>
</li>
<li>
<a class="" href="#tab2">
<span>tab two</span>
</a>
</li>
<li>
<a class="" href="#tab3">
<span>tab three</span>
</a>
</li>
</ul>
</div>
</div>
<hr>
</header>
<div class="tab-content">
<div id="tab1" class="tab--active">
<section class="container">
<h2> content of tab 1</h2>
<hr>
</section>
</div>
<div id="tab2" class="tab--inactive">
<section class="container">
<h2> content of tab 2</h2>
</section>
</div>
<div id="tab3" class="tab--inactive">
<section class="container">
<h2> content of tab 3</h2>
</section>
</div>
</div>
</section>
The <a> elements in questions have no siblings. The containing <li> elements do.
Target those — and their descendant <a> tags — instead, with:
jQuery(this).parent().siblings('li').find('a').removeClass('active');
Your each_tab query can be replaced with:
jQuery('.tab-content > div').not(currentAttrValue).
hide().
addClass('tab--inactive').
removeClass('tab--active');
jQuery(currentAttrValue).
show().
addClass('tab--active').
removeClass('tab--inactive');
You're selecting the <a> tags, then calling jQuery(this).siblings(). But the <a> tags don't have any siblings; it's their parents (the <li> tags) that have siblings. You should be calling jQuery(this).parent().siblings(), instead.

jQuery emptying wrong div? [duplicate]

This question already has answers here:
How to append one jQuery element already in the DOM to another element?
(5 answers)
Closed 3 months ago.
I've been working on a filter plugin using HTML5's data-* attribute, but jQuery (or something) keeps emptying the wrong div.
Basically I have two divs with different classes. '.gallery-source' is the class of the div with ALL of the content (and the 'display' property is set to 'none' value, so it doesn't show up in the document); while '.gallery' on the first hand is empty but then given the contents of '.gallery-source'.
Once the user has selected options to filter in the dropdowns (an unordered list of items, with links that have data-* values matching some of the contents of '.gallery-source' data-* values), the '.gallery' div is emptied and then each matching content (same data-* values as set in the dropdowns) of '.gallery-source' is appended inside '.gallery'.
The code looks something like this:
// Append everything from .gallery-source to .gallery in order to show ALL work (filters may be applied later)
var gallerySource = $('.works-content .gallery-source').html();
$('.works-content .gallery').html(gallerySource);
// Attribute filtering for all work inside .gallery
$('ul#artist-dropdown li a, ul#technique-dropdown li a, ul#material-dropdown li a').on('click', function() {
// Get selected filter on form
var artistFilterValue = $('.works-content .filter-dropdowns .dropdown-wrapper a.button.artist > span').attr('data-filter-artist');
var techniqueFilterValue = $('.works-content .filter-dropdowns .dropdown-wrapper a.button.technique > span').attr('data-filter-technique');
var materialFilterValue = $('.works-content .filter-dropdowns .dropdown-wrapper a.button.material > span').attr('data-filter-material');
// Empty .gallery in order to fill it later with filtered work
$('.works-content .gallery').empty();
// Get filtered elements and append them to .gallery
$('.single-work[data-artist~="' + artistFilterValue + '"][data-technique~="' + techniqueFilterValue + '"][data-material~="' + materialFilterValue + '"]').each(function(){
$('.works-content .gallery').append($(this));
});
});
The document initially looks like this (both '.gallery' and '.gallery-source' are populated):
<div class="row works-content">
<div class="row">
<div class="small-12 medium-12 large-12 columns filter-dropdowns">
<div class="dropdown-wrapper">
Filtrar por:
<span class="dropdown-label">Artista</span>
<span data-filter-artist="all">Seleccionar</span> <i class="fa fa-chevron-down"></i><br>
<ul id="artist-dropdown" data-dropdown-content="" class="f-dropdown">
<li><span data-filter-artist="all">Todos</span></li>
<li><span data-filter-artist="name-one">Name One</span></li>
<li><span data-filter-artist="name-two">Name Two</span></li>
</ul>
</div>
<div class="dropdown-wrapper">
Técnica:
<span data-filter-technique="all">Seleccionar</span> <i class="fa fa-chevron-down"></i><br>
<ul id="technique-dropdown" data-dropdown-content="" class="f-dropdown">
<li><span data-filter-technique="all">Todos</span></li>
<li><span data-filter-technique="acrylic">Acrílico</span></li>
<li><span data-filter-technique="mixed-paper">Mixta sobre papel</span></li>
<li><span data-filter-technique="mixed-fabric">Mixta sobre tela</span></li>
<li><span data-filter-technique="oil">Óleo</span></li>
</ul>
</div>
<div class="dropdown-wrapper">
Soporte:
<span data-filter-material="all">Seleccionar</span> <i class="fa fa-chevron-down"></i><br>
<ul id="material-dropdown" data-dropdown-content="" class="f-dropdown">
<li><span data-filter-material="all">Todos</span></li>
<li><span data-filter-material="fabric">Tela</span></li>
<li><span data-filter-material="paper">Papel</span></li>
</ul>
</div>
<ul class="button-group filter-buttons">
<li class="active show-all">Todas</li>
<li class="show-available">Disponibles</li>
<li class="show-sold">Vendidas</li>
</ul>
</div>
</div>
<div class="row gallery-source">
<div data-artist="name-one all" data-technique="oil all" data-material="paper all" class="small-12 medium-4 large-4 columns single-work available-work">
<a class="work-lightbox" href="img/work/name-one/3.jpg">
<div class="work-image-wrapper">
<div class="work-image" style="background-image: url(img/work/name-one/3.jpg);"></div>
</div>
<img class="avatar" src="img/artists/name-one.png">
</a>
<a href="" class="artist-name">
<h2>Name One <i class="fa fa-plus-circle"></i></h2>
</a>
<ul class="details">
<li class="title">"Título de obra"</li>
<li>Código SUA1005</li>
<li>Tamaño: 140 x 180 cm.</li>
<li>Soporte: Papel</li>
<li>Técnica: Óleo</li>
</ul>
</div>
<div data-artist="name-two all" data-technique="acrylic all" data-material="fabric all" class="small-12 medium-4 large-4 columns end single-work sold-work">
<a class="work-lightbox" href="img/work/name-two/5.jpg">
<img class="sold" src="img/work/sold.png">
<div class="work-image-wrapper">
<div class="work-image" style="background-image: url(img/work/name-two/5.jpg);"></div>
</div>
<img class="avatar" src="img/artists/name-two.png">
</a>
<a href="" class="artist-name">
<h2>Name Two <i class="fa fa-plus-circle"></i></h2>
</a>
<ul class="details">
<li class="title">"Título de obra"</li>
<li>Código SUA1005</li>
<li>Tamaño: 140 x 180 cm.</li>
<li>Soporte: Tela</li>
<li>Técnica: Acrílico</li>
</ul>
</div>
</div>
<div class="row gallery">
<div data-artist="name-one all" data-technique="oil all" data-material="paper all" class="small-12 medium-4 large-4 columns single-work available-work">
<a class="work-lightbox" href="img/work/name-one/3.jpg">
<div class="work-image-wrapper">
<div class="work-image" style="background-image: url(img/work/name-one/3.jpg);"></div>
</div>
<img class="avatar" src="img/artists/name-one.png">
</a>
<a href="" class="artist-name">
<h2>Name One <i class="fa fa-plus-circle"></i></h2>
</a>
<ul class="details">
<li class="title">"Título de Obra"</li>
<li>Código ejemplo</li>
<li>Tamaño: 140 x 180 cm.</li>
<li>Soporte: Papel</li>
<li>Técnica: Óleo</li>
</ul>
</div>
<div data-artist="name-two all" data-technique="acrylic all" data-material="fabric all" class="small-12 medium-4 large-4 columns end single-work sold-work">
<a class="work-lightbox" href="img/work/name-two/5.jpg">
<img class="sold" src="img/work/sold.png">
<div class="work-image-wrapper">
<div class="work-image" style="background-image: url(img/work/name-two/5.jpg);"></div>
</div>
<img class="avatar" src="img/artists/name-two.png">
</a>
<a href="" class="artist-name">
<h2>Name Two <i class="fa fa-plus-circle"></i></h2>
</a>
<ul class="details">
<li class="title">"Título de obra"</li>
<li>Código ejempl5</li>
<li>Tamaño: 140 x 180 cm.</li>
<li>Soporte: Tela</li>
<li>Técnica: Acrílico</li>
</ul>
</div>
</div>
</div>
But after selecting an option in one of the filter dropdowns, '.gallery-source' is empty :(
What am I missing here? I think I'm going crazy!
Anyway, any help will be much appreciated.
.append moves the entire node from .gallery-source to .gallery. You want to do this instead:
$(this).clone().appendTo('.works-content .gallery');
You can read about .clone() here.
Here's a jsFiddle demo.
The API docs of empty also say:
... If we had any number of nested elements inside <div class="hello">, they would be removed, too.
So your $('.works-content .gallery').empty() may remove more than you want it to.

Categories

Resources