selection/active class for show/hide divs - javascript

So I have this thing where I need one div to be shown at any one time depending on the button clicked. I found this great fiddle which is almost perfect except for the fact that it doesn't show when one link is selected. I'd like to have it so that the link that's selected can have a sort of active class or look different from the other links. Is that possible? I've been looking through questions and I can't really find an answer for this.
If anyone's interested, I'm using it for this (but the code is really messed up, sorry). (I'd also like to change the filter buttons on the top row to reset and filter all the images, but am aware that's a different question. Still any help would be appreciated!)
html
<div id="linkwrapper">
<a id="link1" href="#">link1</a><br/>
<a id="link2" href="#">link2</a><br/>
<a id="link3" href="#">link3</a>
</div>
<div id="infocontent">
<div id="link1content">Information about 1.</div>
<div id="link2content">Information about 2.</div>
<div id="link3content">Information about 3.</div>
</div>
jquery
$(document).ready(function(){
$("#infocontent").hide();
$("#infocontent div").hide();
$('#linkwrapper a[id]').click(function(){
var vsubmen = this.id +"content";
if( $("#infocontent").is(":visible") == false ) {
$("#" + vsubmen).show('fast',function() {
$("#infocontent").slideDown();
});
} else if ( $("#" + vsubmen).is(":visible") == false ) {
$("#infocontent").slideUp('slow',function(){
$("#infocontent div").hide();
$("#" + vsubmen).show();
$("#infocontent").slideDown('slow');
});
} else {
$("#infocontent").slideUp('slow',function(){
$("#infocontent div").hide();
});
}
return false;
});
});

