Show/Hide content based on anchor - Almost there - javascript

I am very close but just can't see what I am missing in the jQuery script to only display the correct block of content based upon the anchor clicked and want to display initially to a visitor the first block of content from the anchors. Any help is appreciated.
I have dynamically generated anchor links with a class of .link
The content is also dynamically generated and each anchor point (A, B, C...) has it's content contained in a ul class of .test-full-list. Any help is appreciated.
Generated content:
Anchor links:
<span class="link">A</span>
<span class="link">B</span>
Content:
<div class="test-listing-container">
<ul class="test-full-list">
<ul class="test-category-list">
<a name="A"></a>
<div class="anchor-header">- A -</div>
<li id=test-list>
Some Link 1
Some Link 1
</li>
</ul>
</ul>
</div>
Script:
jQuery(document).ready(function () {
jQuery('.test-listing-container').hide();
jQuery('.link a').click(function () {
var jQuerydiv = jQuery('.test-full-list').eq(jQuery(this).index('.link a'));
jQuerydiv.show('.test-full-list'); // show the relevant div
});
});

If you're bringing in content dynamically, your .click() will not work. This is because the element you are trying to attach the click to hasn't been generated.
You can replace this:
jQuery('.link a').click(function() {
With this:
jQuery('.test-listing-container').on('click', '.link a', function() {
If that doesn't work:
jQuery(document).on('click', '.link a', function() {

Edit: Adding a fiddle to demo the code: http://jsfiddle.net/Fm6bR/1/
Assuming you can't change the markup slightly, you may do the following
A
B
<div class="test-listing-container">
<ul class="test-full-list">
<ul class="test-category-list">
<a name="A"></a>
<div class="anchor-header">- A -</div>
<li id=test-list>
Some Link 1
Some Link 1
</li>
</ul>
</ul>
</div>
jQuery(document).ready(function(){
jQuery('ul.test-category-list').hide();
jQuery('ul.test-category-list').first().show(); //show the first one by default
jQuery(document).on('click', '.link a', function (evt) {
var $a = jQuery(evt.currentTarget),
name = $a.attr('href').substr(1),
$a2 = jQuery('.test-listing-container').find('a[name="' + name + '"]'),
$ul = $a2.parents('ul.test-category-list').first();
jQuery('ul.test-category-list').hide(); // hide all
$ul.show(); // show the relevant one
});
});

Generate the content with an id based on the anchor name or some other unique identifer of the content. set data-content on each link to the id of the contents id. then use jquery to get the content by using .data function on the link in the click function
HTML
<span class="link">A</span>
<span class="link">B</span>
<div class="test-listing-container">
<ul class="test-full-list" id="fulllistA">
<ul class="test-category-list">
<li id=test-list>
Some Link 1
Some Link 1
</li>
</ul>
</ul>
</div>
Javascript
jQuery(document).on("click",".link a",function(e){
e.preventDefault();
e.stopPropagation();
var content = jQuery("#"+jQuery(this).data("content"));
jQuery(".test-listing-container > ul").not(content).hide(); // hide the others.
content.show();
});

Related

How to change active class on li element in JQuery and redirect the user to the specified page when li elelment is clicked?

I have the the following in my script tag. However, whenever I click the on test.php or test2.php li links, I am not redirected to the respective pages.
However, the active class changes from the index.php file to the test.php or test2.php file depending on which link has been clicked but I am not directed to the page. I attempted to the solutions in the following links, but now of them produce the desired result that I want, which is to redirect me to the page clicked and update the active class to the li element.
How to change active class while click to another link in bootstrap use jquery?
Active link after click
Whenever I uncomment this line e.preventDefault(), I am able to navigate to the link that have been click but the active class is not updated to the the
li elememnt clicked, but when the said line is commented, I am not able to navigate to the page clicked, instead, the active class is updated on the li element clicked.
<div class="menu">
<ul class="list">
<li class="header">MAIN NAVIGATION</li>
<li class="active">
<a href="index.php">
<i class="material-icons">home</i>
<span>Home</span>
</a>
</li>
<li class="">
<a href="test.php">
<i class="material-icons">group</i>
<span>Test</span>
</a>
</li>
<li class="">
<a href="test2.php">
<i class="material-icons">people</i>
<span>Test2</span>
</a>
</li>
</ul>
</div>
And the script code:
$(document).ready(function () {
$('.menu .list a').click(function(e) {
$('.menu li.active').removeClass('active');
var $parent = $(this).parent();
$parent.addClass('active');
e.preventDefault();
});
});
The contents of test.php are as follows:
<body class="theme-red">
<nav class="navbar">
<?php include_once('navbar.html'); ?>
</nav>
<section>
<aside id="leftsidebar" class="sidebar">
<?php include_once('left-side-bar.html');?>
</aside>
</section>
<section class="content">
<div class="container-fluid">
<div class="row clearfix">
<table id="tbl-users" class="table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tfoot>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
</tfoot>
<tbody>
<?php
$accounts = get_details();
foreach($accounts as $acc){
?>
<tr>
<td><?php echo $acc['id']; ?></td>
<td><?php echo $acc['name']; ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
</div>
</section>
</body>
Why is the problem arising?
The problem arises that, when you use e.preventDefault() on click of
anchor tag, the default behaviour is to redirect the page and that's
why the page doesn't load but the active class gets added. But when
you don't use e.preventDefault(), the page redirects immediately
and the change you did happen but before it was redirected and not
for the new page(which could be redirected current page or some other page), that's why you can't see the class active added to
it.
.
How to fix the problem?
Well, there are a couple of ways to go about it. I'd say that from the
test.php or test2.php return a value, which you can validate against
the javascript with if-else conditions, if the value matches you make
that li class as active.
Here's the changes you need to make:
Add a span on each of your pages to which you have hyperlinked i.e test.php, test2.php, etc. having text the same as your hyperlink in the anchor tag so for test.php add a span as:
<span id="curpage" style="display:none;">test.php</span>
Then, add a script at the end of your body tag (you may be able to add this script in a seperate file and include in all of your php files using <?php include(".."); ?> :
$('a[href=\"' + $("#curpage").text() + '\"]').parent().addClass("active");
Here's a sample code, that you can try and implement. Make 2 files in
the same directory named as a.html having the code:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<span id="curpage" style="display:none;">a.html</span>
<div class="menu">
<li>1</li>
<li>2</li>
</div>
<script>
$('a[href=\"' + $("#curpage").text() + '\"]').parent().css("color","red");
</script>
</body>
</html>
And b.html having the code:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<span id="curpage" style="display:none;">b.html</span>
<div class="menu">
<li>1</li>
<li>2</li>
</div>
<script>
$('a[href=\"' + $("#curpage").text() + '\"]').parent().css("color","red");
</script>
</body>
</html>
And now when you change the pages by clicking the link, you can see
how the color of bullet changes.
I don't think you should be changing the "active" class just when the li links are clicked. Think that when you redirect your users to a specific page from another, the li links "OnClick" event won't be fired at all, hence, the active menu link won't be displayed appropriately.
Now, what I usually do to solve this issue (don't know if it's the most elegant solution, but it works) is to place a tag at the top of each html content template (I'm assuming you're using templates for the Header, Footer and Content here), I give it a descriptive ID, like "page-name" or "section", and add a data attribute to it with the name of the menu link that this page "belongs" to:
<div id="page-name" data-page="home-page">
Then with JQuery you can ask for the div's data like this:
var current_page = $("#page-name").data("page");
And simply alter the menu links class depending on what page the user is currently in:
// remove the "active" class from ALL the links first
$(".menu li a").removeClass("active");
if (current_page === "home-page") {
// add the "active" class just to the link you want
$("#home-page-link").addClass("active")
}
Of course, you would do that with a switch and you would have to load the js file on ALL pages (that's why the use of the Header template is so important, since you would just need to include it once). Also, in the html "data-page" attribute, the "page" part can be anything, just remember to call it appropriately later.
Hope I helped.
To dynamically add a class, on page load, to the navigation item of the current page, consider:
Checking the current page url: $(location).attr('href') OR
$(location).attr('pathname')
Looping through anchor elements (a) of the navigation menu to
determine if any of the href attribute values match the current
page url with a conditional check using the .indexOf() method:
if(anchorEl.indexOf(currentPageUrl) >= 0)
If any do, add the required class, using the .addClass() method:
$(this).addClass('current');
Code Snippet Demonstration:
Note: Intended for the sake of demonstration
The code snippet embedded below uses specific urls to provide a working example and to demonstrate the intended functionality. Adjust accordingly to apply to a given production environment.
$(document).ready(function () {
var currentPageUrl = $(location).attr('href'), // store current page url in variable
anchorEl;
$('.menu a').each(function(){
anchorEl = $(this).attr('href'); // store href atribute of current anchor element in iteration
console.log('anchor link url:',anchorEl);
console.log('current url of window:',currentPageUrl);
if(anchorEl.indexOf(currentPageUrl) >= 0) { // if anchor element contains
$(this).addClass('current');
console.log('class "current" was added.');
}
});
});
/*
Note:
$(location).attr('href') = full absolute path (https://stacksnippets.net/js)
$(location).attr('pathname') = relative path (/js)
*/
.current {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="menu">
<ul class="list">
<li>
<a href="https://stacksnippets.net/foobar1">
<span>foobar #1</span>
</a>
</li>
<li>
<a href="https://stacksnippets.net/foobar2">
<span>foobar #2</span>
</a>
</li>
<li>
<a href="https://stacksnippets.net/js">
<span>This should be the <em>current</em> url</span>
</a>
</li>
</ul>
</div>
You should know e.preventDefault() will prevent default behavior of that object which called on it (redirect in this case). So you are preventing your application from redirect to that href you specified.
You can change your function code like this:
$(document).ready(function () {
$('.menu .list a').click(function(e) {
$('.menu li.active').removeClass('active');
var $parent = $(this).parent();
$parent.addClass('active');
e.preventDefault();
//Here is needed change
location.href = $(this).attr('href');
});
});
Edit 1:
So you can work like this approach:
1) Specify a class name for each li tag
2) Send the class name that must has active class after redirection and page load
3) Read the passed class name from url and add/remove to/from your li tags
So your html code will be as following:
<div class="menu">
<ul class="list">
<li class="header">MAIN NAVIGATION</li>
<li class="home active">
<a href="index.php">
<i class="material-icons">home</i>
<span>Home</span>
</a>
</li>
<li class="group">
<a href="test.php">
<i class="material-icons">group</i>
<span>Test</span>
</a>
</li>
<li class="people">
<a href="test2.php">
<i class="material-icons">people</i>
<span>Test2</span>
</a>
</li>
</ul>
</div>
If you need to script code according to this solution which I explained, so I will update my answer.
Edit 2:
You need to have below script codes in your file:
function setActiveClass() {
//Remove active class from all li tags
$('.menu li.active').removeClass('active');
//Find current url
var url = $(location).attr('href');
if (url.contains("activeClass")) {
//Find the index of active class in url
var start = url.indexOf("#activeClass");
//Add 6 unit to start index because of the longest class name is people which has 6 character
var end = start + 6;
//Fetch passed class name from url
var className = url.substring(start, end);
//Add active class corresponding to passed class name
if(className.contains("home"))
$(".home").addClass('active');
else if(className.contains("group"))
$(".group").addClass('active');
else
$(".people").addClass('active');
} else {
//Add active class for default mode (when we have not any redirect yet)
$("#defaultLiTag").addClass('active');
}
}
$(document).ready(function () {
//Call the function
setActiveClass();
$('.menu .list a').click(function(e) {
e.preventDefault();
var classNameOfParent = $(this).parent().attr('class');
var classNameToBePassedByUrl = "home";
if(classNameOfParent.contains("group"))
classNameToBePassedByUrl = "group";
else if(classNameOfParent.contains("people"))
classNameToBePassedByUrl = "people";
location.href = $(this).attr('href') + "#activeClass=" + classNameToBePassedByUrl;
});
});
i had the same problem after a lot of searching i could find this solution in this link i hope it could help you. Although you should remove class active and add class active to clicked navbar item ,you should use location.href to add active class when the new page reload.
https://santosh-shah.com/add-class-active-page-refresh-jquery/

active class is removed when page refreshes jQuery

I have a UL on my page which is acting as navigation. In my footer I have some jQuery code so when I click the link it removes the active class on the li and then places it on the current li that has been clicked. This works as I click however when the page reloads the active class goes back onto the previous li.
Here is my code
jQuery(document).ready(function () {
"use strict";
// Init Demo JS
Demo.init();
// Init Theme Core
Core.init();
$('.sidebar-menu > li').click(function (e) {
$(".active").removeClass("active");
$(this).addClass("active");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav sidebar-menu">
<li class="sidebar-label pt20">Menu</li>
<li class="active">
<a href="/dashboard">
<span class="glyphicon glyphicon-home"></span>
<span class="sidebar-title">Dashboard</span>
</a>
</li>
<li>
<a href="/fixtures">
<span class="fa fa-calendar"></span>
<span class="sidebar-title">Fixtures</span>
</a>
</li>
<li>
<a href="/players">
<span class="glyphicon glyphicon-book"></span>
<span class="sidebar-title">Players</span>
</a>
</li>
</ul>
Am I missing something in my jQuery to keep the class on the desired li?
Your JS is losing context with the refresh.
What you can do is run another function on load to check which url you're on, and set active state based on that. Something like this:
var setDefaultActive = function() {
var path = window.location.pathname;
var element = $(".sidebar-menu a[href='" + path + "']");
element.addClass("active");
}
setDefaultActive()
My solution is based on this link.
I needed nav pills to remain active after page refresh.
You can probably format this to fit your needs.
$(document).ready(function () {
// On page load
$('a[data-toggle="pill"]').on('show.bs.tab', function (e) {
// Get the id for the pill that was last shown and set it to local storage
localStorage.setItem('activeLink', $(e.currentTarget).attr('id'));
});
// After page loaded
// Get the id for the pill from local storage
var activeLink = localStorage.getItem('activeLink');
// If it's there, click it
if (activeLink) {
$(`#${activeLink}`).click();
}
});

JQuery each function toggle class

So i have some code like this
<ul>
<li>Example</li>
<li>Example</li>
<li>Example
>
<div class="Menu" style="display:none;">
Some thing
</div>
</li>
<li>Example
>
<div class="Menu" style="display:none;">
Some thing
</div>
</li>
<li>Example</li>
</ul>
Then i use a JS code like this
$("ul li .SplitCtrl").each(function(index) {
$(this).on("click", function(){
$(".Menu").fadeIn(800).slideDown(800);
});
});
But when i using this, all the ".Menu" element will be fade in :(
Please correct my code...
You need to target the specific .Menu that is the one next to this. ELse it will target all element with .Menu class. You can use jquery next
$("ul li .SplitCtrl").each(function(index) {
$(this).on("click", function(){ //changed here
$(this).next(".Menu").fadeIn(800).slideDown(800);
});
});
Check out this JSFIDDLE
jQuery doesn't know which element to open because there are no id's assigned to the menu items. So it opens everything in the .SplitCtrl class because it doesn't know any better. If you assign some id's to the elements, then it will know what to open and when. Using your code so as to minimize modifications, the following will work for you. Note the addition of id's to both of the .SplitCtrl items and the .Menu items, and using the click function and passing in the id of the item that the click originated from. If you embed further elements, this will still work in the case that it isn't the next element following your class, or if you want it to trigger other items on the page in addition to the menu items.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
</head>
<body>
<ul>
<li>Example</li>
<li>Example</li>
<li>Example
>
<div class="Menu" id="menu1" style="display:none;">
Some thing
</div>
</li>
<li>Example
>
<div class="Menu" id="menu2" style="display:none;">
Some thing
</div>
</li>
<li>Example</li>
</ul>
<div id="surprise1" style="display:none;">Now I'm open too!</div>
</body>
</html>
<script>
$(document).ready(function() {
$("ul li .SplitCtrl").click(function(event){
var item = '#menu' + event.target.id;
var surprise = '#surprise' + event.target.id;
$(item).fadeIn(800).slideDown(800); // open the menu item
$(surprise).fadeIn(800).slideDown(800); // open another element
});
});
</script>
In order to toggle the items, you can add something that first hides everything that's open and then makes the newly selected item visible:
//...same code as above to this point
<div id="surprise1" class="Surprise" style="display:none;">Now I'm open too!</div>
</body>
</html>
<script>
$(document).ready(function() {
$("ul li .SplitCtrl").click(function(event){
var item = '#menu' + event.target.id;
var surprise = '#surprise' + event.target.id;
$(".Menu").fadeOut(100); // Hide all items of class .Menu
$(".Surprise").fadeOut(100); // Hide other items of class .Surprise
$(item).fadeIn(800).slideDown(800); // open the menu item
$(surprise).fadeIn(800).slideDown(800); // open another element
});
});
</script>
So now, all the .Menu items in that class are toggled off before the new one is displayed (even though only one displays at a time). Note the added class for "Surprise" to be able to hide all the external elements as well. There are lots of ways to toggle items so this is just one way you could accomplish it.

Display active tab's name in an span

I would like to show the active tab's name (text) in a span .active-class.
Example:
<ul class="tabs">
<li class="feinleinen active">feinleinen</li>
<li class="glatt">glatt</li>
</ul >
<span class="active-class">*Active_Tab_Name_Here (i.e. feinleinen) *</span>
What you want is either to have a click event each time a link is clicked and put the text in there?
Javascript:
function changeSpan(var newText){
document.getElementByClassName('active-class').innterHTML(newText);
}
When the above you need to initialise the function. this can be done in the anchor within the list item.
<li><a href='#' onclick='changeSpan("new item name!");'>
Don't forget the hash (#) within the href! This stops the default action, in layman's terms.
With jQuery this can be a bit simpler
$('a','ul.tabs>li').click(function(){//a classname would be a better selector
$('.active-class').appendTo($(this).innerHTML());//can also use $(this).text();
return false;//also stops default action
});
FIDDLE:
HTML
<ul class="tabs">
<li class="feinleinen active">feinleinen
</li>
<li class="glatt">glatt
</li>
</ul>
<span class="active-class">active tab name here</span>
SCRIPT
$('.active-class').text($('.tabs .active').find('a').text());
I guess you want this on click , therefore bit updation to my above code here :-
$('.tabs a').click(function () {
$('.tabs li').removeClass('active');
$(this).parent('li').addClass('active');
$('.active-class').text($(this).text());
});
fiddle: http://jsfiddle.net/x97g8sc7/
$(".active-class").text($(".tabs .active").text());

How to change content of multiple divs on click

I am attempting to figure out how to change the content of two different, non-contiguous divs, when a link is clicked. I have some draft HTML and Javascript, and I suspect missing CSS might be the key to make this work.
Here is the HTML:
<ul id="tabs">
<li>Link 1
</li>
<li>Link 2
</li>
</ul>
<div id="tabs-container">
<div id="content1">Content for link 1. Should display only when Link 1 is clicked.</div>
<div id="content2">Content for link 2. Should display only when Link 2 is clicked.</div>
</div>
<p>Unrelated text is here. Text in this area is static and should display at all times.</p>
<div id="tabs-container-2">
<div id="content1-2">Additional content for link 1. Should display only when Link 1 is clicked.</div>
<div id="content2-2">Additional content for link 2. Should display only when Link 2 is clicked.</div>
</div>
Here is the Javascript:
$(function () {
$('#tabs-container .tabs').hide().eq(0).show();
$('#tabs-container-2 .tabs').hide().eq(0).show();
$('#tabs li').click(function () {
num = $('#tabs li').index(this);
$('#tabs-container .tabs').hide().eq(num).show();
$('#tabs-container-2 .tabs').hide().eq(num).show();
});
});
I am a novice at CSS and Javascript. In fact, I deleted my attempt at CSS because it was so poor. Here is the partial jsfiddle:
http://jsfiddle.net/Fbx_Steve/GbaMx/14/
Hope someone can help. Am I even on the right track?
Try,
$(function () {
$('#tabs-container div').hide().eq(0).show();
$('#tabs-container-2 div').hide().eq(0).show();
$('#tabs li').click(function () {
$('#tabs-container div').hide()
$('#tabs-container-2 div').hide()
num = $('#tabs li').index(this);
$('#tabs-container div').hide().eq(num).show();
$('#tabs-container-2 div').hide().eq(num).show();
});
});
DEMO
Is this what you're after?
http://jsfiddle.net/GbaMx/16/
I added an id to each link, and when the link is clicked the repective content is toggled.
I grouped them into 2 classes for .c1 .c2 for content 1 and content 2
Updates JSFiddle: http://jsfiddle.net/GbaMx/18/
Your Javascript was totally fine. However, you were trying to reference the tabs class, when there were no such classes defined. Thus, I had to update the HTML with ids of content-x to have a class of tabs.
Try this
JQUERY CODE:
$(function () {
$('#tabs-container div').hide();
$('#tabs-container-2 div').hide();
$('#tabs li a').on('click', function (event) {
event.preventDefault();
num = $(this).parent().index();
$('#tabs-container div').eq(num).slideToggle();
$('#tabs-container-2 div').eq(num).slideToggle();
});
});
LIVE DEMO:
http://jsfiddle.net/dreamweiver/GbaMx/22/
There were few things missing in your code, so i have just tuned it a bit.
Happy Coding :)
Try this:
html
<ul id="tabs">
<li><a id="link1" href="#">Link 1</a>
</li>
<li><a id="link2" href="#">Link 2</a>
</li>
</ul>
<div id="tabs-container">
<div id="content1" class="contents">Content for link 1. Should display only when Link 1 is clicked.</div>
<div id="content2" class="contents">Content for link 2. Should display only when Link 2 is clicked.</div>
</div>
<p>Unrelated text is here. Text in this area is static and should display at all times.</p>
<div id="tabs-container-2">
<div id="content1-2" class="contents">Additional content for link 1. Should display only when Link 1 is clicked.</div>
<div id="content2-2" class="contents">Additional content for link 2. Should display only when Link 2 is clicked.</div>
</div>
javascript
$( document ).ready(function() {
// hide tabs
$('.contents').hide();
$('#link1').click( function() {
$('#content1,#content1-2').show();
return false;
});
$('#link2').click( function() {
$('#content2,#content2-2').show();
return false;
});
});
see demo: http://jsfiddle.net/Magicianred/BV2kS/1/
Enjoy your code
It works you're only missing a class "tabs" in the content divs:
<ul id="tabs">
<li>Link 1
</li>
<li>Link 2
</li>
</ul>
<div id="tabs-container">
<div id="content1" class="tabs">Content for link 1. Should display only when Link 1 is clicked.</div>
<div id="content2" class="tabs">Content for link 2. Should display only when Link 2 is clicked.</div>
</div>
<p>Unrelated text is here. Text in this area is static and should display at all times.</p>
<div id="tabs-container-2">
<div id="content1-2" class="tabs">Additional content for link 1. Should display only when Link 1 is clicked.</div>
<div id="content2-2" class="tabs">Additional content for link 2. Should display only when Link 2 is clicked.</div>
</div>
DEMO

Categories

Resources