ToggleClass on multiple elements with similar class - javascript

I've got a navigation with links, that contain the same classes as the sections of the page. See HTML:
Link 1
Link 2
Link 3
<section class="one">Section 1</section>
<section class="two">Section 2</section>
<section class="three">Section 3</section>
Now I want to add class 'active' to both the link and the section when I click the link. I've got this working with the following jQuery:
$('a').click(function(){
$('.active').removeClass('active');
var activeClass = this.className;
$('.' + activeClass).toggleClass('active');
});
The only problem is that the classes don't toggle. I want the active state to disappear for both the link and the section, when I click an active link. I tried it with the if statement this way:
if($(this).hasClass('active')){
var activeClass = this.className;
$('.' + activeClass).removeClass('active');
}
I guess I'm missing some deeper knowledge here, can anyone help me out? Thanks in advance.
fiddle

You'll have to exclude the currently clicked class from the removeClass statement, otherwise toggleClass will always add the class as you always remove it first.
You should also remove the active from the className when you get it, otherwise you're sometimes getting one active etc. and not just one.
$('a').click(function(){
var activeClass = '.' + $.trim(this.className.replace('active',''));
$('.active').not(activeClass).removeClass('active');
$(activeClass).toggleClass('active');
});
FIDDLE

You just need to rework your script a bit..
<style>
a.active{
color: red
}
section{
height: 200px;
width: 100%;
border: 1px solid black;
margin: 10px 0 10px 0;
}
section.active{
border-color: red!important;
}
</style>
Link 1
Link 2
Link 3
<section class="one active">Section 1</section>
<section class="two">Section 2</section>
<section class="three">Section 3</section>
<script>
$(document).ready(function(){
$('a').on('click', function(){
//remove all active
$('.active').removeClass('active');
//get the class of this link
var activeClass = $(this).attr('class');
$('.' + activeClass).addClass('active');
});//end a.bind
});//end doc.ready
<script>
http://jsfiddle.net/7Q4ph/10/

Related

How to get index without counting the hidden elements?

I'm trying to get the index of clicked element. This works fine so far.
Problem is that you can hide elements. If an element is hidden I don't want it to be "counted" in the index.
If you have a look at the fiddle and all boxes are orange the index is how it should be. If you click on Click me to hide some divs -- they don't get removed, in reality they get a display:none; here they just get another color to give you an idea -- they also get the class hidden so now I don't want the index to index them. But if I click on Div 2 I would like the index to show 1
I've tried with $('div').not('hidden') fiddle here -> http://jsfiddle.net/rva54sy3/2/
<script>
(function($){
var indexBoxes = function(e) {
$element = $(this);
var index = $element.not('.hidden').index();
$( "h3.txt" ).text( "That was div index #" + index );
}
$(document).on( 'click', '.getIndex', indexBoxes);
})(jQuery);
$('.hide-some-divs').on('click',function(){
$('.hide').addClass('hidden').closest('.wrap').addClass('hidden');
});
</script>
<h3 class="txt">Click a div!</h3>
<div class="wrap clearfix">
<div class="getIndex">Div 0</div>
<div class="getIndex hide">Div 1</div>
<div class="getIndex">Div 2</div>
<div class="getIndex hide">Div 3</div>
<div class="getIndex">Div 4</div>
<div class="getIndex hide">Div 5</div>
</div>
<div class="hide-some-divs">Click me to hide some divs</div>
and if you like some styling:
<style>
.getIndex {
width:100px;
height:100px;
margin:5px;
background-color:orange;
float:left;
}
.wrap.hidden > div.hide {
background-color:#fafafa;
}
.hide-some-divs {
background-color:#afafff;
padding:10px;cursor:pointer;
margin:20px auto;
width:250px;
text-transform:uppercase;
text-align:center;
}
.clearfix:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
.clearfix { display: inline-block; }
</style>
Thanks for advices
You can get the index like this way
(function($) {
var indexBoxes = function(e) {
var index = $(".getIndex").not('.hidden').index(this);
$("h3.txt").text("That was div index #" + index);
}
$(document).on('click', '.getIndex', indexBoxes);
})(jQuery);
This will the index of given element corresponding to your selected list(not related to the immediate parent). Here the selected element list is .getIndex class divs which doesnt have the class name .hidden
Fiddle
You can use $.inArray() to get the index of clicked element from visible elements.
(function($){
var indexBoxes = function(e) {
$element = $(this);
var index = ($.inArray((this),$(".getIndex").not(".hidden")));
$( "h3.txt" ).text( "That was div index #" + index );
}
$(document).on( 'click', '.getIndex', indexBoxes);
})(jQuery);
Here's a link to fiddle!
In case you would actually hide them, you could use:
var index = $(".getIndex:visible").index(this);
The selector only counts elements with a class .getIndex that are also visible (aka not display: none)
However, that won't work with your example, because you use a background color to "fake" hiding them.

