How to have certain buttons and balance show after login - javascript

header {
width: 100%;
background-color: #2C2F33;
border-bottom: 5px #FF9F00 solid;
font-size: 12.5px;
display: flex;
align-items: center
}
#logo img {
float: left;
margin: 0;
padding: 20px;
width: 125px;
height: 42.5px;
background-color: #2C2F33;
}
.beforelogin {
display: flex;
justify-content: space-between;
margin-left: auto;
}
.afterlogin {
display: flex;
justify-content: space-between;
margin-left: auto;
}
.navbar {
display: flex;
justify-content: space-between;
margin-left: auto;
}
li {
display: inline;
padding: 0 20px 0 20px;
}
#rightnavbar li {
display: inline-block;
position: relative;
}
.navbar,
li,
a {
text-decoration: none;
list-style-type: none;
text-transform: uppercase;
background-color: #2C2F33;
position: relative;
}
#rightnavbar a:hover {
color: #FF9F00;
}
#rightnavbar a::before {
content: '';
display: block;
height: 3px;
background-color: #FF9F00;
position: absolute;
top: -34px;
width: 0%;
transition: all ease-in-out 225ms;
}
#rightnavbar a:hover::before {
width: 100%;
}
#userbalance {
background-color: #23272A;
padding: 12.5px;
margin-right: auto;
border: 2.5px #FF9F00 solid;
}
#balance,
#dsh {
color: #FF9F00;
}
#dosh {
color: #FFFFFF;
}
<header>
<div id="logo">
<a href="index.html"><img src="./img/logo.png" title="Website Info"></img>
</a>
</div>
<div class="beforelogin">
<div id="rightnavbar">
<ul>
<li>Login</li>
</ul>
</div>
</div>
<div class="afterlogin">
<div class="navbar">
<div id="leftnavbar">
<ul>
<li id="userbalance"><span id="balance">Balance:</span> <span id="dosh">1.00000000</span> <span id="dsh">DSH</span></li>
</ul>
</div>
<div id="rightnavbar">
<ul>
<li>User Panel</li>
<li>News</li>
<li>View on Social Media</li>
<li>Logout</li>
</ul>
</div>
</div>
</div>
</header>
I am trying to make my website, where after user logs in .beforelogin's <li> disappears and .afterlogin's <li> appears.
So there is only Login button for the user till the user logs in (In the header/navbar) and after login the Login exchanges its place for Logout and 3 other buttons and User Balance appears.
I asked a webdev friend and he said to use JavaScript/jQuery but I am not that good in those. I am still trying to find some good tutorials to learn JavaScript/jQuery for webdev but I am not sure where to look for.

There needs to be some trigger that executes this script. In this case you can add this HTML temporarily under the header
<br />
<input type="radio" name="loginStatus" id="loggedIn" value="Logged in" checked="checked" /> User is logged in
<br />
<input type="radio" name="loginStatus" id="loggedOut" value="Logged out" /> User is logged out
Now the jQuery:
// sets initial status - this can be done by CSS as well
if ($('input#loggedIn').prop('checked')) {
alert('Login is visible so after-loggin is hidden');
$('.beforelogin').css('display', 'none');
$('.afterlogin').css('display', 'block');
} else {
alert('Login is visible so after-loggin is hidden');
$('.beforelogin').css('display', 'block');
$('.afterlogin').css('display', 'none');
}
// this changes the status based on the radio buttons
$('input[name = "loginStatus"]').change(function() {
if ($('input#loggedIn').prop('checked')) {
$('.beforelogin').css('display', 'none');
$('.afterlogin').css('display', 'block');
} else {
$('.beforelogin').css('display', 'block');
$('.afterlogin').css('display', 'none');
}
});
This gets you the display block or yes, or display none. To simply use jQuery to see if one is display and if so hide the other, you can do this:
var isDisplayed = $('.afterlogin').css('display', 'block');
var isNotDisplayed = $('.afterlogin').css('display', 'none');
if ($('.beforelogin').css('display') == 'none') {
$(isDisplayed);
} else {
$(isNotDisplayed);
}
If you are unfamiliar with jQuery then you should take a beginners tutorial to show you where to put the scripts and all that stuff. YouTube has good videos for free.
Here's a jsfiddle

