Dropdown vanishes as soon as it comes out of hover - html

I've made a list of categories in the navbar and in these categories. I want to show a dropdown just like a Flipkart website. But when I'm hovering over my categories it shows dropdown but as soon as I move my mouse over the dropdown list my dropdown vanishes.
I'm getting these categories and dropdowns from backend in the form of an array that's why I use ngFor in my Html file to display my categories and dropdown list. Is there any way to expand the hover area over the categories.
My main aim is when I mouse over my dropdown it shows till my mouse is over my dropdown and vanishes after I remove my mouse from the dropdown list.
The categories that I'm getting from backend in the form of an array are
Men
Home&Furniture
Electronics
The dropdown I am getting for these categories-
For Men-Shoes, Watches
For Electronics - Smartwatches, Laptops
home.component.html File
<div class="col-7">
<ul class="row list">
<ng-container *ngFor='let item of menus'>
<li class="px-3 Menu" (mouseover)='overMenu(item.name)'
(mouseout)='leaveMenu(item.name)' >{{item.name}}
<img class="caret ml-1" src="../../../assets/angle-arrow-down.png">
<div class="sub-menu">
<ul class="list2" *ngIf="item.name === 'Men' && flag">
<ng-container *ngFor='let i of arr'>
<li class="text-center">{{i.mensubcat}}</li>
</ng-container>
</ul>
<ul class="list2" *ngIf="item.name === 'Home&Furniture' && flag2">
<ng-container *ngFor='let i of arr'>
<li class="text-center">{{i.mensubcat}}</li>
</ng-container>
</ul>
<ul class="list2" *ngIf="item.name === 'Electronics' && flag2">
<ng-container *ngFor='let i of arr'>
<li class="text-center">{{i.esubcat}}</li>
</ng-container>
</ul>
</div>
</li>
</ng-container>
</ul>
</div>
home.component.css File
.list {
display: flex;
list-style: none;
justify-content: flex-start;
align-items: center;
position: relative;
}
.Menu
{
padding: 9px 20px;
}
.Menu:hover
{
color: rgb(9, 128, 240);
}
.Menu:hover > .caret {
color: rgb(9, 128, 240);
transform: rotate(180deg);
transition: 0.2s;
}
.list2 {
list-style: none;
position: absolute;
line-height: 37px;
display: block;
z-index: 4;
padding: 10px;
background-color: #e1e2e5e3;
border-radius: 5px;
width: 20%;
color:black;
/* padding-left: 0; */
}
home.component.ts File
overMenu(name){
if(name === "Men"){
this.flag = true
}
else if(name === 'Electronics'){
this.flag2 = true
}
}
leaveMenu(name) {
if(name === 'Men'){
this.flag = false
}
else if(name === 'Electronics'){
this.flag2 = false
}
}

I tried with mouseleave instead of mouseout and it did work.
here is the stackblitz i tried

Related

How to wrap text in a option inside select box

