How do I navigate through 5 diffrent divs with a single button - javascript

I have 5 divs with ids; #one, #two, #three, #four and #five. I have a navigation menu linked to each div like this;
<ul>
<li>ONE</li>
<li>TWO</li>
<li>THREE</li>
<li>FOUR</li>
<li>FIVE</li>
</ul>
where each div represents a single page on my website, the the ul works perfectly but is there a way can have a single button like a "next" button that will go to page 2 when clicked and when clicked again will go to page 3 and so on... preferably using some sort of jquery or even javascript

I will respond based on the assumption that this is a purely theoretical exercise and given only the information you have provided. Please note that there are better ways of doing what you ask, as alluded to in the first comment.
However, assuming that you have, as you say, got an identical navigation menu on each page, and that, as you say, each div is on a separate web page, I suggest that you could continue your existing methodology and place a "Previous" and "Next" button on each page, and hook it up manually to the correct page.
For example, on page with #one, you would have buttons that might look like this:
Previous<!-- does nothing.. because you're on the first page -->
Next<!-- goes to page 2 -->
On subsequent pages, you would hard-code the links to the other pages, and on the final page you would blank out the Next button in a similar way to the way the Previous button was blanked out above.
Having said that. You could put all Divs in the same web page, and show/hide them using JavaScript and CSS. For example:
<div id="one" style="display:block;">Div 1</div>
<div id="two" style="display:none;">Div 2</div>
<div id="three" style="display:none;">Div 3</div>
<script type="text/javascript">
function focusOnAParticularDiv(divId)
{
switch(divId)
{
case 'one':
document.getElementById('two').style.display = 'none';
document.getElementById('three').style.display = 'none';
document.getElementById('one').style.display = 'block';
break;
case 'two':
// etc...
break;
case 'three':
// etc...
break;
}
}
</script>
You could then call that JS function on the onClick event of the next/previous buttons.
<input type="button" text="Next" onclick="focusOnAParticularDiv('two');" />
Or something like that...
You could choose to use JQuery's shortcuts if you wish.
Alternatively, you could use an ASP.NET Wizard control :)
As mentioned in some other comments, you can also create the div the user is after at the server side, which would avoid sending ALL the divs to the client on the first request (this would speed up the user's first request). This would mean you do not need any JavaScript, but would also mean that each time the user clicked a button the page would be destroyed and recreated on the server and sent back to the client (a full round-trip), which would have an impact on the number of hits your server gets.
It really depends what you're after and what your criteria are; hence why I have tried to cover several bases for you.

JQuery has a trigger event. You can trigger click event on your links when a user clicks next or previous button.

Something like
$(document).ready(function() {
var links = [];
var cnt=0;
$("ul li a").each(function(i) {
links[i] = this.href;
});
$("#next").click(function(e) {
cnt++;
if (cnt>=links.length) cnt=0;
location.hash=links[cnt].split("#")[1];
e.preventDefault();
});
});

Related

How to change add and remove tags with JS in django template

I have a quiz Django app which consists of two parts. One is showing 10 sentences with their audio to remember, one per page, and the second is asking questions for the same set of sentences. First part was set up with js function which creates pagination in my html the following way:
my_template.html
<button id="prev">prev</button>
<button id="next">next</button>
<ul class="list-articles" id="dd">
</ul>
<script>
var my_objects = `{{ my_objects|safe}}:` #list of items from my view function
function paginate(action) {
console.log(action)
if (action ==='next') {
page_number++;
}
else{
page_number--;
}
const audio = document.createElement('audio');
audio.src =`/media/${my_objects[page_number].fields.audio}`;
$('#dd').empty();
$('#dd').append('<li><h1>'+ my_objects[page_number].fields['content'] +'</h1></li>');
$('#dd').append(audio);
$('#page_number').val(page_number);
}
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('#next').onclick = function() {
paginate('next'); #same goes for 'prev' button.
}
})
</script>
Now when the user paginated through all the sentences I want to show the continue button and if the user clicks it, start the second part. The second part has absolutely same page except I need to hide content of my objects and leave only audio or vice versa and add textarea tag for the user's input. After that I need to loop over my objects again - now in the form of questions. I need to do that without page re-rendering so I don't need to store the list of objects or query the DB again.
I tried to make it with tag disabling and activating the second loop after the first ends but that looks quite messy and I suppose there is a smarter way of doing that. I'm not a JS developer so any help would be appreciated!
Thanks for all who viewed and not commented! I found the answer myself. Just need to add JS functions which will empty the main tag and refill with necessary field.
Details: By accessing elements of DOM in the following way you can empty any element on a web page. For example, if we have a div like:
<div class= id="maindiv">
<h2> Hello, world! </h2>
</div>
We can empty and refill it with a new header:
var container = document.getElementById("maindiv");
container.empty();
new_header = document.createElement('h2');
new_header.innerHTML = 'Hello, brave new world!'
container.append(new_header);
Same applies to the whole web-page. The only thing is, if it is too big, you probably going to be tired of manipulating the DOM each time. So, you may want to check out some frameworks like React to make it easier .

