JavaScript for Responsive Navbar using checkbox checked or not - javascript

I need a Javascript while adds the class checkedNavbar when the checkbox is checked and to remove it when unchecked.
<div class="hamburger">
<input type="checkbox" id="check" onclick="EnableDisableNavbar"/>
<label for="check" class="checkButton">
<i class="fas fa-bars" style="font-size: 35px"></i>
</label>
</div>
I want to add a class while checked and remove it when unchecked.
Here's my css:
ul{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
z-index: 0;
right: 0;
background-color: #e54136;
}
ul li{
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
margin: 15px 0;
}
ul li a{
font-size: 30px;
}
.checkedNavbar{
right: 100%;
}

Try like this:
function EnableDisableNavbar() {
document.querySelector(".hamburger").classList.toggle("checkedNavbar");
}
ul {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
z-index: 0;
right: 0;
background-color: #e54136;
}
ul li {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
margin: 15px 0;
}
ul li a {
font-size: 30px;
}
.checkedNavbar {
right: 100%;
}
/* Below added for demo only */
.hamburger {
background-color: yellow;
}
.checkedNavbar {
background-color: purple;
}
<div class="hamburger">
<input type="checkbox" id="check" onclick="EnableDisableNavbar()" />
<label for="check" class="checkButton">
<i class="fas fa-bars" style="font-size: 35px"></i>
</label>
</div>
Checkbox onclick attribute changed to EnableDisableNavbar()
The JavaScript classList.toggle() method can be used to add/remove the checkedNavbar class each time the checkbox is clicked.
An approach like this, which toggles a class, may be needed where the styling of the parent element of the checkbox changes, because in CSS that cannot be accessed using input:checked.

Related

CSS- Sticky Header content overlaps onScroll

In Angular application I am making Filters and Header row element sticky. I am using HostListener and windowscroll to achieve this functionality. The problem I am facing is Header and filter content is overlapped with the results when user scroll down.
I need help to fix this overlap.
Link to demo - https://screenrec.com/share/XKtIZji2lY
FILTERS Code
html
<div class="filters-data" [ngClass]="{'mat-elevation-z5' : true, 'sticky' : isSticky}">
<div class="im-results">
<div>
<strong>{{ Amazon Data }} </strong> match
</div>
</div>
<div class="filters-data-result">
<app-filters-data-result *ngFor="let item of filters; let i = index" [item]="item" (onRemoved)="remove(item)">
</app-filters-data-result>
</div>
</div>
.css
.mat-elevation-z5 {
position: relative;
}
.sticky {
position: fixed;
top: 100px;
}
div.filters-data {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-around;
align-items: center;
align-content: flex-start;
padding: 20px 0;
.im-results {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
align-content: center;
font-size: 18px;
}
.filters-data-result {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
align-content: center;
margin-right: 8px;
}
}
.ts
isSticky: boolean = false;
#HostListener('window:scroll', ['$event'])
checkScroll() {
this.isSticky = window.pageYOffset >= 10;
}
HEADER CODE
html
<div class="header-top bottom-border mb-10" [ngClass]="{'mat-elevation-z5' : true, 'sticky' : isSticky }">
<div class="am-ctnr rows-header">
<div class="im-header-product">
<div> Products</div>
</div>
<div class="im-number">
<div> Number</div>
</div>
<div class="shippment-number">
<div>Shippment Number</div>
</div>
<div class="origin">
<div>
Origin
</div>
</div>
<div class="size">
<div>
Size
</div>
</div>
</div>
</div>
.css
.header-top{
.im-error-notification-div{
overflow:hidden;
.im-error-notification-inner{
float:right;
}
}
&.bottom-border {
border-bottom: 1px solid am-colors.$ash-grey;
}
.mb-10 {
margin-bottom: 10px;
}
.am-ctnr {
display: flex;
padding: 5px 16px 10px;
align-items: baseline;
flex-wrap: wrap;
#media #{am-responsive-breakpoints.$screen-xs-sm-md}{
display: none;
}
&.rows-header {
font-family: am-fonts.$am-font-family-bold;
font-size: 11px;
font-weight: bold;
justify-content: space-between;
.im-header-product{
padding: 5px;
width: 30%;
}
.im-header-catalog{
padding: 5px;
width: 10%;
}
.im-header-lot-number{
padding: 5px;
width: 10%;
}
.im-header-origin{
padding: 5px;
width: 10%;
}
.im-header-unit-size{
padding: 5px;
width: 5%;
min-width: 60px;
}
.im-header-item-price{
padding: 5px;
width: 10%;
}
}
}
}

Select tag to be side by side options tag

