Navigation with an if that counts and add elements certain times - javascript

I'm looking to create a interactive nav bar for my own personal study purposes, so the idea behind it is if you click on down the number in the corner of the screen changes and a new image and text pops up every time this goes til number(page 5) all the other elements would be on display none except that one page that is active
I'd like to know if it would be possible to create a nav bar and lets say you have a set up nav with 2 buttons up and down how to make certain things not show up and others show up, i think my counter or var is not calculating properly, this is my javascript if statement( more in depth js fiddle https://jsfiddle.net/emilegmn/1L3h51zw/ )
if(numberCount < 1 ) {
add class to nav showing only one button ( down )
}
and this is my counter
numberCount = numberCount + 1
and then after that between 2-4 to show 2 buttons ( up and down )
and at 5 to only show up.
If someone has any things or knows something online that does this, please link me to it if you want!
I have tried finding how to do this but I am still trying to get it all figured out,
Thanks in advance and for your time!

If I understand correctly, is this what you want to achieve:
User clicks between two buttons to make new things appear (like a slider maybe?) but in a nav bar.
To do so you need JavaScript as well as an HTML structure that helps you out. In summary, you could do something along these lines. Granted this only takes into account a sort of "next button", if you want a previous one then you just need to add another function that instead of adding to the current_slide , subtracts from it.
Happy coding!
HTML
<nav id="slider-nav">
<div id="slide-1" class="active"></div>
<div id="slide-2"></div>
<div id="slide-3"></div>
<div id="slide-4"></div>
</nav>
CSS
With this you make sure that only the <div> with class .active is visible
#slider-nav div:not(.active) {
display:none;
}
JS
This would be your sweet JavaScript (jQuery)
//To be placed within your document ready function
const nav_slides =[]; //Holds the id of all your slides
var current_slide = 0;
$('#slider-nav div').each(function(){
nav_slides.push('#' + $(this).attr('id'));
});
/*This would be the part of when clicking happens on the 'next' button in your nav.
Keep in mind that the definition of the function must be within the same
scope as the defined variable, current_slide and nav_slides.
Hopefully, all encapsulated into one single scope that is your api.*/
function nextSlide(){
$(nav_slides[current_slide]).removeClass('active');
current_slide = (current_slide + 1) % nav_slides.length;
//Move on to next slide
//It's a circular counter, when it reaches max slide 4, it'll go back to 0
$(nav_slides[current_slide]).addClass('active');
}
ps: The initialization of current_slide is not dynamic. If in your HTML you happen to change who the first slide with active class is, then you need to update it in your JS. It would be very useful to initialize that current_slide dynamically, in other words, not hard coded out of laziness.

Related

Retain state of multi-level navbar/sidebar on new page

