Make jquery toggle work with dynamic content - javascript

I've the following code on my website: http://jsfiddle.net/dJLK3/1/
As you can see, it works just fine.
The problem is: those divs and link triggers come from a database. Today I have 1, tomorrow it can be 10...
I can not figure out how to convert it and make it work without needing to right lot's of codes like link1, link2, link3, link4, link5 and so on...
Anyone? :)

Use data attr and jQuery.data. reference
Update:
according to this comment.
html
<div class="menu">
Link1
Link2
</div>
<div id="div1" class="slide"></div>
<div id="div2" class="slide"></div>​
js
$('.menu').on('click', '.link', function(){
var id = $(this).data('slideContent');
$('.slide').not('#' + id).slideUp(function() {
$('#' + id).slideToggle();
});
});
​css
.slide {
display: none;
height: 100px;
width: 100px;
position: fixed;
top: 30px;
}
demo
References:
slideUp - http://api.jquery.com/slideUp/
slideToggle - http://api.jquery.com/slideToggle/

Update
Here's a fiddle with a possible answer - FIDDLE - Update - With new requirements
Code posted here for clarification
<div id='link_collection'>
Link1
Link2
</div>
<div id='div_collection'>
<div class='div current'></div>
<div class='div'></div>
</div>
$(document).ready(function() {
$('#link_collection').on('click', '.link', function() {
var divCollection = $('#div_collection .div'),
index = $(this).index(), hasClickedMeAgain,
current = divCollection.filter('.current');
hasClickedMeAgain = current.index() === index;
if (hasClickedMeAgain){
current.slideToggle();
return false;
}
current.slideUp(function() {
$(this).removeClass('current');
divCollection.eq(index).addClass('current').slideToggle();
});
})
});
This way, you don't need to keep tag of anything. Just keep inserting the div and link in the order in which they arrive, and the code then handles itself. All the best.

Will this work for you? Use the same class attribute for all of them. And have the following code on document.ready() to assign on click events:
HTML:
<a class="ui-link-option">Link 1</a>
<a class="ui-link-option">Link 2</a>
<div class="ui-link-option-text">Text Here 1</div>
<div class="ui-link-option-text">Text Here 2</div>
Javascript:
$("a.ui-link-option").each(
function (index) {
var $this = $(this);
$this.data("index", index);
$this.bind("click", function(e) {
var $this = $(this);
var linkIndex = $this.data("index");
$("div.ui-link-option-text").each(
function (index) {
if (index == linkIndex) {
$(this).slideToggle();
} else {
$(this).hide();
}
}
);
});
}
);

Related

Show specific div when atag is click. And hide other divs