Is it possible to have an option list in two columns? For example that an option has a text that is on the left side and another that is on the right, but in the same row.
Example:
+-----select options-----+
option1 option2
option3 option4
+-----------------------+
It's not possible to do that with a standard select but you can simulate it. Below is an example which you can modify according to your needs.
When the form is submitted, the selected option is being sent as a hidden input.
$("body").on("click", ".selected", function() {
$(this).next(".options").toggleClass("open");
});
$("body").on("click", ".option", function() {
var value = $(this).find("span").html();
$(".selected").html(value);
$("#sel").val(value);
$(".options").toggleClass("open");
});
.container {
display: flex;
flex-wrap: wrap;
width: 160px;
}
.selected {
border: thin solid darkgray;
border-radius: 5px;
background: lightgray;
display: flex;
align-items: center;
cursor: pointer;
height: 1.5em;
margin-bottom: .2em;
padding-left: .5em;
min-width: 150px;
position: relative;
}
.selected:after {
font-family: FontAwesome;
content: "\f0d7";
margin-left: 1em;
position: absolute;
right: .5em;
}
.options {
display: none;
margin: 0;
padding: 0;
width: 100%;
}
.options.open {
display: flex;
flex-wrap: wrap;
}
li {
display: flex;
align-items: center;
cursor: pointer;
width: 50%;
}
li:nth-child(odd) {
justify-content: flex-start;
}
li:nth-child(even) {
justify-content: flex-end;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<form>
<input type="hidden" id="sel">
<div class="container">
<div class="selected">Select an option</div>
<ul class="options">
<li class="option"><span>Option 1</span></li>
<li class="option"><span>Option 2</span></li>
<li class="option"><span>Option 3</span></li>
<li class="option"><span>Option 4</span></li>
</ul>
</div>
</form>

How do I change the div size by clicking multiple button?

I want to change the div size when someone clicks the corresponding button. For example, clicking the small button will make the div width 30%, and clicking the medium button will make the div width 50%.
I found this Javascript: Change Div size on button click, but it's not working for me because I don't know his HTML structure, and he is using ID instead of class.
Below is my code. Please help me:
body {
display: flex;
flex-direction: column;
justify-content: center;
height: 300px;
}
.Button_Container {
display: flex;
flex-direction: row;
justify-content: center;
}
.Medium {
margin: 0 15px;
}
.Content_Container {
width: 100%;
height: 150px;
background-color: blue;
margin-top: 30px;
}
<div class="Button_Container">
<button class=">FULL" onclick="myFunction">FULL</button>
<button class="Medium" onclick="myFunction">Medium</button>
<button class="Small" onclick="myFunction">Small</button>
</div>
<div class="Content_Container"></div>
function myFunction(width){
var all = document.getElementsByClassName('Content_Container');
for (var i = 0; i < all.length; i++) {
all[i].style.width = width;
}
}
body {
display: flex;
flex-direction: column;
justify-content: center;
height: 300px;
}
.Button_Container {
display: flex;
flex-direction: row;
justify-content: center;
}
.Medium {
margin: 0 15px;
}
.Content_Container {
width: 100%;
height: 150px;
background-color: blue;
margin-top: 30px;
}
<div class="Button_Container">
<button class=">FULL" onclick="myFunction('100%')">FULL</button>
<button class="Medium" onclick="myFunction('70%')">Medium</button>
<button class="Small" onclick="myFunction('50%')">Small</button>
</div>
<div class="Content_Container"></div>

How do I loop through refs made from a v-for to then add a class depending if the radio is clicked?

here is what my services page currently looks like:
So when you choose one of the blue radio buttons, it loads the green radio buttons which are sub options, clicking on a green sub option will show the information for that specific product/service.
As you can see when you select a categeory and then a service, it all works correct but I need to add an "active-radio-button" class to the ones that are currently selected.
Similar to a nav bar showing which page is currently active.
I've tried giving each radio button a $ref and then I loop through all the refs to see if they are checked, however it doesnt work, I can't even figure out how to print each ref to the console (although I can see them in the Vue developer console).
Here is the service page:
<template>
<div class="services">
<div class="header services__header">
<h1 :class="$mq">Services</h1>
</div>
<div class="services__services-container">
<div class="select-wrapper">
<div
class="services__services-container__category-selection"
:key="`category-${index}`"
v-for="(item, index) in this.JSON"
>
<!-- GENERATE CATEGORIES -->
<input
v-model="currentCategory"
#change="UncheckRadio"
type="radio"
class="services__services-container__category-selection__category"
:class="$mq"
:value="item"
:ref="item.name"
/>
<label :for="item">{{ item.name }}</label>
</div>
</div>
<!-- GENERATE SERVICES -->
<div class="services__services-container__service-selection" v-if="currentCategory != null">
<div class="select-wrapper">
<div
class="services__services-container__service-selection__service"
:key="`option-${index}`"
:class="$mq"
v-for="(option, index) in currentCategory.options"
>
<input
type="radio"
class="services__services-container__service-selection__service__wrapper"
:class="$mq"
:value="option"
v-model="currentService"
:ref="option.optionName"
/>
<label :for="option">{{ option.optionName }}</label>
</div>
</div>
</div>
<!-- GENERATE DESCRIPTIONS -->
<div class="services__services-container__product-description" v-if="currentService != ''">
<div class="services__services-container__product-description__description" :class="$mq">
<div :class="$mq">
<img :src="currentService.images" alt />
<p>{{ currentService.description }}</p>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import services from "#/JSON/services.json";
export default {
name: "Services",
data: function() {
return {
JSON: [],
currentCategory: "",
currentService: ""
};
},
created: function() {
//TO TEST
this.JSON = services.services;
},
methods: {
UncheckRadio: function() {
this.currentService = "";
console.log("kek");
for (const ref in this.refs) {
console.log(ref.key);
}
}
}
};
</script>
<style lang="scss">
#import "#/scss/variables.scss";
#import "#/scss/button.scss";
#import "#/scss/header.scss";
#import "#/scss/input.scss";
.services {
width: 100%;
height: auto;
display: grid;
grid-template-rows: 15vh auto auto auto;
&__services-container {
//FLEX
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
flex-wrap: wrap;
//
padding: 2rem;
&__category-selection {
//FLEX
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
flex-wrap: wrap;
//
position: relative;
padding: 1rem;
cursor: pointer;
& input {
cursor: pointer;
position: absolute;
width: 100%;
height: 100%;
z-index: 100;
opacity: 0;
}
& label {
cursor: pointer;
color: $colour-blue;
}
}
&__service-selection {
&__service {
//FLEX
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
flex-wrap: wrap;
//
position: relative;
padding: 1rem;
cursor: pointer;
& input {
cursor: pointer;
position: absolute;
width: 100%;
height: 100%;
z-index: 100;
opacity: 0;
}
& label {
cursor: pointer;
color: $colour-green;
}
}
}
/* For IE10 */
select::-ms-expand {
display: none;
}
&__product-description {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
#include green-gradient;
padding: 2rem;
border-radius: 1.5rem;
&__description {
& img {
margin-bottom: 1rem;
height: 10rem;
width: 10rem;
object-fit: cover;
}
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
text-align: center;
}
}
}
}
.select-wrapper {
//FLEX
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
//
border-radius: 1.5rem;
position: relative;
width: auto;
height: auto;
margin-bottom: 1rem;
}
.select-icon {
font-size: 1rem;
color: $white;
position: absolute;
right: 0.5rem;
pointer-events: none;
}
.transition {
transition: all 0.25s linear;
}
.active-radio-button {
border-bottom: 0.1rem solid black;
}
</style>

Hamburger menu drop down on low width

I have navbar with few items and hamburger icon that should be displayed on low width, in this time navbar items should hide. With the button i want to change their display to bo flex and flex-direction set to column, so items will display vertically. I am trying to use this function, could you suggest me something ?
Here is the code :
let btn = document.getElementById('btn');
let menu = document.getElementsByClassName('hammburger-links')[0];
btn.addEventListener('click', function() {
menu.classList.toggle('openmenu');
});
.slider .hammburger-menu {
width: 16px;
height: 14px;
border: 0;
display: none;
position: absolute;
}
#media (max-width: 1425px) {
.slider .hammburger-menu {
display: inline;
}
.slider .hammburger-menu div {
background-color: #202124;
display: block;
width: 16px;
height: 2px;
margin: 4px 0;
}
}
.slider .hammburger-links {
padding: 0 1.250em;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
position: relative;
}
.slider .hammburger-links a {
padding: 0 1.500em;
text-decoration: none;
font-family: "Helvetica", Arial;
font-size: 11px;
color: #a6adb4;
}
#media (max-width: 1425px) {
.slider .hammburger-links a {
display: none;
}
}
.slider .hammburger-links .under-home {
position: absolute;
top: 2.5em;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
background: #F6F8F9;
min-width: 12.5em;
min-height: 12.5em;
z-index: 1;
display: none;
}
.slider .hammburger-links .under-home a {
margin: 10px 0;
}
.slider .hammburger-links.openhome {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
.slider .hammburger-links.openmenu a {
display: flex;
flex-direction: column;
}
<div class="slider">
<div class="hammburger-menu" id="btn">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
</div>
<div class="hammburger-links" id="menu">
HOME
<div class="under-home">
WORLD NEWS
TRAVEL
TECHNOLOGY
CITY
CULTURE
MORE...
</div>
DISCOVERY
PHOTOS
CONTACT
<img src="images/navbar-img.png" alt="">
</div>
</div>
document.getElementsByClassName returns an array. So you want to do let menu = document.getElementsByClassName('hammburger-links')[0]; or get the element by id (menu).
Doing that should add the desired class to the #menu element, but your CSS also has a problem. Your CSS selector .slider .hammburger-links .openmenu doesn't select anything. That selector looks for an element .openmenu that is a descendant of an element .hammburger-links, that is a descendant of element .slider. You need the element that belongs to classes hammburger-links and openmenu. The selector looks like this: .slider .hammburger-links.openmenu
However, that still doesn't reveal the menu elements. I found that changing the selector again to target child anchor elements (.slider .hammburger-links.openmenu a) did the trick, but you may want to go about that differently depending on how you want to implement it.

Categories

Resources