As per above HTML you can use below code to hide containers based on logged in and logged out scenarios.
1) User non logged in scenario
$(".beforelogin").show();
$(".afterlogin").hide();
2) User logged in scenario.
$(".afterlogin").show();
$(".beforelogin").hide();
Of course we should call above functions at right place in the code and logged in and non logged in scenario should be dependent on login service call, but it depends on the requirement. And also to draw containers (afterlogin, beforelogin) at same location you have to use similar styling.

Related

How can I make it so only the tab area loads instead of the page jumping to the top after clicking on tab?

As the title states, I'm making a tabbed section to switch content upon click which works fine, how can I make it so upon clicking a new tab it has a smooth transition to the content as well as prevent jumping to the top of the page every time I click a tab?
I've tried adding the function which prevents it for links but this isn't a link so that doesn't seem to be working.
HTML
<section class="featured-books">
<div class="featured-books-title"><h2>Featured Books</h2></div>
<ul class="tabs">
<li data-tab-target="#featured" class="active tab">Featured</li>
<li data-tab-target="#on-sale" class="tab">On Sale</li>
<li data-tab-target="#most-viewed" class="tab">Most Viewed</li>
</ul>
<div id="featured" data-tab-content class="active">
<div class="featured-tab">
<img src="./images/12-rules.jpg">
<img src="./images/7-habits.jpg">
<img src="./images/art-of-war.jpg">
<img src="./images/boundaries.jpg">
<img src="./images/unlimited-memory.jpg">
<img src="./images/meaning-of-marriage.jpg">
<img src="./images/meditations.jpg">
<img src="./images/peaceful-parents.jpg">
<img src="./images/plant-paradox.jpg">
<img src="./images/spirit-filled-life.jpg">
<img src="./images/javascript-definitive-guide.jpg">
<img src="./images/atomic-habits.jpg">
</div>
</div>
<div id="on-sale" data-tab-content>
</div>
<div id="most-viewed" data-tab-content>
</div>
</section>
CSS
.featured-books h1 {
display: flex;
justify-content: center;
}
[data-tab-content] {
display: none;
}
.active[data-tab-content] {
display: block;
}
.tabs {
display: flex;
justify-content: center;
list-style-type: none;
margin: 0;
padding-bottom: 60px;
padding-top: 16px;
}
.tab {
border-radius: 20px;
cursor: pointer;
padding: 10px;
}
.tab.active {
background-color: #CCC;
}
.tab:hover {
background-color: #aaa;
}
/**------FEATURED TAB CONTENT------*/
.featured-tab {
position: absolute;
justify-content: center;
align-items: center;
margin-top: 10px;
width: 100vw;
display: grid;
grid-template-columns: repeat(auto-fill,minmax(300px,300px));
column-gap: 3px;
row-gap: 40px;
}
.featured-tab img {
width: 180px;
height: auto;
object-fit: cover;
object-position: center;
}
JavaScript
const tabContents = document.querySelectorAll('[data-tab-content]')
tabs.forEach(tab => {
tab.addEventListener('click', () => {
const target = document.querySelector(tab.dataset.tabTarget)
tabContents.forEach(tabContent => {
tabContent.classList.remove('active')
})
tabs.forEach(tab => {
tab.classList.remove('active')
})
tab.classList.add('active')
target.classList.add('active')
})
})
Here is a simple example using a opacity transition but you can use height, width or transform if you would like. I use aria-attributes to keep track of things like which article is open and if the information in the article should be picked up by screen readers. The two most important CSS classes are show and hide. These control the opacity and when the transition takes place. Show has a slight delay so it waits for the one being hidden to get out of the way. As far as the JavaScript.
Select all the buttons that have popups.
Create a event listener to handle the click.
Select the controlled article and all the articles.
Check if the controlled article is currently hidden.
If it is hide all the artiles.
Change all the buttons aria-expanded attributes to false.
Set the aria-expanded attribute on the clicked button to true.
Set aria-hidden class on the controlled article to false.
Remove the hide class and add the show class to the controlled article.
const buttons = document.querySelectorAll("[aria-haspopup=true]")
const handleClick = (event) => {
const controls = event.target.getAttribute("aria-controls"),
controlled = document.getElementById(controls),
articles = document.querySelectorAll("article");
if (controlled.getAttribute("aria-hidden") === "true") {
articles.forEach(article => {
article.setAttribute("aria-hidden", "true");
article.classList.add("hide");
article.classList.remove("show");
})
buttons.forEach(button => button.setAttribute("aria-expanded", "false"))
event.target.setAttribute("aria-expanded", "true");
controlled.setAttribute("aria-hidden", "false");
controlled.classList.remove("hide");
controlled.classList.add("show");
}
}
buttons.forEach(button => {
button.addEventListener("click", handleClick);
})
ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
}
li {
margin-right: 10px;
}
article {
height: calc(100vh - 50px);
width: 100vw;
position: absolute;
top: 50px;
left: 0;
}
#feature {
background-color: red;
}
#sale {
background-color: green;
}
#view {
background-color: blue;
}
.show {
opacity: 1;
transition: opacity .2s ease-in-out .2s;
}
.hide {
opacity: 0;
transition: opacity .2s ease-in-out;
}
button[aria-expanded=true] {
background-color: #cceeff;
}
<ul>
<li>
<button aria-haspopup="true" aria-expanded="true" aria-controls="feature">Featured</button>
</li>
<li>
<button aria-haspopup="true" aria-expanded="false" aria-controls="sale">On Sale</button>
</li>
<li>
<button aria-haspopup="true" aria-expanded="false" aria-controls="view">Most Viewed</button>
</li>
</ul>
<article class="show" id="feature" aria-hidden="false">
<h1>Featured</h1>
</article>
<article class="hide" id="sale" aria-hidden="true">
<h1>On Sale</h1>
</article>
<article class="hide" id="view" aria-hidden="true">
<h1>Most Viewed</h1>
</article>