Change elements/classes in/with jquery

I'm new in jQuery and used it right now for a navigation, that slides in and out in mobile or small views. That works fine and correct, but I'm using a plus-icon to open a submenu, that changes into a minus-icon, when the submenu is opened.
But it doesn't change back into the plus-icon, when the submenu is closed.
The code is the following:
$(document).ready(function() {
$('<span class="menu-expander"><span class="plusicon horizontal"></span><span class="plusicon vertical"></span></span>').insertAfter('.level_2');
$('#menu-toggle').click(function() {
$(this).next('#navigation-main').slideToggle();
});
$('.menu-expander').click(function() {
$(this).prev('.level_2').slideToggle();
$(this).children('span.plusicon.vertical').toggleClass('plusicon vertical');
});
});
I think the "interesting" part might be the second function, the first is still for a hamburger-icon, that opens the navigation, that works (okay, it doesn't show a sliding animation, what the second one do... no idea, why it don't works...).
So the second part is for the plus. When I click on the plus, the submenu slides in and the plus changes to the minus, but when I click back to the the minus it doesn't change back to the plus.
Has somebody any idea why it doesn't work or can explain me, how I can do it work?
Regards,
Markus
The problem is that your selector is trying to find a span with both plusicon and vertical classes but after the first call to this:
$(this).children('span.plusicon.vertical').toggleClass('plusicon vertical');
wich removes said classes, it is not able to find your target span.
To work around this you could assign an id (iconId on the next example) or another class to your icon so it can be allways found
$('<span class="menu-expander"><span id="iconId" class="plusicon horizontal"></span><span class="plusicon vertical"></span></span>').insertAfter('.level_2');
...
$('.menu-expander').click(function() {
$(this).prev('.level_2').slideToggle();
$(this).children('#iconId').toggleClass('plusicon vertical');
});
Do this :
$('.menu-expander').click(function() {
$(this).prev('.level_2').slideToggle();
var $icon = $(this).children('#ID OF ELEMENT'); // Would be easier to add an ID to your element whcih you want to alter - limits the error possibilties :)
if($icon.hasClass("CLASS YOU WANT TO GET RID OF"){
$icon.removeClass("CLASS YOU WANT TO GET RID OF");
$icon.addClass("THE CLASS YOU NEED");
else{
$icon.addClass("THE CLASS YOU WANT TO ADD");
}
});
I am at work now so pardon any typing errors.
You basically need to check whether the class that changes the icon to a MINUS symbol is still active - if so you change it back.
I hope it will help.
Points:
to find element good to use find();
better toggle 1 class to show hide element like "show" in example;
With elements inserted with js code better use .on() (for future);
$(document).ready(function() {
$('<span class="menu-expander"><span class="plusicon horizontal">horizontal</span><span class="plusicon vertical show">vertical</span></span>').insertAfter('.level_2');
$('#menu-toggle').click(function() {
$('#navigation-main').slideToggle();
});
$('.menu-expander').click(function() {
$(this).prev('.level_2').slideToggle();
$(this).find('.plusicon').toggleClass('show');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style>
.plusicon {display:none}
.show {display:block!important}
</style>
<ul>
<li id="menu-toggle" class="level_2">Toggle</li>
</ul>
<ul id="navigation-main">
<li>test</li>
</ul>

JQuery Cookies with dynamic div ID's

I hope you guys can give me a push in the right direction as this problem has been eating me up all day now..
What I'm basicly trying to accomplish is this. I have several div's on a page that can be collapsed independently from eachother with the use of a button. Every div has it's own specific ID, generated with a string of static text, and a numeric value based on a auto-incremented database-value. This ensures I never have two div's with the same ID on one page. To target each specific div with Javascript (jQuery) I use the following code:
http://jsfiddle.net/LU7QA/0/
This works really well and does what it's supposed to do. Only there is one problem. On every page frefresh, every div that was opened is closed. Everything resets, and that's why I want to use JQuery Cookies in this construction. Only problem is, I know how it works, but I can't get it to work in this specific construction as it has to deal with a completely unique ID every time and needs to store the values of that particular ID.
As seen here: http://jsfiddle.net/LU7QA/1/
I tried to fiddle around with it but I can't seem to get it working properly and I'm starting to lose my sight on the problem..
<div>
<button class="button_slide" value="1">Show hide</button>
</div>
<div id="slidingDiv_1" class="slidingDiv">Stuff</div>
<div>
<button class="button_slide" value="2">Show hide</button>
</div>
<div id="slidingDiv_2" class="slidingDiv">Stuff</div>
function initMenu() {
$(".slidingDiv").hide();
// Toggle Field
$(".button_slide").click(function(){
//alert($(this).val()); debugging purposes
var sliding_id = $(this).val();
div_sliding_id = '#slidingDiv_'+sliding_id;
$(div_sliding_id).next().slideToggle('slow', function() {
$.cookie(div_sliding_id, $(this).is(':hidden') ? "closed" : "open");
return false;
});
});
$('.button_slide').each(function() {
var sliding_id = $(this).val();
div_sliding_id = '#slidingDiv_'+sliding_id;
if ($.cookie(div_sliding_id) == "open") $(this).next().show();
});
}
jQuery(document).ready(function() {initMenu();});
May you have missed a dot on the last *button_slide* declaration?
Btw, look at https://code.google.com/p/sessionstorage/

calling a function on one page from a link on another page

I have an html page (django) that contains several divs(each displaying different data) and one div that has navigation links. I'll call this my main page. I have an external .js file (jQuery) that reveals one display div on the main page and simultaneously hides all of the others (except the navigation div) based on which nav link is chosen.
$(function(){
$("#sl_sectorbr").click(function showSectorMini(){
$(".minimenu").hide();
$(".minimenu > *").hide();
$("#sector_mini").fadeIn("slow");
$("#sector_mini > *").fadeIn("slow");
});
All of this works fine. My question is, if I want to place "navigation links" on a second html page; that when clicked would both load my main page AND call/execute a specific function like
"showSectorMini()" just as if it were clicked from the main page itself — how would I write that code? I'd really appreciate any help I could get.
Oh.... existing class is...
}
/* ------- Interaction Containers Class -------- */
.interactContainers {
padding:8px;
border:#999 1px solid;
display:none;
}
But you probably already knew that!
Steve
Gentlemen...
This is exactly what I need and mine is less complicated than this. Just one div to open with the script. I am a javascript incompetent person so far. :(
How do you dumb this down to my needs?
Seperate page link is:
Email</div>
Page it goes to code is:
function toggleSlideBox(x) {
if ($('#'+x).is(":hidden")) {
$(".interactContainers").slideUp(200);
$('#'+x).slideDown(300);
} else {
$('#'+x).slideUp(300);
}
}
and the div is this...
<div class="interactContainers" id="interactContainers" style="background-color: #EAF4FF;">
I just want to click the link (Email) from one page...have it open the correct persons(id) profile page...and then execute my existing toggleSlideBox javascript.
Is that doable without a bunch or re-code with javascript that I have about an IQ of 4 in. :\
Thank you for any assistance you provide
S
You could use the hash - link to http://example.com/#sectionOne and read the hash in your ready function.
As SidneySM suggested, a hash is the standard way of handling this. It could go something like this:
In your external js file:
var initSectorUI = function(){
if (location.hash) showSectorMini(location.hash);
};
var showSectorMini = function(sector){
$('#sectors > div').hide();
$(sector).show();
};
On your other pages:
$(function(){
initSectorUI();
$("#navigator a").click(function(){
showSectorMini($(this).attr('href'));
});
});
<div id="navigator">
One
Two
</div>
<div id="sectors">
<div id="one" style="display:none">A one</div>
<div id="two" style="display:none">A two</div>
</div>
You should arrange to produce different versions of the page, and put different onload actions into each version. For example, make the div to show a query parameter, and make django fill in the right onload depending on the query parameter. Then put the different query parameters into the links.

Getting my head around jQuery

OK, I'm designing a site and thought I'd stick some jQuery in as I really need so js experience.
Page with my problem is here: http://new.focalpix.co.uk/moreinfo.php
JS in question is:
$(document).ready(function(){
$(".answer").css("display","none");
$("#maincontent a.animate").click(function() {
$("#maincontent .answer").slideUp('slow');
var id = $(this).attr('href');
$(id).slideDown('slow');
return false;
});
});
This works fine, but if you click on a link where the answer has already slid down, then it slides up, then back down again.
I'm not sure on the cleanest way to stop this happening - any ideas?
You should be using the .slideToggle() effect.
$(document).ready(function() {
$(".answer").css("display","none");
$("#maincontent a.animate").click(function() {
$("#maincontent .answer").slideToggle('slow');
});
});
First, I'd suggest the following structure for your faq's:
<div id="faq">
<div class="qa" id="faq_greenandflies">
<span class="q">What is green and flies</span>
<div class="a">
Super Pickle!
</div>
</div>
<div class="qa" id="faq_redandbadforteeth">
<span class="q">What is Red and bad for your teeth</span>
<div class="a">
a Brick
</div>
</div>
<!--
More FAQ's here
-->
</div>
and then defining your jQuery as follows:
<script type="text/javascript">
$(function(){
// hide all answers
$('div#faq .qa .a').hide();
// bind a click event to all questions
$('div#faq .qa .q a').bind(
'click',
function(e){
// roll up all of the other answers (See Ex.1)
$(this).parents('.qa').siblings().children('.a').slideUp();
// reveal this answer (See Ex.2)
$(this).parents('.qa').children('.a').slideDown();
// return true to keep any other click events
return true;
});
// check location.hash to see if we need to expand one (direct link)
$(location.hash).find('.q a').click();
});
</script>
Explanation:
(Ex.1)
this is the link that was clicked
get the element that contains this and has a class of 'qa' (the box that contains both question and answer)
select all of its siblings. (we now have all qa's as a jQ object)
hide the answers
(Ex.2)
this is the line or link that was clicked
get the element that contains this and has a class of 'qa' (the box that contains both question and answer)
reveal the answer
A working demo is here.
This does several things for you:
If a user deep-links to an answer, the answer is automatically revealed
If a user clicks on one answer, all other answers are hidden
You can give your divs proper ids, so which helps search engine optimization of links to individual answers
Use slideToggle() like Soviut said, but just as a tip -- you can declare the display property in the actual CSS file instead of declaring it inside the javascript. jQuery will pick up on the fact that it is hidden in the stylesheet and still perform the appropriate slide function.
You can also use $(".answer").hide();
Instead of setting the display CSS property. Just thought I would let you know.
try using the one method, something like:
$(selector).one('effect', 'data for effect', callback function);
it makes sure an effect only happens once per element.

Categories