You can simplify that fiddle like this:
$('a[id^=link]').click(function(){
$('a[id^=link]').removeClass('meactive');
$(this).addClass('meactive');
$('#infocontent>div').slideUp();
var tmp = this.id;
$('#'+tmp+'content').slideDown();
}); //end a.click
jsFiddle Demo
Notes:
(1) $('a[id^=link]') -- grabs all a elements with a ID that starts with link
(2) $('#' +tmp+ 'content') -- builds selectors like: $('#link3content)`

Related

Add class to all elements with a certain class [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I'm a bit new to javascript and jquery, and I have some troubles doing what I want in a "nice" way.
I have a HTML web page like this:
<div class="list-group">
All
Foo
Bar
FooBar
</div>
<div class="row">
<div class="category-0">element 1</div>
<div class="category-1">element 1</div>
<div class="category-1">element 1</div>
<div class="category-0">element 1</div>
<div class="category-2">element 1</div>
<div class="category-0">element 1</div>
<div class="category-2">element 1</div>
</div>
I would like to add some kind of "filter", where if you click on a certain category link, all elements from other categories will disappear.
I managed to do it by adding a class to my css called invis with "display:none", and then wrote this:
$( ".list-group-item" ).click(function() {
$(".list-group-item").removeClass('active');
$( this ).toggleClass("active");
var test = "." + event.target.id;
$(".category-0").addClass('invis');
$(".category-1").addClass('invis');
$(".category-2").addClass('invis');
if (test == ".category-0")
$(".category-0").removeClass('invis');
if (test == ".category-1")
$(".category-1").removeClass('invis');
if (test == ".category-2")
$(".category-2").removeClass('invis');
if (test == ".category-all") {
$(".category-0").removeClass('invis');
$(".category-1").removeClass('invis');
$(".category-2").removeClass('invis');
}
});
This does the job, but I'd like to find a "cleaner" way of doing it. How can I improve it?
Thanks !
One way to do it using jQuery would be to hide all of the <div>s when a filter control is clicked, then unhide the specific ones that you want to show.
This way you won't need your extra invis class.
you will notice the "^=" symbol in the below code it simply is a selector that literally means "starts with".
$('a[id^="category"]').click(function() {
// when an <a> element is click THAT has an ID that starts with "category" ...
$('div[class^="category"]').hide();
// hide every <div> that's ID starts with "category" ...
$('div.' + this.id).show();
// re-show every <div> that's CLASS matches the original <a>'s ID ...
});
$('a[id="show-all"]').click(function() {
// if the "all" is clicked, show them ALL again.
$('div[class^="category"]').show();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="list-group">
All
Foo
Bar
FooBar
</div>
<div class="row">
<div class="category-0">Foo</div>
<div class="category-1">Bar</div>
<div class="category-1">Bar</div>
<div class="category-0">Foo</div>
<div class="category-2">FooBar</div>
<div class="category-0">Foo</div>
<div class="category-2">FooBar</div>
</div>
Hide all elements with class "row" and then un-hide all elements with class [id of what was clicked] within class "row".
$('.list-group-item').click(function(event) {
$('.row').addClass('invis');
$('.row.' + event.target.id).removeClass('invis');
});
By simply adding to all your categories the .category-all you've done half-job.
Now you can control the id>>>class relations much easily.
jsBin demo
If you need to always have at least one category visible it's quite simple:
var $btns = $(".list-group-item");
var $ctgs = $("[class^='category-']");
$ctgs.addClass("category-all"); // Job done! :D :D
$btns.click(function(e) {
$ctgs.hide(); // Hide all
$("."+this.id).show(); // Show realated
});
Otherwise, The code below will allow you to have any combination you desire
And even hide/toggle the active ones:
jsBin demo
var $btns = $(".list-group-item");
var $ctgs = $("[class^='category-']");
$ctgs.addClass("category-all"); // Job done! :D :D
$btns.click(function(e) {
$ctgs.not("."+this.id).hide(); // Hide all (not this...)
$("."+this.id).toggle( $(this).hasClass("active") ); // Toggle realated
});
Disclaimer: not tested.
$('.list-group-item').click(function() {
$('.list-group-item').removeClass('active');
$(this).addClass('active');
var id = $(this).attr('id');
if(id == 'category-all') {
$('div.row > div').show();
} else {
$('div.row > div.' + id).show();
$('div.row > div:not(.' + id + ')').hide();
}
});
Here's another version. Added color coding for visibility.
*Edit updated to actually have the right behavior.
http://codepen.io/anon/pen/NPrGJp
$( ".list-group-item" ).click(function() {
$('.active').removeClass('active');
$(this).addClass('active');
$('.row > div').show();
$('.' + $(this).attr('id')).hide();
});

Open Expanding List from Href

I'm trying to modify this pen I found on CodePen. I'd like to be able to open a specific list on the page from another page. Clicking the link should open the corresponding section on the next page on page load.
I'm a bit of a newbie when it comes to jQuery, so I appreciate any help I can get. I've tried searching around and have an idea of what I need to target, but I haven't been able to make it happen. Here is my code:
HTML:
<!--Link on Previous Page-->
Click Here
<!--Target List-->
<div class="integration-list">
<ul>
<li class="integration">
<a class="expand" id="list">
<div class="expand_intro"><h3 class="teal_bold">Click Here</h3></div>
<div class="right-arrow">▼</div>
</a>
<div class="detail">
<div><p>Lorem Ipsum Dolor...</p></div>
</div>
</li>
</ul>
</div>
JS:
$(function() {
$(".expand").on( "click", function() {
$(this).next().slideToggle(100);
$expand = $(this).find(">:nth-child(2)");
if($expand.text() == "▼") {
$expand.text("▲");
} else {
$expand.text("▼");
}
var hash = window.location.hash;
var thash = hash.substring(hash.lastIndexOf('#'), hash.length);
$('.expand').find('a[href*='+ thash + ']').trigger('click');
});
});
Few things that I did to get it to work:
The trigger event is probably firing before the handler is actually attached. You can use setTimeout as a way around this.
Also, even with setTimeout around $('.expand').find('a[href*='+ thash + ']').trigger('click'); it didn't work for me. I changed that to simply $(thash).click();.
The complete code of the "expand.js" file:
$(function() {
var hash = window.location.hash;
var thash = hash.substring(hash.lastIndexOf('#'), hash.length);
setTimeout(function() {
$(thash).click();
}, 10);
$(".expand").on( "click", function() {
$(this).next().slideToggle(100);
$expand = $(this).find(">:nth-child(2)");
if($expand.text() == "â–¼") { //If you copy/paste, make sure to fix these arrows
$expand.text("â–²");
} else {
$expand.text("â–¼");
}
});
});
Apparently the arrows don't display properly here, so watch that if you copy/paste this.

Set "active" accordion menu after click

I'm trying to set accordion menu "active" after click on link and change the page...
<div class="menu">
<dl>
<dt>HOME</dt>
<dt>QUEM SOMOS</dt>
<dd>
<ul>
<li>EMPRESA</li>
<li>INSTITUCIONAL</li>
<li>NOSSOS PRODUTOS</li>
<li>RESPONSABILIDADE SOCIAL</li>
<li>RESPONSABILIDADE AMBIENTAL</li>
</ul>
</dd>
<dt>PRODUTOS</dt>
<dd>
<ul class="produtos">
<%do while not rscat.EOF%>
<li><%= rscat("categoria")%></li>
<% rscat.MoveNext
if rscat.EOF then Exit do %>
<% Loop %>
</ul>
</dd>
<dt>INFORMATIVO</dt>
<dt class="no_border">CONTATO</dt>
</dl>
</div>
jquery:
<script type="text/javascript">
$(document).ready(function(){
$('dd').hide();
$('dt a.submenu').click(function(){
$("dd:visible").slideUp("slow");
$(this).parent().next().slideDown("slow");
return false;
});
});
</script>
i'm trying too, use this https://stackoverflow.com/questions/10681033/accordion-menu-active-state-after-link-click but dont work...
what i try (but don't work):
<script type="text/javascript">
$(document).ready(function(){
$('dd').hide();
var sPath = window.location.pathname;
var sPage = sPath.substring(sPath.lastIndexOf('/') + 1);
$("dt a.submenu[href='" + sPage + "']").parents("dd:visible").show();
$('dt a.submenu').click(function(){
$("dd:visible").slideUp("slow");
var checkElement = $(this).next();
if ((checkElement.is("dd")) && (checkElement.is(":visible"))) {
return false;
}
if ((checkElement.is("dd")) && (!checkElement.is(':visible'))) {
$(this).parent().next().slideDown("slow");
checkElement.slideDown("normal");
return false;
}
});
});
</script>
Well, the first sublinks ul point to especific pages, but the another sublink ul class=produtos show the categories that's on database, and uses same link on each categories like: produtos_categoria.asp?categoria=xxxxxx...
If the user, click on "EMPRESA", on the page empresa.asp the QUEM SOMOS menu need to be opened. And if the user click on some categories under the menu PRODUTOS, on the page produtos_caegoria.asp the PRODUTOS need to be opened..
I'm clear?
So.. what i need to do?
FIDDLE: http://jsfiddle.net/Qf7Js/1/
check this jsfiddle to see if it does what you require. As far as I could understand the problem, you want to, on page load, automatically open the accordion menu that contains the current link.
This can be achieved with following code
//say this is the current link which can be retrieved in real website using window.location object
var init_link = 'institucional.asp'
//then instead of hiding all <dd>, using $('dd').hide(), you only hide the ones that don't contain an <a> that has href equal to init_link.
$('dd').filter(function () {
return $('a[href="' + init_link + '"]', $(this)).length == 0
}).hide();
Just change the init_link value to what the current URL. Watch out for the hostname part because your <a> might not contain absolute URL. This might help Get current URL in web browser.
To get currnet URL without the hostname part, you could (not must) use following code
var init_link = window.location.href.replace(window.location.protocol+'//'+window.location.hostname+'/', '')
To clarify, it seems like all you are looking to do is apply a class to the dt in addition to hiding/showing the next dd item? This can be achieved with callback functions, or by simply chaining the method on. Something like this:
<script type="text/javascript">
$(document).ready(function(){
var $menu = $('dl.menu');
$('dd', $menu).hide();
$('dt a.submenu', $menu).on("click", function(e){
e.preventDefault();
var $parent = $(this).parent('dt');
if($parent.hasClass('active')){
$parent.removeClass('active').next('dd').slideUp("slow");
} else {
$parent.siblings('.active').removeClass('active').siblings("dd").slideUp("slow", function(){
$parent.addClass('active').next('dd').slideDown("slow");
});
}
$("dd:visible", $menu).slideUp("slow", function(){
$(this).removeClass('active');
});
$(this).parent().next().slideDown("slow");
});
});
</script>
Hope this helps provide some direction.

Toggle innerHTML

I've seen various examples come close to what I am looking for, but none of it seems to describe it how I exactly want it. I am a beginner to jQuery, so explanations welcome.
I'm looking for this to toggle the innerHTML from - to +. Anyone know of a way to do this, efficiently?
jQuery/JavaScript
$(document).ready(function() {
$(".A1").click(function() {
$(".P1").toggle("slow");
$(".A1").html("+");
});
});
HTML
<div class="A1">-</div>
<h2 class="H1">Stuff</h2>
<div class="P1">
Stuffy, Stuffy, Stuffed, Stuffen', Stuffing, Good Luck Stuff
</div>
Thank you, anything relating to switching the inside text of an HTML element shall help. =)
How about adding a class that will let you know the expanded/collapsed status?
$(document).ready(function() {
$(".A1").click(function() {
var $this = $(this);
$(".P1").toggle("slow")
$this.toggleClass("expanded");
if ($this.hasClass("expanded")) {
$this.html("-");
} else {
$this.html("+");
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="A1 expanded">-</div>
<h2 class="H1">Stuff</h2>
<div class="P1">
Stuffy, Stuffy, Stuffed, Stuffen', Stuffing, Good Luck Stuff
</div>
Example: http://jsfiddle.net/sGxx4/
$(document).ready(function() {
$(".A1").click(function() {
$(".P1").toggle("slow");
$(".A1").html(($(".A1").html() === "+" ? $(".A1").html("-") : $(".A1").html("+")));
});
});
A bit of explanation: I'm setting $("#A1").html() with the product of the tertiary operator, using it to check for the current value of #A1's text. If it's a +, I set the element's text to -, otherwise, I set it to +.
However, you said "efficiently." To this end, it's important to note that if you're going to use a selector twice or more in the same function, you should store the jQuery object that results from the selector you give in a variable, so you don't have to re-run the selector each time. Here's the code with that modification:
$(document).ready(function() {
$(".A1").click(function() {
var $A1 = $(".A1");
$(".P1").toggle("slow");
$A1.html(($A1.html() === "+" ? $A1.html("-") : $A1.html("+")));
});
});
There's no way to toggle content.
You could check if the $('.P1') is visible, then changing the +/- div according to that.
Something like :
$(document).ready(function() {
$(".A1").click(function() {
$(".P1").toggle("slow", function(){
if($(this).is(':visible'))
$(".A1").html("-")
else
$(".A1").html("+")
});
});
});
Using a callback function (the second argument of the .toggle() method) to do the check will guarantee that you're checking after the animation is complete.
JsFiddle : http://jsfiddle.net/cy8uX/
more shorter version
$(document).ready(function() {
$(".A1").click(function() {
var $self = $(this);
$(".P1").toggle("slow", function ( ) {
$self.html( $self.html() == "-" ? "+" : "-");
});
})
});
Here's a way that uses class names on a parent and CSS rules and doesn't have to change the HTML content and works off a container and classes so you could have multiple ones of these in the same page with only this one piece of code:
HTML:
<div class="container expanded">
<div class="A1">
<span class="minus">-</span>
<span class="plus">+</span>
</div>
<h2 class="H1">Stuff</h2>
<div class="P1">
Stuffy, Stuffy, Stuffed, Stuffen', Stuffing, Good Luck Stuff
</div>
</div>​
CSS:
.expanded .plus {display:none;}
.collapsed .minus {display: none;}
Javascript:
$(document).ready(function() {
$(".A1").click(function() {
$(this).closest(".container")
.toggleClass("expanded collapsed")
.find(".P1").slideToggle("slow");
});
});
​
Working demo: http://jsfiddle.net/jfriend00/MSV4U/

Selecting a single class from a multi class element

I'm trying to select a specific class (in this case page1, page2, page3 etc.)
I've written this code that works fine for a single class, i've tried using .match() to exclude the .plink class picked up in dis but can't get it working.
$(function(){
$("a.plink").click(function() {
var dis = $(this).attr("class"); // This is the problem line, I need it to contain 'page1' ONLY. Not 'page1 plink'.
$("#page1,#page2,#page3").hide();
$("#" + dis).show();
return false;
});
});
The HTML that is associated with this is:
<div id="page-links">
<a class="page1 plink" href="#">About</a>
<a class="page2 plink" href="#">History</a>
<a class="page3 plink" href="#">Backstage</a>
</div>
EDIT:
These are the DIV's being shown and hidden:
<div id="page1">
<?php include_once("page1.php");?>
</div>
<div id="page2">
<?php include_once("page2.php");?>
</div>
<div id="page3">
<?php include_once("page3.php");?>
</div>
Is there a simple way to achieve this without regular expression matching?
$(function(){
var pages = $('div[id^=page]');
$("a.plink").click(function() {
var dis = $(this).attr("class").replace(' plink', '');
pages.hide().filter('#' + dis).show();
return false;
});
});
This should be
$("." + dis).show();
for class and in your example there are all classes.
As you mentioned simple way so it could be
$("a.plink").click(function() {
$(".plink").hide();
$(this).show();
return false;
});
According to your question after edit
$("a.plink").click(function() {
$('div[id^="page"]').not('#page-links').hide();
pid=$(this).attr('class').split(' ')[0];
$('#'+pid).show();
return false;
});
Here is a fiddle.
The JavaScript code is not correct. With the "#" you select ids from the html-element.
As you have only classes, the right way is to do it with "."
So this would be correct:
$(function(){
$("a.plink").click(function() {
var dis = $(this).attr("class");
$(".page1,.page2,.page3").hide();
$("." + dis).show();
return false;
});
});
I didn't test it, but I think you have to change something with the var dis.
If you click on .page1, the variable dis would contain "page1 plink".
$("." + dis).show();
would be
$(".page1 plink").show();
So I recommend to split the two classes, as it should be like
$(".page1 .plink").show();
You are trying to associate functionality of a click by appending classes. It would make more sense to put id of the div you want to show in the href
html:
<div id="page-links">
<a class="plink" href="#page1">About</a>
<a class="plink" href="#page2">History</a>
<a class=" plink" href="#page3">Backstage</a>
</div>
<div id="page1">
Content 1
</div>
<div id="page2">
Content 2
</div>
<div id="page3">
Content 3
</div>
​javascript:
jQuery(function ($) {
var pages = [];
function showPage(page) {
var i;
for(i = 0; i < pages.length; i++)
{
if(page === pages[i]) {
$(pages[i]).show();
} else {
$(pages[i]).hide();
}
}
}
// Store each href in a pages array and add handlers
$('.plink').each( function() {
var page = $(this).attr('href');
pages.push(page);
$(this).attr('href', '#');
$(this).click(function () {
showPage(page);
});
});
// show the first page
if(pages.length > 0) {
showPage(pages[0]);
}
});​
Example:
http://jsfiddle.net/38qLB/
And just so I don't avoid the actual question, which is how do you select a class from a multi class element, you should follow this example of splitting up the class name Get class list for element with jQuery if you truly insist on using classes to make your link/div association
You don't really want to exclude the plink class, because that will bring you confusion and trouble when you need to add another class. Instead you want to extract just the pageX class:
// Regex for extracting pageXX
var reg = /^(.*\s)?(page\d+)([^\d].*)?$/;
dis = reg.exec(dis)[2];
I haven't testet this 100%, but put these two lines in right after var dis = $(this).attr("class"); and you should hopefully be good to go.
i down't know if i get your question right
to get all classes with class plink u can use
var klasses $("a.plink");
now u can loop true the items
var yourClasses = Array();
for(var klass in klasses)
{
var word = klass.attr('class').replace(" plink", "");
yourClasses.push(word);
}
now you have all the classes wich have the class plink
hope this was where u where looking for
If I was just doing a minor tweak to fix your existing structure I would do something like this:
$(document).ready(function() {
$('a.plink').click(function() {
var id = $.trim(this.className.replace('plink', ''));
/*adding a "page" class to each of the page divs makes hiding the visible one a bit easier*/
$('div.page').hide();
/*otherwise use the version from sheikh*/
//$('div[id^="page"]').not('#page-links').hide();
$('div#' + id).show();
});
});
The main change I would recommend to your existing markup would be to add a common "page" class to each of the page divs. Here is a fiddle
If I was starting on this from scratch I would probably take a slightly different approach in which I define an "active" class and toggle which elements have it rather than using show/hide on the divs. And that would end up looking something like this:
Markup:
<div id="page-links">
<a class="plink active" href="#page1">About</a>
<a class="plink" href="#page2">History</a>
<a class="plink" href="#page3">Backstage</a>
</div>
<div id="page1" class='page active'> </div>
<div id="page2" class='page'> </div>
<div id="page3" class='page'> </div>
CSS:
div.page
{
height: 300px;
display:none;
}
div.page.active
{
display:block;
}
a.plink
{
padding-left:5px;
padding-right:5px;
}
a.plink.active
{
background-color:#ddd;
}
div#page1
{
background-color:blue;
}
div#page2
{
background-color:green;
}
div#page3
{
background-color:red;
}
Script:
$(document).ready(function() {
$('a.plink').click(function() {
var id = $(this).attr('href');
$('.active').removeClass('active');
$(this).addClass('active');
$('div' + id).addClass('active');
});
});
Or the fiddle here.
Oh and to answer the title question rather than just the end behavior described...
var classes = this.className.split(' ');
var id;
for (var i = 0; i < classes.length; i++) {
if(classes[i].substring(4) === classes[i].replace('page', '')) {
id = classes[i];
break;
}
}
should end up with id containing the "page#" value associated with the link that was clicked regardless of its position in the list of classes.

Categories