When I click on the menu button It is not opening the menu

const menuBtn = document.querySelector('#menuBtn')
const exitBtn = document.querySelector('#exitBtn');
const menu = document.getElementsByClassName('menu');
menuBtn.addEventListener('click' , () => {
menu.style.display = 'block'
})
.fa.fa-bars.menuBtn {
color: #fff;
font-size: 35px;
cursor: pointer;
display: none;
}
.fa.fa-times-circle.exit {
color: white;
font-size: 35px;
cursor: pointer;
}
#media (max-width: 934px) {
.max-width {
padding: 0 50px;
}
.fa.fa-bars.menuBtn {
display: block;
}
.navbar .menu {
position: fixed;
height: 100vh;
width: 100%;
left: 0;
top: 0;
background-color: #111;
text-align: center;
padding-top: 110px;
display: none;
}
.menu{
display: none
}
.exit {
z-index: 999;
display: none;
margin: 1.8rem;
}
.navbar .menu li {
display: block;
}
.navbar .menu li a {
display: inline-block;
margin: 20px 0;
font-size: 35px;
}
}
<nav class="navbar" id="nav">
<div class="max-width">
<div class="logo"><a id="headSpan" href="index.html">Port<span>folio.</span></a></div>
<ul class="menu">
<li>Home</li>
<li>About</li>
<li>Skills</li>
<li>Projects</li>
<li>CV</li>
<li>Contact</li>
</ul>
<div>
<i class="fa fa-bars menuBtn" id="menuBtn" aria-hidden="true"></i>
</div>
<div class="exit">
<i class="fa fa-times-circle exit" id="exitBtn" aria-hidden="true"></i>
</div>
</div>
</nav>
How do I make it work ? I tested to see if the add event listener was working and it was working but when it comes to displaying the menu when clicked it does not work. Any idea what the issue may be ? I am not that good at using Javascript so any help would be appreciated . Thank you
document.getElementsByClassName('menu'); doesn't return a single element. It returns an HTMLCollection. So menu isn't an element and menu.style.display = 'block doesn't do what you're trying to do.
document.getElementsByClassName('menu') gets multiple elements, all of which have the class 'menu'. The function returns an HTMLCollection, but you can treat it like a list. If you want to use classes, I would recommend using:
var list = document.getElementsByClassName('menu')
for (var item of list) {
// Do Stuff Here
}
If you have multiple menus, consider using JQuery with the .each(function) method for functions.