I'm very new to programming & working on creating a website for a work project.
In it, there will be a multi-level (w/sub-menus) vertical sidebar on each page.
The problem I'm facing is that every time a user clicks on one link, the sidebar resets to its original state & will have to redo the same thing & not very UX friendly.
I took the template of the accordian sidebar from here.
I've looked at various search results on both stack overflow & google, but can't seem to understand how to get it working to retain the state of the sidebar, regardless of how many levels are opened.
Can someone please help me with the JS code to get it working?
UPDATE:
Nathan, thanks for writing mate! I really appreciate the help.
So based on your suggestion, I've written the following (shoddy) code that injects the 'checked' attribute to the input element.
But it isn't transferring over to the new/redirected html page when a user clicks on one of the sub-menus. What am I missing here?
var menuIndex = -1;
//extract all the input elements
var inputs = document.querySelectorAll('.parent-menu');
//Find index of the element from the array that has "checked == true"
function indexFinder() {
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].checked == true) {
menuIndex = i;
console.log(menuIndex);
}
};
}
//Function to set/inject the attribute
function attributeSetter() {
inputs[menuIndex].setAttribute('checked', 'checked')
}
//When a user clicks literally anywhere, it'll run the indexFinder function
//to check if any of the input elements were expanded (i.e. checked == true)
window.addEventListener('click', () => {
indexFinder();
});
//Run the attributeSetter function when a page loads
window.addEventListener('DOMContentLoaded', () => {
attributeSetter();
});
Welcome to the world of programming! Hopefully I can help you out a little!
So what you're asking is something that can easily get a little complicated.
In order to achieve what you're trying to do you need to specify how you want your menu to look on each individual page!
Allow me to present a few menu options for an imaginary site:
Home
Contact
Email
Mail
About
The Company
Our Owner
I've indented the page names based on how we want them to show up in our menu.
So for example you may click on "Contact" and it drops down with the Email and Mail options.
Well, if you take your regular code from that webpage and copy and paste it everywhere. Any time you reload a page (or travel to another page with the same code) it's gonna reset the code! Thus "closing" the menu. Think of it as some sort of multi-dimentional sci-fi. When you load a webpage, you are accessing the main flow of time, any time you make an update to that page it takes you to an alternate reality with that change! but once you reload the webpage you jump back to the main timeline as if you never made that change (when you get into more advanced web dev, this analogy will break down but it should work to help your understanding for now.)
So let's say I click on the Contact > Email option and it takes me to the Email page. Well, in order to make it seem like my changes to the menu bar (clicking "Contact" to expand the dropdown) are still active. I need to hardcode the change into the Email page!
Here's some sample code:
<nav class="nav">
<a class="navOption">Home<a>
<a class="navOption">Contact<a>
<div class="navDropdown">
<a class="navOption">Email<a>
<a class="navOption">Mail<a>
</div>
<a class="navOption">About<a>
<div class="navDropdown">
<a class="navOption">The Company<a>
<a class="navOption">Our Owner<a>
</div>
<nav>
By default the .navDropdown will be closed. However when we add a class to them .active they will expand! If this is my base menu, then how should I make it so that the "About" dropdown is expanded when you are on one of the About pages?
Simply by adding .active to that dropdown!
<nav class="nav">
<a class="navOption">Home<a>
<a class="navOption">Contact<a>
<div class="navDropdown">
<a class="navOption">Email<a>
<a class="navOption">Mail<a>
</div>
<a class="navOption active">About<a>
<div class="navDropdown">
<a class="navOption">The Company<a>
<a class="navOption">Our Owner<a>
</div>
<nav>
Now, my example is different from yours because it's meant more for JavaScript. However, you can use the same concept in your code too.
For you, instead of having a .active class to expand a dropdown menu. You are using a checkbox element! In your codem you have CSS which is checking to see if the checkbox is checked and then it is opening the dropdown menu if it is:
<input class="cd-accordion__input" type="checkbox" name ="group-1" id="group-1">
So, if we use this method on our example webpage. We could set it to be open by setting the checkbox to start out being checked. Like so:
<input class="cd-accordion__input" type="checkbox" name ="group-1" id="group-1" checked>
It's important to note that as you get better and better at web development (eventually learning JavaScript and a server side language such as PHP). You will be able to piece together more advanced methods to doing what we're trying to accomplish! But for now, I hope I was able to break this down for you!

Show div when click on a different div, and show a different div when clicked again