Show/Hide divs that occupy the same space with separate links

I'm having an issue with trying to get divs to occupy the same space, and to also have a show/hide ability on them when clicking their respective links.
Can anybody please let me know the proper jQuery to put in to make this happen? Below is the code without jQuery.
The idea is that when I click on Print 1, then the piece #1 will show up, and when I click Print 2, #1 will disappear and #2 will take it's place.
Current HTML looks something vaguely like this:
<div id="content">
<div id="SideNav">
<ul>
<li>
<a>Print 1</a>
</li>
<li>
<a>Print 2</a>
</li>
</ul>
</div>
<div id="pieces">
<div id="1">
</div>
<div id="2">
</div>
</div>
</div>
CSS is basically this:
#content {
width:848px;
position:relative;
}
#SideNav {
width:169px;
float:left;
}
#pieces {
width:678px;
top:0px;
float:right;
position:relative;
}
#1 {
position:absolute;
top: 0px;
right: 0px;
z-index:1;
}
#2 {
position:absolute;
top: 0px;
right: 0px;
z-index:2;
}
JSFIDDLE
a Basic example of what you want to achieve :
JS :
$('a').on("click",function(){
alert($(this).text());
if($(this).text() == "Print 1"){
$('#1').show();
$('#2').hide();
}else{
$('#2').show();
$('#1').hide();
}
});
putting an event on click of your anchors and then checking the value of the clicked anchor.
Assuming the first link toggles the visibility of the first div and the second link toggles the second div
$('a').click(function() {
var index = $(this).closest('li').index();
$('#pieces div').eq(index).toggle();
}
And set display:none on the the second div
The trick is to make your markup structure a little more meaningful, and your CSS styling a little more generalized. This allows you to leverage common indexes between the links and the tabs below, as well as to define the style using a single CSS class. Then you can easily scale the solution for any number of links and panels:
jsFiddle
HTML
<div id="content">
<div id="SideNav">
<ul>
<li> Print 1
</li>
<li> Print 2
</li>
</ul>
</div>
<div id="pieces">
<div id="panel1" class="panel">First Div</div>
<div id="panel2" class="panel">Second Div</div>
</div>
</div>
CSS
/*
#content, #SideNav, #pieces
Same As Before
*/
.panel {
display: none;
position:absolute;
top: 0px;
right: 0px;
}
JS
$(function () {
$("a[id^='link']").click(function (e) {
e.preventDefault();
var index = this.id.replace("link", "");
$(".panel").hide();
$("#panel" + index).show();
});
});
You setup the click function for each of the anchors within the #sideNav container, prevent the default anchor tag function(preventDefault(), in case an href attribute is provided) and then execute what you want to do.
$('#sideNav a').click(function(e){
// prevent default link event
e.preventDefault();
// use show()/hide() or toggle()
});

dynamic breadcrumbs using anchor tags and isinViewport

Working on creating a small jquery plugin for a client's website that is a simple breadcrumb system using anchor tags, that changes the last element in the breadcrumb list based on which anchor tag is currently visible. Further, I'm using HTML5 data- elements to store each page name, so that I can add that as the second element in the breadcrumb list as well.
For visibility, I'm using this plugin: https://github.com/zeusdeux/isInViewport
This is the fiddle I'm working with: http://jsfiddle.net/7F59C/4/
Here is the HTML:
<div class="header">head element
<div id="breadcrumbs" data-page="About">
<ul>
<li>Home</li>
<li class="currentpage"></li>
<li class="active"></li>
</ul>
</div>
</div>
<div class="spacer"></div>
<div class="gridContainer">
<div class="space">
take up some space<br />
<a class="crumb" id="About" href="#">About Us</a>
</div>
<div class="space">
take up more space<br />
<a class="crumb" id="Other_heading" href="#">Other heading</a>
</div>
</div>
The JS:
$(document).ready(function() {
$jbread();
});
$.fn.jbread = function () {
//set bc as breadcrumbs list
var bc = $("#breadcrumbs");
//BUILD CURRENT PAGE BREADCRUMB ITEM
//set currentpage to current page's data-page value
var currentpage = bc.data("page");
//set currentpage_link to current page's url
var currentpage_link = window.location.pathname;
//add currentpage as next li in breadcrumbs list
$(".currentpage").html('' + currentpage + '');
//UPDATE ACTIVE ITEM IN BREADCRUMB LIST
$.fn.updateCrumbs = function () {
var currentactive = $(e.target);
$(".active").html(currentactive);
}
//WORK WITH ISINVIEWPORT PLUGIN
$('div.gridContainer > a.crumb').updateCrumbs();
$('div.gridContainer > a.crumb:in-viewport(10)').updateCrumbs();
$(window).scroll(function() {
$('div.gridContainer > a.crumb').updateCrumbs();
$('div.gridContainer > a.crumb:in-viewport(250)').updateCrumbs();
});
//STYLE BREADCRUMB LIST
};
And, for good measure, CSS:
#breadcrumbs ul {
list-style: none;
float: left;
padding: 2px;
}
#breadcrumbs ul li a {
text-decoration: none;
color: black;
}
.space {
height: 500px;
background-color: red;
}
.header {
position: fixed;
height: 100px;
background-color: #FFF;
width: 100%;
margin-top: 0;
}
.spacer {
min-height: 100px;
}
INTENDED FUNCTIONALITY:
As the user is scrolling down the page, when one of the anchor tags with the class "crumb" comes intoViewport (which I have set as 250-350 pixels down the page), I would like the list item with the class of "active" to be updated with the anchor tag that just triggered the function. I'm not sure if I'm using $(e.target) correctly, or if it will even reference the correct thing.
I'm hoping to get this function working, and then I need to create an actual demo page to flesh out styling the list after it is populated. That's for another question.
Any thoughts, comments, or criticisms are welcome as I am very new to jQuery and am questioning my logic on this one.
Looks like you want something like
$.fn.updateCrumbs = function () {
var currentactive = this.text();
$(".active").text(currentactive);
}