How to wrap text in a option inside select box? you can see the given below image
<div class=" assignment">
<div style="display: flex;">
<i class="fa fa-cube"></i> <strong>Dropdown</strong>
<select id="" class="" style="/* width: 50%; */overflow: hidden; overflow-wrap: break-word; width: 100%;">
<option id="default" value="">Select PickUp Point</option>
<option value="B-01-62,Room - Bereich IT Site Service,Mooswaldallee 1, FREIBURG, , 79090, Pickup Timings - Mo-Fr: 09:00-12:00 and 13:00-16:00" ;">Bccnew-01-62,Room - Bereich coupan Site university,Mooswalgfr ghytdallee 1, FREIBBNHRYURG, , 7900090, Pickup Timings - Mo-Fr: 09:00-12:00 and 13:00-16:00</option>
</select>
<span> </span> <br> <br> <button id="digitalDeliverybtn" class="button pull-right">Submit</button>
</div>
</div>
enter image description here
You can simulate a select box and style it any way you want.
const sel = document.querySelector("#selected");
/* Create an array with the options */
const opt = [...document.querySelectorAll(".option")];
const inp = document.querySelector("#sel");
sel.addEventListener("click", () => {
const opts = document.querySelector("#options");
if (opts.classList.contains("open")) {
/* If the <ul> is visible, hide it */
opts.classList.remove("open");
} else {
/* If the <ul> is hidden, show it */
opts.classList.add("open");
}
});
opt.forEach((e, i, o) => {
/* Add an event listener for each option */
o[i].addEventListener("click", () => {
/* Store the value of the option in a variable */
const chosen = e.querySelector("span").innerHTML;
const opts = document.querySelector("#options");
/* Assign the value of the option to the select box */
sel.innerHTML = chosen;
/* Assign the value of the option to the hidden input field */
inp.value = chosen;
/* And close the <ul> */
opts.classList.remove("open");
});
})
.container {
display: flex;
flex-wrap: wrap;
width: 25%;
}
#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;
}
#options.open {
display: inline-block;
}
li {
display: flex;
justify-content: flex-start;
align-items: center;
cursor: pointer;
width: 500px;
}
li:hover {
background-color: yellow;
}
li>img {
margin-right: 1em;
}
<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 id="selected">Select PickUp Point</div>
<ul id="options">
<li class="option"><span>Bccnew-01-62,Room - Bereich coupan Site university,Mooswalgfr ghytdallee 1, FREIBBNHRYURG, , 7900090, Pickup Timings - Mo-Fr: 09:00-12:00 and 13:00-16:00</span></li>
</ul>
</div>
</form>
You cannot directly wrap text in a select box option. However, you can simulate this effect by using a combination of CSS and JavaScript.
First, you will need to set the select box width:
<select style="width:200px;">
Then, you will need to apply a style to the option so that the text wraps:
<option style="white-space:normal;">
Finally, you will need to use JavaScript to detect when the option is selected and dynamically adjust the select box width based on the length of the text:
$('select').on('change', function(){ $(this).css('width', this.value.length * 10); });

JSX Full Navbar Size

Why when I make a navbar using next.js with react that the navbar isn't the full length? Like why isn't the navbar width 100%?
Here is the SCSS Styles:
$color-navbar-text: #000000;
$color-navbar-border: #303030;
$color-navbar-background: #707070;
/* Styles */
.navbar {
color: $color-navbar-text;
height: 60px;
display: flex;
padding: 0px 7.5%;
background: $color-navbar-background;
align-items: center;
justify-content: space-between;
.nList {
display: flex;
list-style: none;
align-items: center;
.nlItem {
.nliLink {
margin: 0px 25px;
text-decoration: none;
}
}
}
}
Here is the JSX component:
import Link from "next/link";
import moduleStyles from "../styles/Navbar.module.scss";
const Navbar = () => {
return (
<nav
className = { moduleStyles.navbar }
>
<h3>
Hello
</h3>
<ul
className = { moduleStyles.nList }
>
<li
className = { moduleStyles.nlItem }
>
<Link
href = "/"
>
<a
className = { moduleStyles.nliLink }
>
Home
</a>
</Link>
</li>
<li
className = { moduleStyles.nlItem }
>
<Link
href = "/"
>
<a
className = { moduleStyles.nliLink }
>
Home
</a>
</Link>
</li>
<li
className = { moduleStyles.nlItem }
>
<Link
href = "/"
>
<a
className = { moduleStyles.nliLink }
>
Home
</a>
</Link>
</li>
</ul>
<button>
Login
</button>
</nav>
);
}
export default Navbar;
I don't know how the navbar isn't full size because when I worked on another project it is full size. I think it might have to do with the flexbox or something.
Image

How to customize ion-range in ionic 5?