I currently have made a way so the user can add another text field to the form by pressing on a 'add_another' div, this uses basic JS so when the user presses on the div 'add_another' the div 'author_2' is toggled.
I would like to make it so that when the user presses on the 'add_another' div for a second time it shows 'author_3' div, and when they press 'add_another' again, it then shows 'author_4'. I have put all the CSS and HTML divs in place to support this, I am just trying to adapt my code so it shows one div after another, rather then toggling a single div.
Here is my JS:
<script>
$(document).ready(function() {
$('.add_another').on('click', function(){
$('.author_2').toggle();
});
});
</script>
I have tried altering this code, however with no luck.
I haven't added my HTML as it is just 4 divs, 'author_1' 'author_2' ... 3...4
Thankyou for your help
There are two solutions to Your problem.
First one - use static code
It means the max author count is 4 and if user gets to 4, this is it.
If so - You need to store the number of authors already shown.
var authors_shown = 1;
$(document).ready(function() {
$('.add_another').on('click', function(){
authors_shown++;
if (!$('.author_'+authors_shown).is(":visible")) {
$('.author_'+authors_shown).toggle();
}
});
});
But there is also a second - more dynamic option.
What if user wants to input 10 or 20 authors? You don't want to pre render all that html code and hide it. You should clone the div and change its id or if the (HTML) code (for another author) is not too long, you can render it within JS code.
var div = document.getElementById('div_id'),
clone = div.cloneNode(true); // true means clone all childNodes and all event handlers
clone.id = "some_id";
document.body.appendChild(clone);
If it's a form, then change names of input fields to array as author_firstname[]
Also You can store number of added authors in another hidden field (so you know how long to loop the form fields on the server side.
The second option is a bit more complex and longer, but way more dynamic.
You should make another div when clicked on add_another:
something like this:
<script>
$(document).ready(function() {
$('.add_another').on('click', function(){
$('<div><input type="text" name="name[]" /></div>').appendTo('.your_container');
});
});
</script>
as you see, input's name has [] which means you should treat with the inputs as an array.
let me know if you got any further questions
good luck.

jQuery For Loop Image Check and Display

Good afternoon Stack Overflow,
I'm inexperienced when it comes to coding in general and I've been having a problem that's doing my head in!
If you'll allow me to set the scene...
The section of the project I am currently working on involves a user picking items from a warehouse in order to fulfil a shipment and in some cases they have to pick the same item from various locations, when that needs to be done, the small "!" type icon appears next to the item.
The user then can click on the icon and choose which locations they will be retrieving the stock from, they then press confirm on the modal and when it closes it sets the text back to blue and hides the icon.
The part I am having trouble with is that once all the locations have been established, the order needs to be processed and this requires a button to be clicked on, which I only want to appear once all the "!" icons are hidden.
I know there are alot of questions based on for loops and images checks and believe me when I say I've tried hard to figure this out myself and I've tried different approaches:
ShowProcess = false
for (i = 0; i<Picker; i++) {
if ($('#MultiLocIcon'+i).is(':visible')){
ShowProcess = true
}
if (ShowProcess == true) {
$('#ProcessConfirm').show()
};
};
This obviously wouldn't work because its setting the first variable in the list to "true" and will always read it as true, therefore always showing the image, even if the "!" icon still exists in other rows.
I also tried using .each() to test each rows text color of a specific but also had no luck:
var table = $('#RequestedItemsTable');
table.find('tbody > tr').each(function(){
if $('#Desc').css('color') == '#0000FF'){
//do something
I feel like my experience is letting me down as I still have a lot to learn and have a suspicious feeling that the solution is going to be really easy, but then again, its only easy if you know how.
If anyone could take the time to help me with this problem or offer me any advice, I'd be really grateful.
Here is a section of my code which might be useful:
Modal "Confirm" button:
//CONFIRM Button which will submit final picks.
'Confirm': function() {
//Reset the length loop
length = undefined;
//Remove "Multiple Location" icon from the row.
$('#icon'+id).hide();
//Change text colour back to blue to have visual confirmation that item is ready for picking
$('#Desc'+id).css('color', '#0000FF');
$('#QtyReq'+id).css('color', '#0000FF');
$('#QtyinStock'+id).css('color', '#0000FF');
$(this).dialog('close');
The "!" Icon:
<td id= "MultiLocIcon<?=$i;?>"><?if($row->Count_Location > 1)
{?><img src="<?=base_url();?>public/css/images/error.png" alt="LocPick" title="Multiple Locations" style="cursor: pointer;" id= "icon<?=$i;?>" onClick="$.LocPick(<?=$i;?>);"/><?}?></td>
Basically just need to know how my image can show once the loop checks and knows that the "!" icon is hidden from every possible row.
Thank you for your patience.
You'll need to add a second check in your modal logic, perhaps after your .hide():
//Remove "Multiple Location" icon from the row.
$('#icon'+id).hide();
$('img[id^=icon]:visible').length || $('#ProcessConfirm').show();
What this does is combines the :visible pseudo-selector and a regex selector for all img tags with id starting with "icon". This assumes you won't have any other unrelated image tags with an id like "icon*". If the length is 0, it will go ahead and show the #ProcessConfirm element.
simplest solution I would give is to add a class warning to all the table column which has warning icon & then check for visibility of the same.
if($('.warning:visible').length === 0){
//all warning icons are hidden
}
What I would do is based off your HTML, select all the alert icons, and do a :visible psuedo selector on it. This will return all the visible alert icons, if there are none in the array, you know none of them are visible. You will need to identify them with a class, such as .alert:
if( $(".alert:visible").length === 0 ){
// Do your code in here for no visible alert icons!
}
When user clicks confirm on modal you should run a check on how many icons are still visible, and if the amount is 0 then show the button, like this:
// This searchs for every <td> with an id that contains '#MultiLocIcon'
// Then checks if the amount of those which are visible is 0 and do something
if ( $('td[id*=MultiLocIcon]').not(':visible').length === 0 ) {
$('#ProcessConfirm').show()
}

check to see if div is already showing, and hide it

I am working on the responsive design of my website for mobile phones. I have an "img" tag inside of an "a" tag for 3 icons, like this:
<img src="images/webIcon.png" data-attr="webIcon">
On all other screen sizes, when a user hovers over the icon, a description appears, and then disappears again when they mouse-off. But on mobile phones, by the time they scroll down to view the description, it's gone, so I'm changing it to a click event on the "a" tag. I've successfully added the content where I want it when the user clicks on the appropriate icon, but I'm having trouble hiding it when the next icon is clicked, or if they click the same one again.Here is what I have:
$('#mobileServices a').hover(function(e) {
e.preventDefault();
//Grab the corresponding description for the icon
data = $(this).children('img').attr('data-attr');
section = $('#' + data + '').html();
//Plop in the new section containing the description below the icon
$(this).after('<section class=' + data + '>' + section + '</section');
//So I figured perhaps I should store-off the new sections for later use
newSection = $('section.' + data + '');
});
So then I thought: I'll use a simple if statement to check if the newSection is visible, and if it is, hide it (or slide it up, or slideToggle it), but that logic isn't working. I'm getting into the if statement, because I checked it with console.log(s). I tried something like:
if('section:visible') {
newSection.slideToggle();
}
But obviously that doesn't work, because it just slides it down and then up right away. So, now I'm stuck... Any help is greatly appreciated!!!!!
I think your issue may lie with the if statement you're trying to use. You'll want to get the element(s) first, with $('section') and then do .is(":visible");. So, to tie it together:
// Checks for display:[none|block], ignores visible:[true|false]
if($('section').is(":visible")) {
$('section').hide();
}
This will hide all the sections, and should achieve something close to what you're looking for. Then, you can show your new one with newSection.slideToggle() and be good to go.

JS While statement in Image Slider

Im trying to build an image slider with little buttons at the bottom that you can click and it will show the appropriate slide. So if you click button #3, it will show slide #3...pretty standard stuff. Im using javascript to detect how many slides there are and show an equal number of buttons. But now I can't figure out how to connect the buttons to the slide so that when a user clicks on one, it will show the appropriate number slide. I know this must be a pretty simple task, I just can't figure out how to set it up.
My script looks like this:
<script>
$(document).ready(function() {
var count = $(".slider_class").length;
$("#slide_0").show();
var i=0;
while (i < count){
$(".slider_bullets").append('<a href="#" id="bullet_link_' + i +'"><img src="img/slider_down.png" alt="slider_down" />');
i++;
}
});
</script>
.slider_class is a class I have applied to each of the slides. Each slide also has a number id starting at zero so that the third slide is #slide_2. The .slider_bullets are the buttons I was talking about. You'll notice that I have given each of them a unique specified id as well that references the slide that they are associated with.
This is what I would use.
$(".slider_bullets a").click(function(){
$(".slider_class").hide();
$("#slide_"+$(this).index()).show();
});

Categories

Resources