I'm faily new to jquery and coding in general. I'm having a few troubles with this.
What i want is for when the page loads, the 'Vlogging' link is active and 'Details 1' is shown. Then when you click on either 'Filmmaking' or 'Beme'... 'Details 2 or 3 is shown and which ever one was there goes away.
I have everything set up right so far just need to get it to where when you click on one of the other links the correct 'Details' text shows itself.
Thank you so much and i have it in a fiddle right now!
http://jsfiddle.net/t1huc43d/
Here is the code than needs tuned:
$(function() {
$("togglediv1").click(function() {
$("#togglediv1").removeClass("display-start");
$("li").removeClass("display");
$(this).addClass("display");
});
});
This code will save you a lot of time. I added a custom attribute called "data". This attribute is used to tie the link to the tab you wish to display. This code will make it a lot easier to add additional tabs and etc. Look at the bottom for the changed HTML and JavaScript.
<div id="wrap">
<ul id="divtoggle">
<li><a class="link" data="1">Vlogging</a></li>
<li><a class="link" data="2"> Filmmaking</a></li>
<li><a class="link" data="3"> Beme</a></li>
</ul>
<div class="text">
<div class="tab" data="1">Details 1</div>
<div class="tab" data="2">Details 2</div>
<div class="tab" data="3">Details 3</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script>
$(function () {
$(".link").click(function () {
$(".active").removeClass("active");
$(this).addClass("active");
dataAttr = $(this).attr("data");
$(".tab").hide();
$(".tab[data="+dataAttr+"]").show();
});
$(".link:first").click();
});
</script>
$(function() {
$("#togglediv1").click(function() {
$("#one").removeClass("display");
$("#one").addClass("display-start");
$("#two").removeClass("display-start");
$("#two").addClass("display");
$("#three").removeClass("display-start");
$("#three").addClass("display");
});
});
$(function() {
$("#togglediv2").click(function() {
$("#one").removeClass("display-start");
$("#one").addClass("display");
$("#two").removeClass("display");
$("#two").addClass("display-start");
$("#three").addClass("display");
$("#three").removeClass("display-start");
});
});
...
Updated jsfiddle: http://jsfiddle.net/t1huc43d/3/
Since your ids aren't that conducive in tracking what is clicked and what isn't, I decided to just use this to find what you've clicked in correspondence with the details.
Your updated javascript:
$(function() {
$("li").click(function() {
$("#togglediv1").removeClass("active-start");
$("li").removeClass("active");
$(this).addClass("active");
let temp = $("#divtoggle").children();
var index;
for (let i = 0; i < temp.length; i++)
{
if (this == temp[i] )
{
index = i;
break;
}
}
$(".display-start").addClass("display");
$(".display-start").removeClass("display-start");
let text_children = $(".text").children()
let the_child = text_children[index];
$(text_children[index]).addClass("display-start");
$(text_children[index]).removeClass("display");
});
});
JQuery actually has some components to help you out, but to me, the shortest and CLEANEST way of doing this is the following:
The first thing I'd do is set an id of each of the titles, incrementing them by 1. Then, I'd do the same for the details like so:
<div id="wrap">
<ul id="divtoggle">
<li><a class="title" id="title-1">Vlogging</a></li>
<li><a class="title" id="title-2"> Filmmaking</a></li>
<li><a class="title" id="title-3"> Beme</a></li>
</ul>
<div class="text">
<div class='display' id="detail-1">Details 1</div>
<div class='display' id="detail-2">Details 2</div>
<div class='display' id="detail-3">Details 3</div>
</div>
</div>
After that, the JQuery is pretty simple. Setup a click event on the class title. The first thing to do is to parse the id of the clicked title. Once you have that, target the related detail and show it:
$(document).ready(function() {
$(".title").click(function() {
//*** get id
var id = $(this).attr("id").split("-")[1];
if (typeof id != "undefined"){
//*** hide other descriptions and show yours
$(".display").hide();
$("#detail-" + id).show();
}
});
});
DEMO: http://jsbin.com/volikofihe/edit?html,js,console,output
Here you go. Simplified your CSS a little. Toggling a .active class on the top links, and a .display class on the text divs. When you click on a link, the code uses the $.index() of that link in the list as the index of the text div to show. So if you click on the 2nd link, it will show the 2nd text box.
$(function() {
$toggleLinks = $('#divtoggle a'),
$displays = $('.text div');
$toggleLinks.on('click', function(e) {
e.preventDefault();
$toggleLinks.removeClass('active');
$(this).addClass('active');
$displays.removeClass('display');
$displays.eq($(this).closest('li').index()).addClass('display');
});
});
li {
color: grey;
font: effra;
font-weight: bold;
}
a:hover {
color: #aaaaaa;
cursor: pointer;
}
.active {
color: orange;
}
.text div {
display: none;
}
.text .display {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrap">
<ul id="divtoggle">
<li><a class="active">Vlogging</a></li>
<li><a>Filmmaking</a></li>
<li><a>Beme</a></li>
</ul>
<div class="text">
<div class='display'>Details 1</div>
<div>Details 2</div>
<div>Details 3</div>
</div>
</div>
Preserved as much of your existing code as possible. Updated fiddle.
I added a data-controls custom attribute to each of your li elements so as to associate them to each of the corresponding data divs:
<li data-controls="one"><a id="togglediv1" class="active-start">Vlogging</a></li>
<li data-controls="two"><a id="togglediv2"> Filmmaking</a></li>
<li data-controls="three"><a id="togglediv3"> Beme</a></li>
Then I updated the JavaScript to remove and add the classes, as needed.

jQuery page fade script

I'm attempting to create a script that, when I click a nav-link, checks what class is attached to that specific link, then hides the current page and displays the page that also contains that specific class.
This script currently switches between 2 pages rather than checking for a page with a class, but I'm sure it'll be simple to add that later (1 line of code).
(function () {
pages = ["home", "about", "portfolio", "misc", "inquire"];
//request = window.location.hash.substring(1);
//Finding page corresponding to clicked link
function SetRequest (link, pages)
{
lookingFor = ".home";
for (var i in pages)
{
if (link.hasClass(("." + pages[i]).toString()))
{
lookingFor = pages[i];
}
}
return ("." + lookingFor).toString();
}
//Hiding all other pages, showing page needed
function ShowCurrentPage (page, pages, lookingFor)
{
for (var i in pages)
{
if (page.hasClass(lookingFor))
{
$(".page.current").animate({opacity: 0});
$(".page.current").removeClass("current");
$(".page").animate({opacity: 1});
$(".page").addClass("current");
}
}
}
$(".nav-link a").click(function(){
ShowCurrentPage($(this), pages, SetRequest($(this), pages));
});
})();
You don't need to make a loop. Just do something like this:
function switchPage(lookingFor)
{
var lookingForDom = $('' + lookingFor); // I assume that lookingFor carries full selector either id or css based
if (lookingForDom.length > 0) // We've found one
{
$(".page.current").removeClass("current").animate({opacity: 0});
lookingForDom.addClass("current").animate({opacity: 1});
}
}
There's also easy way to obtain needed page name, just keep it inside some attribute of link that's beeing clicked and retrive it. Href is designed place for such things (but you need to use id on page-div then). So js would be:
$('.nav-link a').click(function(){ switchPage($(this).attr('href')); });
Also remember to registrate your events either with inside $(document).ready function like so:
$(document).ready(function()
{
$(".nav-link a").click(...);
});
Full example:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript">
function switchPage(lookingFor)
{
var lookingForDom = $('' + lookingFor); // I assume that lookingFor carries full selector either id or css based
if (lookingForDom.length > 0) // We've found one
{
$(".page.current").removeClass("current").animate({opacity: 0});
lookingForDom.addClass("current").animate({opacity: 1});
}
}
$(document).ready(function()
{
// Initial switch to hide other pages
$('.page').css({ opacity: 0 });
switchPage('#pageA');
$('.links a').click(function(){ switchPage($(this).attr('href')); });
});
</script>
</head>
<body>
<div id="pageA" class="page">I'm page A</div>
<div id="pageB" class="page">I'm page B</div>
<div id="pageC" class="page">I'm page C</div>
<ul class="links">
<li>Go to page A</li>
<li>Go to page B</li>
<li>Go to page C</li>
</ul>
</body>
</html>
Here's a really simple code that does the trick : http://codepen.io/anon/pen/advjeN
html :
<nav class="nav-link">
<a class="aa" href="#">FIRST LINK</a>
<a class="bb" href="#">SECOND LINK</a>
</nav>
<div class="pages">
<div class="aa page red"></div>
<div class="bb page blue hide"></div>
</div>
CSS :
.page{
height: 200px;
width: 200px;
margin : 20px;
display: inline-block;
}
.red{ background-color: red;}
.blue{background-color: blue;}
.hide{ display: none;}
and jquery :
(function () {
$(".nav-link a").click(function(){
var myclass = '.' + $(this).attr('class');
$('.pages').children().hide();
$(myclass).fadeIn();
});
})();
If put them all in a " pages " div so you can hide them all easely, but if they all at least one class that's the same for all you can simply do $(myclass).hide();

How to let url with anchor tags show a hidden div

How can I show an hidden div when using anchors that are linked with their linked a tag that is in the hidden div. If you know what I mean..
See the fiddle: http://jsfiddle.net/2sjdeucf/
I mean when visiting the url site.com/#1 Then I want the div shown, so the same like when you press on the button named 1.
Html
1
2
3
<br><br><br>
<div id="clicks">
<a class="click" id="showInfo" data-target=".1"><button>1</button></a>
<a class="click" id="showDataInput" data-target=".2"><button>2</button></a>
<a class="click" id="showHistory" data-target=".3"><button>3</button></a>
</div>
<div class="1 target" style="display: none;"><a name="1">1</a></div>
<div class="2 target" style="display: none;"><a name="1">2</a></div>
<div class="3 target" style="display: none;"><a name="1">3</a></div>
<div id="text">"I WANT THIS DIV GONE EVERYTIME I LET DIV 1, 2 OR 3 SHOW BY CLICKING THE BUTTONS. BUT SHOW UP AGAIN WHEN 1, 2 OR 3 IS NOT SHOWING/SELECTED"</div>
Javascript
var $targets = $('.target');
$('#clicks .click').click(function () {
var $target = $($(this).data('target')).toggle();
$targets.not($target).hide();
$('#text').css('display', $('div.target:visible').length ? 'none':'')
});
Thank you
You need get initial hash and subscribe for hash changes via onhashchange, so your code becomes (I slightly modified your code, final version is, tested locally in Chrome):
function doToggle(num) {
var target = $('div.target' + num);
target.toggle();
$('.target').not(target).hide();
$('#text').css('display', $('div.target:visible').length ? 'none' : '')
}
$('#clicks .click').click(function () {
var num = $(this).data('target');
doToggle(num);
});
function handleHash() {
doToggle("." + location.hash.substring(1));
}
window.onhashchange = handleHash;
$(handleHash);
You can use window.location.hash to detect the values after the hash.
exp:
var val=window.location.hash.substring(1);//substring to remove the #
if(val.length!==0){
$(".target").hide();
$("."+val).show();
}
I'm not sure to understand well but I tried to stick to your instruction within your .text div, so this code shoud do the trick :
function showHideDiv() {
$('.target').each(function(){
if($(this).is(':visible')){
$('#text').hide();
}
});
}
$(document).on('load', showHideDiv);
$('.click').on('click', showHideDiv);
$('#clicks .click').click(function () {
$('div.target' + $(this).data('target')).toggle();
$('#text').css('display', $('div.target:visible').length ? 'none':'')
});
Working JSFiddle
You can use :target pseudoclass and hash based links (browser support)
div {
display: none;
}
div:target {
display: block;
}
jsfiddle

Hashchange to show divs

I have a number of divs on my page, which are hidden by default. Jobs can be selected by links (to "#job8, for example). I'm trying to use hashchange in my script to check the URL for the specific hash and then to display the appropriate div.
This is an example div
<div class="job-details" id="job8" data-jobid="8">
<p>Job 8</p>
</div>
This is my script.
$(document).ready(function(){
$('.job-details').hide();
});
$(window).bind('hashchange', function() {
if (location.hash.substring(0,4) == "#job"){
var jobID = location.hash.substring(0);
$('.job-details').hide();
$('[data-jobid="' + jobID + '"]').show();
}
});
Your line:
var jobID = location.hash.substring(0);
Assigns '#' to jobID. Presumably that isn't what you want? Probably you want:
var jobID = location.hash.substring(4);
Do you must use hashchange? If not try example below, here's a FIDDLE
<nav>
Job 1
Job 2
Job 3
</nav>
<div class="job-details" id="job1">
<p>Job 1</p>
</div>
<div class="job-details" id="job2">
<p>Job 2</p>
</div>
<div class="job-details" id="job3">
<p>Job 3</p>
</div>
.job-details {
position: absolute;
width: 400px;
height: 200px;
border: 1px solid #ddd;
display: none;
}
$(function() {
$('nav a').click(function() {
$('.job-details').fadeOut(400);
$('#'+$(this).data('rel')).fadeIn(400);
});
});
Palpatim is right, this will do the job:
var jobID = location.hash.substring(4);
Here is a jsfiddle: http://jsfiddle.net/Cc9dL/
Jquery hashchange
Your function working correctly after making some changes in get/set jobid.
Here location.hash gives you #job8, so you can directly use this as id selector.
$(window).bind('hashchange', function() {
if (location.hash.substring(0,4) == "#job"){
var jobID = location.hash;
$('.job-details').hide();
$(jobID).show();
}
});
Try in fiddle
Updated :
$(window).bind('hashchange', function() {
if (location.hash.substring(0,4) == "#job"){
var jobID = location.hash.substring(4);
$('.job-details').hide();
$('div[data-jobid="' + jobID + '"]').show();
}
});
Try in Fiddle

How can I separate these divs in the javascript?

I have this div scrolling script:
$(document).ready(function () {
$('.tab-box').each(function () {
var top = 0;
var $tabbox = $(this);
var height = $tabbox.height();
$(this).find('.tab').each(function () {
var shift = top;
$(this).click(function () {
$tabbox.find('.items').animate({
marginTop: shift + 'px'
});
$tabbox.find('.tab').removeClass('active');
$(this).addClass('active');
});
top -= height;
});
$(this).find('.tab:eq(0)').addClass('active');
});
});
If I understand it correctly it gets every divs working only within the div "tab-box".
http://jsfiddle.net/9SfEH/5/
What I want to change is that I separate the "tabs" from the main tab-box div, but make them still controll the "items".
http://jsfiddle.net/w65Dn/1/
I was trying for a simple solution buuut couldn't come up with one by myself.
Thanks everyone in advance :)
The problem was that in the original code, it was looking for the tab clickables using $(this).find(".tab"), but the .tabs were no longer inside of the .tab-box. So, if you just search globally, with $(".tab"), it works.
Note that you can no longer have more than one tab box, because it is searching globally for the .tabs. You could use something like javaCity's solution (i.e. wrapping everything in another div) to fix this.
You were looking for .tabs inside the tab-box which does not exist. So how about creating a div outside of .tabs which also encloses tab-box?
http://jsfiddle.net/3D8we/
HTML:
<div class="enclosingDiv">
<div class="tabs">
<div class="tab">1</div>
<div class="tab">2</div>
<div class="tab">3</div>
</div>
<div class="tab-box">
<div class="items">
<div class="item" style="background: #cbe86b;"></div>
<div class="item" style="background: #f2e9e1;"></div>
<div class="item" style="background: #1c140d;"> </div>
</div>
</div>
</div>
JS:
$(document).ready(function () {
$('.tab-box').each(function () {
var top = 0;
var $tabbox = $(this);
var height = $tabbox.height();
$('.enclosingDiv').find('.tab').each(function () {
var shift = top;
$(this).click(function () {
$tabbox.find('.items').animate({
marginTop: shift + 'px'
});
$tabbox.find('.tab').removeClass('active');
$(this).addClass('active');
});
top -= height;
});
$(this).find('.tab:eq(0)').addClass('active');
});
});
On line 7, change the selector from this to .tabs
$(this).find('.tab') becomes $(.tabs).find('.tab')
as seen here: jsfiddle example

Categories