I am looking for a solution with my current issue regarding on how to customize the ion-range based on the wireframe. As you can see below the difference between the wireframe and the actual worked I made.
Wireframe Design
My actual work
Above, you can see the difference between the two. My question is, is there anyway or solution that I can do to get the actual look of the wireframe. Based on the wireframe, as the user moves the tick, the label aligned with the tick should be color blue also.
These are my codes I used and produced my actual work.
.html
<div class="slidecontainer">
<ion-range
class="range-position"
min="5"
max="100"
dualknobs="true"
pin="false"
snaps="true"
ticks="false"
value="0"
snaps color="primary"
list='tickmarks'>
</ion-range>
<div id="tickmarks" class="tick-position">
<p>5</p>
<p>10</p>
<p>25</p>
<p>50</p>
<p>75</p>
<p>100</p>
</div>
</div>
.scss
// Customize Slider
#tickmarks {
display: flex;
justify-content: space-between;
padding: 0 25px;
}
#tickmarks p {
position: relative;
display: flex;
justify-content: center;
text-align: center;
width: 1px;
background: #ccd3da;
height: 10px;
line-height: 40px;
margin: 0 0 20px 0;
font-family: 'Archivo';
font-size: 12px;
}
Hope you can help so that I can move forward with my task. Thank you so much
You can Use (ionChange) event to make it work.
<ion-range
class="range-position"
min="5"
max="100"
dualknobs="true"
pin="false"
snaps="true"
ticks="false"
value="0"
step="25" // use step attribute for sure event value
snaps color="primary"
list='tickmarks'
(ionChange)="changeFunction($event)">
</ion-range>
<div id="tickmarks" class="tick-position">
<p [ngClass]="selectedValue == 0 ? 'active' : null">5</p>
<p [ngClass]="selectedValue == 25 ? 'active' : null">25</p>
<p [ngClass]="selectedValue == 50 ? 'active' : null">50</p>
<p [ngClass]="selectedValue == 75 ? 'active' : null">75</p>
<p [ngClass]="selectedValue == 100 ? 'active' : null">100</p>
</div>
.ts
selectedValue;
changeFunction($event){
this.selectedValue = $event.detail.value;
}
You can have the the tick marks underneath the ion-range component react to the selected value in the range, like below.
Add a function that listens to the ionChange event to <ion-change>. Use that function in your component class to update a value. Then you can use that value in your template to indicate which tick should be highlighted (gets the selected CSS class).
range.component.html - for single range (one knob)
<div class="range-container">
<ion-range
(ionChange)="setValue($event)"
[value]="currentValue"
color="primary"
dual-knobs="false"
max="100"
min="0"
pin="false"
snaps="true"
step="25"
ticks="false"
>
</ion-range>
<ul class="tick-marks">
<li
*ngFor="let number of [0, 25, 50, 75, 100]"
[class.selected]="number === currentValue"
>
{{number}}
</li>
</ul>
</div>
range.component.html - for dual knobs
<div class="range-container">
<ion-range
(ionChange)="setDualValues($event)"
[value]="currentDualValues"
color="primary"
dual-knobs="true"
max="100"
min="0"
pin="false"
snaps="true"
step="25"
ticks="false"
>
</ion-range>
<ul class="tick-marks">
<li
*ngFor="let number of [0, 25, 50, 75, 100]"
[class.selected]="number === currentDualValues.lower || number === currentDualValues.upper"
>
{{number}}
</li>
</ul>
</div>
range.component.ts- the component file
#Component({
selector: 'app-range',
styleUrls: ['./range.component.scss']
templateUrl: './range.component.html'
})
export class RangeComponent {
currentValue = 0;
currentDualValues = {
lower: 25,
upper: 50
};
// use this for single slider
setValue($event: Event): void {
this.currentValue = parseInt(($event.target as HTMLInputElement).value, 10);
}
// use this for dual sliders (dual knobs)
setDualValues($event: Event): void {
this.currentDualValues = JSON.parse(JSON.stringify(($event.target as HTMLInputElement).value));
}
}
Finally, in your CSS add the .selected class to style selected numbers as you wish, for instance like this (you will probably need to change padding of ul.tick-marks to make sure the tick marks align properly with the range selector):
range.component.scss
.range-container {
display: flex;
flex-direction: column;
width: 100%;
.tick-marks {
display: flex;
justify-content: space-between;
list-style: none;
margin: 0;
padding: 0;
li {
color: var(--ion-color-dark);
position: relative;
&::before {
background-color: var(--ion-color-dark);
content: '';
display: block;
height: 20px;
left: 50%;
position: absolute;
width: 1px;
top: -20px;
}
&.selected {
color: var(--ion-color-primary);
&::before {
background-color: var(--ion-color-primary);
}
}
}
}
}
See also this stackblitz for reference.