Submenu close function not working properly using Javascript

I have a function that is semi-working to get a submenu to close when a user clicks anywhere else outside of the box. The function is selecting a class of sub.menu-open. If the event target does not equal the sub.menu-open and its parentNodes, (the elements inside the box), the function should execute "submenu-.open.style.display = "none". So, this works for a few clicks then it stops. The console reads Null after the first click. What I believe is that in my HTML there is no initial set class of sub.menu-open, which is why its saying Null at first. I add the submenu-open class with javascript. That is how I get the submenu to open in the first place. Is this possible to fix?
arrowButton.forEach((el) =>
el.addEventListener("click", (event) => {
const subMenu = event.target.parentElement.querySelector(".sub-menu");
subMenu.classList.toggle("open");
})
);
-opening the submenu-
window.addEventListener("mouseup", (event) => {
let box = document.querySelector(".sub-menu.open");
if (event.target != box && event.target.parentNode != box) {
box.style.display = "none";
}
});
--closing the submenu--
.sub-menu {
display: none;
}
.sub-menu.open {
position: absolute;
width: 10vw;
background-color: white;
color: black;
text-align: left;
display: flex;
flex-direction: column;
margin: 6px auto;
padding-left: 0.3rem;
border-radius: 5px;
#include mobile {
display: flex;
flex-direction: column;
background-color: $footer-text;
width: 60vw;
margin: 0 auto;
color: $darkblue-headingtext;
border-radius: 5px;
position: relative;
left: 5px;
text-align: center;
}
}
<li class="parent">
Product
<img
class="menu-arrow mobile"
src="images/icon-arrow-dark.svg"
alt="arrow"
/>
<img
class="menu-arrow desktop"
src="./images/icon-arrow-light.svg"
alt="arrow"
/>
<ul class="sub-menu">
<li>Overview</li>
<li>Pricing</li>
<li>Marketplace</li>
<li>Features</li>
<li>Integrations</li>
</ul>
</li>
Any tips are greatly appreciated!

Setting default content with jQuery