Collapse/Expand a content box with a toggle

I go right to the point, I have a few boxes that I want them to be expanded and collapsed with a toggle located in their headers.
This toggle is an anchor tag which has a sprite background, the top part of this sprite image is pointing at top, and bottom section is pointing at down. You can guess what they mean and I want their state to be changed (first one for collapse and second one for expand)
The structure of the boxes are something like this :
<section class="box2">
<header class="box-head">
<div class="box-title fr">
<span class="box-icon"></span>
<h3 class="box-title-text">Title Title</h3>
</div>
<a class="box-toggle fl active" href="#">A</a>
<br class="cfx" />
</header>
<div class="box-content">
<img src="img/chart-1.png" alt="" />
//Content or collapsing data goes here
</div>
</section>
And I used one of the most straight forward ways to achieve this effect. You can see the following CSS and jQuery code below. (I chose active class as default when the icon is pointing at top)
JS :
<script type="text/javascript">
$("a.box-toggle").toggle(function(){
$(this).addClass("active");
}, function () {
$(this).removeClass("active");
});
//Slide up and down on click
$("a.box-toggle").click(function(){
$(this).next("div.box-content").slideToggle("slow");
});
});
</script>
CSS :
.widget-toggle {
display: block;
overflow: hidden;
text-indent: -9999px;
width: 18px; height: 9px;
margin-top: 15px;
margin-left: 13px;
background: url(../img/sidebar-arrows.png) no-repeat 0 -18px;
}
.widget-toggle.active {
background: url(../img/sidebar-arrows.png) no-repeat 0 0;
}
Thanks for your huge help :)
Edit No. #1 :
Thanks to #Recode , their tip worked just fine, But according to what I explained and you can see in this picture. I wanna show the state of this with an Icon
Active is pointing at top and Inactive is pointing at bottom, when I want the box to be collapsed I'm showing "Active" and when I want the box to be expanded I'm showing "Inactive" .
With this code I managed to show active at default (I set the class of each box to active manually, if there is a better way to set the default class to active or whatever else please note.)
When I click on it, box collapses and the Icon transitions to Inactive state. And When I click again box expands but the Icon stays in the same state (Inactive and pointing at bottom).
And after clicking :
Here is the Code :
$("a.box-toggle").click(function(){
$(this).addClass("active");
}, function () {
$(this).addClass("inactive");
});
Thanks a lot, Again.
Just use this:
$(document).ready(function() {
//Slide up and down on click
$("a.box-toggle").click(function(){
$(this).toggleClass('inactive');
$(this).parent().next("div.box-content").slideToggle("slow");
});
});
http://jsfiddle.net/Recode/DLxaB/
updated fiddle: http://jsfiddle.net/Recode/DLxaB/1/
Try this: FIddle
jQuery code:
$("a.box-toggle").on('click', function () {
$('div.box-content').slideToggle(200).toggleClass('active');
});
.slideToggle() .toggleClass()