The Content should be Moved When the Sidenav bar Menu Appear

Goal:
When you click on the icon menu in the header toolbar, it should be expanded and the content of "<mat-sidenav-content>" should be moved more to the right due to the space of the sidenav menu.
Problem:
When clicking on the icon menu the content of "<mat-sidenav-content>" doesn't move to the right side direction due to the expansion space of the sidenavemenu. The content is static when you expand the sidenav bar menu.
What part am I missing?
Info:
*Using angular 9
*A example of a content that will be moved when you make the sidebar nav menu to appear.
(https://stackblitz.com/angular/qoaqpenxjqy)
*When the menu is not expanded, the icon should appear and not the text.
Stackblitz:
https://stackblitz.com/edit/angular-ymkpvj-hso3tw
Thank you!
<mat-toolbar color="primary" class="example-toolbar">
<button mat-icon-button (click)="isExpanded = !isExpanded" >
<mat-icon>menu</mat-icon>
</button>
<h1 class="example-app-name">Nested Menus</h1>
</mat-toolbar>
<mat-sidenav-container class="example-container" >
<mat-sidenav #sidenav class="example-sidenav"
mode="side"
opened="true"
(mouseenter)="mouseenter()"
(mouseleave)="mouseleave()"
>
<mat-nav-list>
<mat-list-item (click)="showSubmenu = !showSubmenu" class="parent">
<mat-icon mat-list-icon>home</mat-icon>
<span class="full-width" *ngIf="isExpanded || isShowing">Parent Menu</span>
<mat-icon class="menu-button" [ngClass]="{'rotated' : showSubmenu}" *ngIf="isExpanded || isShowing">expand_more</mat-icon>
</mat-list-item>
<div class="submenu" [ngClass]="{'expanded' : showSubmenu}" *ngIf="isShowing || isExpanded">
<a mat-list-item href="...">Submenu Item 1</a>
<a mat-list-item href="...">Submenu Item 2</a>
<mat-list-item (click)="showSubSubMenu = !showSubSubMenu" class="parent">
<span class="full-width" *ngIf="isExpanded || isShowing">Nested Menu</span>
<mat-icon class="menu-button" [ngClass]="{'rotated' : showSubSubMenu}" *ngIf="isExpanded || isShowing">expand_more</mat-icon>
</mat-list-item>
<div class="submenu" [ngClass]="{'expanded' : showSubSubMenu}" *ngIf="isShowing || isExpanded">
<mat-list-item>SubSubmenu Item 1</mat-list-item>
<mat-list-item>SubSubmenu Item 2</mat-list-item>
</div>
</div>
</mat-nav-list>
<mat-nav-list>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>
test test test test test test test
</mat-sidenav-content>
</mat-sidenav-container>
<!-- Copyright 2017 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license -->
import {Component, ViewChild} from '#angular/core';
import {FormBuilder, FormGroup} from '#angular/forms';
/** #title Fixed sidenav */
#Component({
selector: 'sidenav-fixed-example',
templateUrl: 'sidenav-fixed-example.html',
styleUrls: ['sidenav-fixed-example.css'],
})
export class SidenavFixedExample {
/**
options: FormGroup;
constructor(fb: FormBuilder) {
this.options = fb.group({
bottom: 0,
fixed: false,
top: 0
});
}
*/
constructor() {}
events: string[] = [];
isExpanded = true;
showSubmenu: boolean = false;
isShowing = false;
showSubSubMenu: boolean = false;
mouseenter() {
if (!this.isExpanded) {
this.isShowing = true;
}
}
mouseleave() {
if (!this.isExpanded) {
this.isShowing = false;
}
}
}
.example-container {
height: 500px;
border: 1px solid rgba(0, 0, 0, 0.5);
}
.example-sidenav-content {
display: flex;
height: 100%;
align-items: center;
justify-content: center;
}
.example-sidenav {
user-select: none;
}
.full-width {
width: 100%;
}
.menu-button {
transition: 300ms ease-in-out;
transform: rotate(0deg);
}
.menu-button.rotated {
transform: rotate(180deg);
}
.submenu {
overflow-y: hidden;
transition: transform 300ms ease;
transform: scaleY(0);
transform-origin: top;
padding-left: 30px;
}
.submenu.expanded {
transform: scaleY(1);
}
Demo make opened propery isExpanded
[opened]="isExpanded"
but if you want to show small icon while closing then you need to change css. Because navigation position is absolute but, content is relative. and content changes with margin-left property to opened property value.
Possible solution
make both position relative and remove margin-left property for content in true condition of opened
.mat-sidenav{
position: relative !important;
height: 100%;
overflow: auto;
float: left;
}
.mat-drawer-content {
margin-left: 0 !important;
}
you should put them inside style.css. Demo