In the code below, the default main content is empty. Unless I click on any of the bottom navbar buttons, no content will show up.
I'd like to set content-1 and menu-1 (its respective button) to be the default, i.e. when the user opens the webpage it would be the first thing they see and the button would be black indicating that it is active.
I tried to use an else statement but it did not work:
// set menu-1 as default
else {
$('.menu-1').addClass('default')
$('.content').addClass('default')
}
Find the entire code below:
$(document).ready(function() {
// only show menu-1
$('.menu-1').click(function() {
if ($('.menu-2, .menu-3').hasClass('active')) {
$('.menu-2, .menu-3').removeClass('active');
$('.content-2, .content-3').removeClass('active');
}
// set menu-1 as default
// else {
// $('.menu-1').addClass('default')
// $('.content').addClass('default')
// }
$('.menu-1').addClass('active');
$('.content-1').addClass('active');
});
// only show menu-2
$('.menu-2').click(function() {
if ($('.menu-1, .menu-3').hasClass('active')) {
$('.menu-1, .menu-3').removeClass('active');
$('.content-1, .content-3').removeClass('active');
}
$('.menu-2').addClass('active');
$('.content-2').addClass('active');
});
// only show menu-3
$('.menu-3').click(function() {
if ($('.menu-2, .menu-1').hasClass('active')) {
$('.menu-2, .menu-1').removeClass('active');
$('.content-2, .content-1').removeClass('active');
}
$('.menu-3').addClass('active');
$('.content-3').addClass('active');
});
});
.container {
margin: 0 auto;
background-color: #eee;
border: 1px solid lightgrey;
width: 20vw;
height: 90vh;
font-family: sans-serif;
position: relative;
}
header {
background-color: lightgreen;
padding: 5px;
text-align: center;
text-transform: uppercase;
}
.bottom-navbar {
position: absolute;
bottom: 0;
width: 100%;
padding: 6px 0;
overflow: hidden;
background-color: lightgreen;
border-top: 1px solid var(--color-grey-dark-3);
z-index: 50;
display: flex;
justify-content: space-between;
> a {
display: block;
color: green;
text-align: center;
text-decoration: none;
font-size: 20px;
padding: 0 10px;
&.active {
color: black;
}
}
}
.menu-1.default,
.menu-1.active,
.menu-2.active,
.menu-3.active {
color: black;
}
.content-1,
.content-2,
.content-3 {
display: none;
}
.content-1.default,
.content-1.active,
.content-2.active,
.content-3.active {
display: block;
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}
<div class="container">
<header>My header</header>
<div class="main-content">
<div class="content-1">House content</div>
<div class="content-2">Map content</div>
<div class="content-3">Explore content</div>
<div class="bottom-navbar">
<i class="fa fa-home"></i>
<i class="fa fa-map"></i>
<i class="fa fa-search"></i>
</div>
</div>
In case you find it easier, here's my CodePen:
https://codepen.io/fergos2/pen/vYYaRzN
All that is going on to set up each menu and content item to display on the page is adding the class active. So it looks to me like all you need to do is add that class to the HTML. That way when the page loads it's already "active" and when you click something else you already have it set up to remove the class and set something else as active. So basically, your HTML would look like this:
<header>My header</header>
<div class="main-content">
<div class="content-1 active">House content</div>
<div class="content-2">Map content</div>
<div class="content-3">Explore content</div>
<div class="bottom-navbar">
<i class="fa fa-home active"></i>
<i class="fa fa-map"></i>
<i class="fa fa-search"></i>
</div>
</div>
All I did was give .menu-1 and .content-1 the class of active.
You'll also need to get rid of the css bit which references .content-1.default and .menu-1.default and also set your JS to add the .active back when you click that menu button which you already have. Don't worry about the else statement inside that click function
Let me know if this works out for you!

How to make different video answers in list of questions?

I need to make popup which have to contain questions and video answers.
The tricky part for me is how to make every question to display different video, but on the same place. Also when the user first sees the popup the first question and video should be predefined.
Here is the basic scheme of the popup:
Set every video to display:none, then use jQuery to display the needed item once some user action is taken. In my example I used .click()
Basic example:
$(".options>li").click(function() {
$(".view").css('display', 'none')
});
$("li.aaa").click(function() {
$(".view.aaa").css('display', 'block')
});
$("li.bbb").click(function() {
$(".view.bbb").css('display', 'block')
});
$("li.ccc").click(function() {
$(".view.ccc").css('display', 'block')
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.wrapper {
display: flex;
width: 90vw;
margin: 0 auto;
align-items: center;
}
.panel {
display: inline-block;
width: 50%;
}
.view {
max-width: 100%;
display: none;
border: 1px solid red;
}
.options>li {
width: 100%;
background: grey;
list-style: none;
margin: .25em auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="panel right">
<ul class="options">
<li class="aaa">aaa</li>
<li class="bbb">bbb</li>
<li class="ccc">ccc</li>
<li class="ddd"></li>
<li class="eee"></li>
</ul>
</div>
<div class="panel left">
<img src="http://fruitandvegetablesmelbourne.com.au/wp-content/uploads/2015/04/golden-delicious-apples.jpg" class="view aaa">
<img src="http://img.aws.livestrongcdn.com/ls-article-image-400/cpi.studiod.com/www_livestrong_com/photos.demandstudios.com/56/251/fotolia_5712687_XS.jpg" class="view bbb">
<img src="http://timesofindia.indiatimes.com/thumb/msid-49502853,width-400,resizemode-4/49502853.jpg" class="view ccc">
</div>
</div>

Categories

Resources