Wrong box being hidden

I have an array of links that when clicked will bring up a hidden div with information related to it. Each link, when clicked, will bring up a different div associated with it. I'm trying to make an image (closelabel.png) on every div with the class 'countystats' act as a close button to hide the divs. I can't get the image in every div to act as a clickable link yet. More importantly, when I click on link one nothing happens. When I open up two hidden divs and try to close one, the opposite one closes (if I click on 'one' and 'two' to make the divs appear, and then I lick on the "a" (for purposes of a closing link) the opposite div is closed. So the button for two closes one.
<style type="text/css">
.county{
color:blue;
display:block;
}
.countystats{
background-image:url('../../../../../closelabel.png') ;
background-position:top right;
border:3px black inset;
background-repeat:no-repeat;
background-color:#ccc;
display:none;
right:250px;
margin: 5px 5px 5px 5px;
padding:5px 5px 5px 5px;
width:200px;
}
</style>
<div style="height:250px;bottom:300px; width:100px; padding: 1em; overflow:auto; margin:5px 5px 5px 5px; border: 2px black; overflow-x:hidden;">
<a class="county" href="#">one</a>
<a class="county" href="#">two</a>
<a class="county" href="#">three</a>
<a class="county" href="#">four </a>
<a class="county" href="#">five</a>
<a class="county" href="#">six</a>
</div>
<div class="countystats">stats one<p>woot</p><a class="closediv" href="#">a</a></div>
<div class="countystats">stats two <a class="closediv" href="#">a</a></div>
<div class="countystats">stats three</div>
<div class="countystats">some other stuff</div>
<div class="countystats">even more other stuff</div>
<script type="text/javascript">
$('a.county').each( function(e){
$(this).bind('click', function(e){
var thisIs = $(this).index(); $('.countystats').eq(thisIs).show (250);
});
});
$('a.closediv').each( function(e){
$(this).bind('click', function(e){
var toClose = $(this).index(); $('.countystats').eq(toClose).hide(250);
});
});
</script>
jsfiddle demo
Your problem is a bit of confusion about what this is in the click handler in here:
$('a.closediv').each( function(e){
$(this).bind('click', function(e){
var toClose = $(this).index();
$('.countystats').eq(toClose).hide(250);
});
});
You're calling index on the <a> that you're using to hide the <div> rather than on the <div> itself.
The simplest solution is, as other people have noted, to use closest:
$('a.closediv').click(function(e) {
$(this).closest('.countystats').hide(250);
});
No one else noticed what the real root of your problem was so I thought I'd mention it.
You are trying to bind event handlers incorrectly (for what you want the code to do). Also, just use .closest() to figure out which element to hide.
$('a.county').click(function(e) {
var thisIs = $(this).index();
$('.countystats').eq(thisIs).show(250);
});
$('a.closediv').click(function(e) {
$(this).closest('.countystats').hide(250);
});
http://jsfiddle.net/mattball/tbNvn/4/
Just use parent():
$('a.county').click(function(e) {
var thisIs = $(this).index();
$('.countystats').eq(thisIs).show(250);
});
$('a.closediv').click(function(e) {
$(this).parent().hide(250);
});

Categories