Change the color of the timeline in different states

I developed a timeline with 4 levels. When I click on each of the levels, the timeline is filled with green color. Would it be possible to change this color in different types of states?
In state 4 I have the circle and the lines green, how can I change this color in the remaining 3?
That is, in 3 I want yellow color, in 2 green color 3 in 1 red color.
In the image, I leave an example of what I want
Can anyone help me?
HTML
<ul class="timeline" id="timeline" >
<li class="li" [ngClass]="priority['isComplete']?'complete':''" *ngFor="let priority of Priorities; let p = index;">
<div class="timestamp">
</div>
<div class="status">
<span class="circle" (click)="changeTimeline(priority.id)">{{priority.id}}</span>
<h4 class="timelineh4">{{priority.text}}</h4>
</div>
</li>
</ul>
Component
public Priorities:Array<Object> = [
{id: 4, text: '',isComplete:true},
{id: 3, text: '',isComplete:true},
{id: 2, text: '',isComplete:true},
{id: 1, text: '',isComplete:true},
];
I have change your method of calculate the selected level to save the selected state.
this this.selectedPrioroties = prio; will set the current state and I have create a css classes base of the selected text
public changeTimeline(prio) {
this.selectedPrioroties = prio;
this.selectedState = String(prio.text).toLowerCase().replace(' ','-');
}
base of the selectedState low , mid-low ,mid ,high I create a set of classes in the css file app.component.css
.circle {
border: none;
transition: all 200ms ease-in;
}
.low li:nth-child(1) .circle {
background-color: #66DC71;
}
.mid-low li:nth-child(1) .circle ,.mid-low li:nth-child(2) .circle {
background-color: #ffeb3b;
}
.mid li:nth-child(1) .circle ,.mid li:nth-child(2) .circle ,.mid li:nth-child(3) .circle {
background-color: #2196f3;
}
.high li:nth-child(1) .circle ,.high li:nth-child(2) .circle ,.high li:nth-child(3) .circle ,.high li:nth-child(4) .circle {
background-color: #ff5722;
}
template
<ul class="timeline" id="timeline" [ngClass]="selectedState" >
<li class="li" *ngFor="let priority of Priorities; let p = index;">
<div class="timestamp">
</div>
<div class="status">
<span class="circle" (click)="changeTimeline(priority)">{{priority.id}}</span>
<h4 class="timelineh4">{{priority.text}}</h4>
</div>
</li>
</ul>
demo 🚀