How to make the inactive tabs unclickable - javascript

I have these tabs but is it possible to make the other inactive tabs to be unclickable?
<div class="navbar">
<div class="navbar-inner">
<ul class="nav nav-tabs" style="display:inline-flex">
<li class="active">Step 1</li>
<li>Step 2</li>
<li>Step 3</li>
<li>Step 4</li>
<li>Step 5</li>
<li>Step 6</li>
<li>Step 7</li>
</ul>
</div>
</div>

To get the best result you can:
Add the disabled class to the li element
Remove the data-toggle attribute for the a
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<div class="navbar">
<div class="navbar-inner">
<ul class="nav nav-tabs" style="display:inline-flex">
<li class="active">Step 0</li>
<li>Step 1</li>
<li class="disabled"><a href="#step2" >Step 2</a></li>
<li class="disabled"><a href="#step3" >Step 3</a></li>
<li class="disabled"><a href="#step4" >Step 4</a></li>
</ul>
</div>
</div>

You can use :not() CSS selector with pointer-events: none; to disable click event.
li:not(.active) a{
pointer-events: none;
}
<div class="navbar">
<div class="navbar-inner">
<ul class="nav nav-tabs" style="display:inline-flex">
<li class="active">Step 1</li>
<li>Step 2</li>
<li>Step 3</li>
<li>Step 4</li>
<li>Step 5</li>
<li>Step 6</li>
<li>Step 7</li>
</ul>
</div>
</div>

Simply add this class to the tabs that you want to disable the clicks.
Here is the css.
.avoid-clicks {
pointer-events: none;
}

disable them all and enable the active one
$('li').prop('disabled',true);
$('.active').prop('disabled',false);

To disable the links on the fly using jquery try this:
$(document).ready(function(){
$("a").click(function(event){
event.preventDefault();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
Go to google

You can add the following rules to your non-active items to make them unclickable. This was suggested in the following post:
How to disable all div content
.disabled, li:not(.active) {
pointer-events: none;
opacity: 0.4;
}
ul {
display: inline-flex;
width: 100%;
list-style-type: none;
margin: 0;
padding: 0;
height: 1em;
line-height: 1em;
}
li {
width: 14%;
height: 2em;
margin: 0.1%;
line-height: 2em;
background-color: #FFF;
border: thin solid #777;
text-align: center;
}
li a {
display: block;
width: 100%:
height: 100%;
text-decoration: none;
}
li a, li a:active, li:visited {
color: #48A;
}
li a:hover {
color: #5AC;
text-decoration: underline;
}
.active {
background-color: #FFF;
font-weight: bold;
border: thin solid #DDD;
}
.disabled, li:not(.active) {
background-color: #AAA;
pointer-events: none;
opacity: 0.4;
}
<div class="navbar">
<div class="navbar-inner">
<ul class="nav nav-tabs">
<li class="active">Step 1</li>
<li>Step 2</li>
<li>Step 3</li>
<li>Step 4</li>
<li>Step 5</li>
<li>Step 6</li>
<li>Step 7</li>
</ul>
</div>
</div>

Related

Setting Floating UI shift on multiple elements

I want to use Floating UI to prevent dropdown menus from going off the left/right edge of the screen. The example code is as follows:
HTML:
<ul class="menu">
<li class="menu__item">
Item 1
<ul class="submenu">
<li>Item 1.1</li>
<li>Item 1.2</li>
<li>Item 1.3</li>
<li>Item 1.4</li>
<li>Item 1.5</li>
</ul>
</li>
<li class="menu__item">
Item 2
<ul class="submenu">
<li>Item 2.1</li>
<li>Item 2.2</li>
<li>Item 2.3</li>
<li>Item 2.4</li>
<li>Item 2.5</li>
</ul>
</li>
<li class="menu__item">
Item 3
<ul class="submenu">
<li>Item 3.1</li>
<li>Item 3.2</li>
<li>Item 3.3</li>
<li>Item 3.4</li>
<li>Item 3.5</li>
</ul>
</li>
<li class="menu__item">
Item 4
<ul class="submenu">
<li>Item 4.1</li>
<li>Item 4.2</li>
<li>Item 4.3</li>
<li>Item 4.4</li>
<li>Item 4.5</li>
</ul>
</li>
<li class="menu__item">
Item 5
<ul class="submenu">
<li>Item 5.1</li>
<li>Item 5.2</li>
<li>Item 5.3</li>
<li>Item 5.4</li>
<li>Item 5.5</li>
</ul>
</li>
</ul>
CSS:
* {
margin: 0;
padding: 0;
}
ul {
list-style-type: none;
display: flex;
}
a {
color: inherit;
text-decoration: none;
}
.menu {
display: flex;
gap: 5px;
justify-content: space-around;
color: white;
}
.menu > li {
position: relative;
background: blue;
padding: 0 30px;
height: 40px;
}
.submenu {
display: none;
position: absolute;
left: 50%;
top: 40px;
transform: translateX(-50%);
background: red;
}
.menu > li:hover .submenu {
display: flex;
}
.submenu li {
padding: 10px 20px;
}
.submenu a {
white-space: nowrap;
}
JS:
import { autoUpdate, computePosition, shift } from "https://cdn.skypack.dev/#floating-ui/dom#1.2.0";
const menuItems = document.querySelectorAll('.menu__item');
menuItems.forEach((item) => {
const reference = item.querySelector('.menu__link');
const floating = item.querySelector('.submenu');
computePosition(reference, floating, {
placement: "bottom",
middleware: [shift()]
}).then(({ x, y }) => {
Object.assign(floating.style, {
left: `${x}px`
});
});
});
There's a CodePen here.
However, I'm struggling to understand the documentation and the implementation I have doesn't seem to work. The red dropdowns should be center-aligned under the blue items where possible but Floating UI should adjust the positioning horizontally so that the first dropdown should have its left edge aligned to the left of the screen and the last dropdown should have its right edge aligned to the right of the screen.
Could anyone advise how to get this working and ensure that it maintains the correct positioning even after window resizing?
Many thanks.

I wanna show an element when hovering it using Jquery but even though it recognizes the event it won´t work

So, i've seen some other answers for similar stuff, but nothing that really helps or even works, I've tried to follow every step people said in other posts but nothing helped.
I wanna show a sub menu when I hover over it by removing the class hidden that it is defining its display to hiden, but I can´t make it using only css and, even though my js code recognizes that the mouse is hovering through it, it won´t budge.
So, here's my codes
$(".dropdown").hover(function() {
console.log('hover in');
$(".dropdown-content").removeClass("hidden");
console.log('hover out');
$(".dropdown-content").addClass("hidden");
})
.hidden {
display: none;
}
.menu-desktop {
position: absolute;
left: 70%;
list-style-type: none;
}
.menu-desktop ul {
margin: 0;
padding: 0;
list-style: none;
}
.menu-desktop a {
display: inline;
float: left;
margin-left: 5px;
color: #bcbcbc;
text-align: center;
text-transform: uppercase;
text-decoration: none;
background-color: transparent;
border-radius: 0%;
border-color: transparent;
}
.menu-desktop a:hover {
color: #858181
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
}
.dropdown-content .shown {
position: absolute;
background-color: blue;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
padding: 12px 16px;
z-index: 1;
}
.dropdown:hover .dropdown-content {
display: block !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav class="navbar-itens">
<div class="logo">
<img src="assets/9mnb2mazqne71.png" alt="">
</div>
<!-- Navigation menu -->
<ul id="nav" class="menu-desktop">
<li>HOME</li>
<li class="dropdown">EMPRESA</li>
<ul id="submenu" class="dropdown-content hidden">
<li>submenu 1</li>
<li>submenu 1</li>
<li>submenu 1</li>
<li class="dropdown">submenu 1</li>
<ul id="submenu2" class="dropdown-content hidden">
<li>submenu 2</li>
<li>submenu 2</li>
<li>submenu 2</li>
<li>submenu 2</li>
</ul>
</ul>
<li>CLIENTES</li>
<li>CONTATO</li>
</ul>
</nav>
EDIT: Forgot to include my css, so, here it is!
You need to declare function inside hover() to handle hover in & out event:
$( ".dropdown" ).hover(
function() {
$(".dropdown-content").removeClass("hidden");
}, function() {
$(".dropdown-content").addClass("hidden");
}
);
The problems with your code
Main problem
You immediately add the class back after removing it, so you never see the dropdown content.
jQuery's .hover() expects two function arguments (first is run when mouse enters, second when mouse leaves).
direct-child-only problem
Second problem with your code is that it toggles the class on all submenus while the one you want is only the direct, immediate child of the list item being hovered. You can use
$(this).find(".dropdown-content").first()
to only affect the sub-ul you want. Alternatively, instead of .first(), you can also use .eq(0).
Invalid html problem
Please also note that ul can only have li children, so you need to wrap any sub-ul inside an li.
The solution to not use
$(".dropdown").hover(
function() {
$(this).find(".dropdown-content").first().removeClass("hidden");
},
function() {
$(this).find(".dropdown-content").eq(0).addClass("hidden");
}
);
.hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="nav" class="menu-desktop">
<li>HOME</li>
<li class="dropdown">EMPRESA
<ul id="submenu" class="dropdown-content hidden">
<li>submenu 1</li>
<li>submenu 1</li>
<li>submenu 1</li>
<li class="dropdown">submenu 1
<ul id="submenu2" class="dropdown-content hidden">
<li>submenu 2</li>
<li>submenu 2</li>
<li>submenu 2</li>
<li>submenu 2</li>
</ul>
</li>
</ul>
</li>
<li>CLIENTES</li>
<li>CONTATO</li>
</ul>
The solution to use is CSS only
That being said, you don't need any JavaScript for this, and you shouldn't be using JS for a CSS job:
.dropdown-content {
display: none;
}
.dropdown:hover > .dropdown-content {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="nav" class="menu-desktop">
<li>HOME</li>
<li class="dropdown">EMPRESA
<ul id="submenu" class="dropdown-content">
<li>submenu 1</li>
<li>submenu 1</li>
<li>submenu 1</li>
<li class="dropdown">submenu 1
<ul id="submenu2" class="dropdown-content">
<li>submenu 2</li>
<li>submenu 2</li>
<li>submenu 2</li>
<li>submenu 2</li>
</ul>
</li>
</ul>
</li>
<li>CLIENTES</li>
<li>CONTATO</li>
</ul>

How can I restrict jQuery UI connected lists drag and drop to single direction

I am using jQuery UI Connectedlist
Here drag and drop is working fine with both side from left to right and right to left.
How can I disable right to left ? It has to work only one way, from left to right.
I need also sorting to still work inside ul yellow items like in grey items.
$(function() {
$( "#sortable1, #sortable2" ).sortable({
connectWith: ".connectedSortable"
}).disableSelection();
});
#sortable1, #sortable2 {
border: 1px solid #eee;
width: 142px;
min-height: 20px;
list-style-type: none;
margin: 0;
padding: 5px 0 0 0;
float: left;
margin-right: 10px;
}
#sortable1 li, #sortable2 li {
margin: 0 5px 5px 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
}
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Sortable - Connect lists</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<body>
<ul id="sortable1" class="connectedSortable">
<li class="ui-state-default">Item 1</li>
<li class="ui-state-default">Item 2</li>
<li class="ui-state-default">Item 3</li>
<li class="ui-state-default">Item 4</li>
<li class="ui-state-default">Item 5</li>
</ul>
<ul id="sortable2" class="connectedSortable">
<li class="ui-state-highlight">Item 1</li>
<li class="ui-state-highlight">Item 2</li>
<li class="ui-state-highlight">Item 3</li>
<li class="ui-state-highlight">Item 4</li>
<li class="ui-state-highlight">Item 5</li>
</ul>
</body>
</html>
You could cancel the drag event in the right list sortable2 using receive event in sortable1 to prevent receiving any item from second list.
To drag grey lis back to the left side we will add helper class e.g s2 that will identify the sortable2 original items and cancel the drag only on them :
$("#sortable1").sortable({
receive: function(ev, ui) {
if(ui.item.hasClass("s2"))
ui.sender.sortable("cancel");
}
});
Hope this helps.
$(function() {
$( "#sortable1, #sortable2" ).sortable({
connectWith: ".connectedSortable"
}).disableSelection();
$("#sortable1").sortable({
receive: function(ev, ui) {
if(ui.item.hasClass("s2"))
ui.sender.sortable("cancel");
}
});
});
#sortable1, #sortable2 {
border: 1px solid #eee;
width: 142px;
min-height: 20px;
list-style-type: none;
margin: 0;
padding: 5px 0 0 0;
float: left;
margin-right: 10px;
}
#sortable1 li, #sortable2 li {
margin: 0 5px 5px 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
}
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Sortable - Connect lists</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<body>
<ul id="sortable1" class="connectedSortable">
<li class="ui-state-default">Item 1</li>
<li class="ui-state-default">Item 2</li>
<li class="ui-state-default">Item 3</li>
<li class="ui-state-default">Item 4</li>
<li class="ui-state-default">Item 5</li>
</ul>
<ul id="sortable2" class="connectedSortable">
<li class="ui-state-highlight s2">Item 1</li>
<li class="ui-state-highlight s2">Item 2</li>
<li class="ui-state-highlight s2">Item 3</li>
<li class="ui-state-highlight s2">Item 4</li>
<li class="ui-state-highlight s2">Item 5</li>
</ul>
</body>
</html>
Currently your connectWith selector matches both the sortable, i.e it's a two way connection. If you only want one way connection from left to right, just connect the left sortable to right sortable using a more specific selector (#sortable2) than a common one:
$(function() {
$("#sortable1").sortable({
connectWith: "#sortable2"
}).disableSelection();
$("#sortable2").sortable({}).disableSelection();
});
The demo below has the shorter code that does the same thing:
$(function() {
$(".connectedSortable").sortable({
connectWith: "#sortable2"
//----------^---------- #sortable2 connectWith #sortable2 has no effect
}).disableSelection();
});
#sortable1,
#sortable2 {
border: 1px solid #eee;
width: 142px;
min-height: 20px;
list-style-type: none;
margin: 0;
padding: 5px 0 0 0;
float: left;
margin-right: 10px;
}
#sortable1 li,
#sortable2 li {
margin: 0 5px 5px 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
}
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<ul id="sortable1" class="connectedSortable">
<li class="ui-state-default">Item 1</li>
<li class="ui-state-default">Item 2</li>
<li class="ui-state-default">Item 3</li>
<li class="ui-state-default">Item 4</li>
<li class="ui-state-default">Item 5</li>
</ul>
<ul id="sortable2" class="connectedSortable">
<li class="ui-state-highlight">Item 1</li>
<li class="ui-state-highlight">Item 2</li>
<li class="ui-state-highlight">Item 3</li>
<li class="ui-state-highlight">Item 4</li>
<li class="ui-state-highlight">Item 5</li>
</ul>
The options you are looking for are cancel and update (s2 inspired by the post above), it will disable the drag on matched elements.
$(function() {
$( "#sortable1, #sortable2" ).sortable({
connectWith: ".connectedSortable",
cancel: ".ui-state-highlight, .s2",
update: function( event, ui ) {ui.item.addClass("s2");}
}).disableSelection();
});

Multi-level dropdown navigation - keep secondary dropdown closed

so I am relatively new to coding and I am trying to make a multilevel dropdown menu, that when opened shows the links for the first level but doesn't show the second level links until clicked.
I started with a fork from codepen and have the navigation built, but I do not know what script to add to close the secondary links.
// open mobile menu
$('.js-toggle-menu').click(function(e){
e.preventDefault();
$('.mobile-header-nav').slideToggle();
$(this).toggleClass('open');
});
$('.sub-toggle').click(function(e){
e.preventDefault();
$('.subnav1').slideToggle();
$(this).toggleClass('open');
});
$('.sub-toggle2').click(function(e){
e.preventDefault();
$('.subnav2').slideToggle();
});
$('.sub-toggle3').click(function(e){
e.preventDefault();
$('.subnav3').slideToggle();
});
* {
box-sizing: border-box;
}
#media (min-width: 768px) {
.mobile-nav-wrap {
/* display: none; */
}
}
.mobile-header-nav {
background-color: #222222;
display: none;
list-style: none;
margin: 0;
padding: 0;
position: absolute;
top: 100px;
width: 100%;
}
.mobile-header-nav li {
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.mobile-header-nav li a {
color: white;
display: block;
padding: 15px 15px;
text-align: left;
text-decoration: none;
-webkit-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
}
.mobile-header-nav li a:hover {
background-color: #2f2f2f;
}
a.mobile-menu-toggle {
padding-left: 50px;
color: #52575f;
text-decoration: none;
background: #eeeff0;
font-size: 3em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<header>
<nav class="mobile-nav-wrap" role="navigation">
<ul class="mobile-header-nav">
<li>
Overview
<ul class="subnav1">
<li>Nav Item 1</li>
<li>Nav Item 2</li>
<li>Nav Item 3</li>
</ul>
</li>
<li><a class="sub-toggle2" href="#">Resources</a>
<ul class="subnav2">
<li>Nav Item 1</li>
<li>Nav Item 2</li>
<li>Nav Item 3</li>
</ul>
</li>
<li><a class="sub-toggle3" href="#">Service</a>
<ul class="subnav3">
<li>Nav Item 1</li>
<li>Nav Item 2</li>
<li>Nav Item 3</li>
</ul>
</li>
</ul>
</nav>
<a class="mobile-menu-toggle js-toggle-menu" href="#">
Get Started
</a>
</header>
The codepen that I am working on can be found here:
Codepen Link
Any advice is welcome
You can just add some CSS to hide the sub nav initially, like this:
.subnav1, .subnav2, .subnav3 {
display: none;
}
You may want to also change the classes so they are a little more generic, like just use a class of subnav and sub-toggle instead of subnav1, sub-toggle2, etc. Then you can have just one CSS rule and one event handler regardless of how many menu items you add. So your CSS for hiding the sub nav would just be:
.subnav {
display: none;
}
And your javascript to toggle all of the menu items is reduced to just:
$('.sub-toggle').click(function(e){
$(this).next('.subnav').slideToggle();
$(this).toggleClass('open');
});
I updated your code pen with an example here.
You may try this. The changes are only done to js logic.
Also, I'm not sure why you have e.preventDefault(). You only need it if you are trying to avoid submit a form. So I took them out.
<header>
<nav class="mobile-nav-wrap" role="navigation">
<ul class="mobile-header-nav">
<li>
Overview
<ul class="subnav">
<li>Nav Item 1</li>
<li>Nav Item 2</li>
<li>Nav Item 3</li>
</ul>
</li>
<li><a class="sub-toggle" href="#">Resources</a>
<ul class="subnav">
<li>Nav Item 1</li>
<li>Nav Item 2</li>
<li>Nav Item 3</li>
</ul>
</li>
<li><a class="sub-toggle" href="#">Service</a>
<ul class="subnav">
<li>Nav Item 1</li>
<li>Nav Item 2</li>
<li>Nav Item 3</li>
</ul>
</li>
</ul>
</nav>
<a class="mobile-menu-toggle js-toggle-menu" href="#">
Get Started
</a>
</header>
<script>
$().ready(function()
{
$('.js-toggle-menu').click(function(e){
$('.sub-toggle').slideToggle();
$('.sub-toggle').each(function()
{
$(this).closest('li').find('.subnav').hide();
});
});
$('.sub-toggle').click(function(){
$(this).closest('li').find('.subnav').slideToggle();
});
});
</script>

How to make “See all category” link button to display rest of the text with jquery 1.11 and above

I have an issue on the dropdown text.
Below snippet using jquery 1.11.1
$(".more").toggle(function(){
$(this).text("Less category").siblings(".complete").show();
}, function(){
$(this).text(" All category").siblings(".complete").hide();
});
.complete{
display:none;
}
.more{
background:black;
color:red;
font-size:13px;
padding:3px;
cursor:pointer;
}
li{
list-style:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>kategori 1</li>
<li>kategori 2</li>
<li class="complete">kategori 3</li>
<li class="complete">kategori 4</li>
<li class="complete">kategori 5</li>
<li class="more">See all category</li>
</ul>
Below snippet using jquery 1.8.3
$(".more").toggle(function(){
$(this).text("Less category").siblings(".complete").show();
}, function(){
$(this).text(" All category").siblings(".complete").hide();
});
.complete{
display:none;
}
.more{
background:black;
color:red;
font-size:13px;
padding:3px;
cursor:pointer;
}
li{
list-style:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<ul>
<li>kategori 1</li>
<li>kategori 2</li>
<li class="complete">kategori 3</li>
<li class="complete">kategori 4</li>
<li class="complete">kategori 5</li>
<li class="more">See all category</li>
</ul>
Problem is, "See all category" text will disappear if I use jquery 1.9.1 and above.
If I use jquery 1.8.3 and lower "See all category will appear and work just fine.
Can anyone help, thanks anyway :)
You need to use the click handler as this variant of toggle is removed in jQuery 1.9
$(".more").click(function() {
$(this).text(function(i, text) {
return text == 'Less category' ? 'All category' : 'Less category';
}).siblings(".complete").toggle();
});
.complete {
display: none;
}
.more {
background: black;
color: red;
font-size: 13px;
padding: 3px;
cursor: pointer;
}
li {
list-style: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>kategori 1</li>
<li>kategori 2</li>
<li class="complete">kategori 3</li>
<li class="complete">kategori 4</li>
<li class="complete">kategori 5</li>
<li class="more">See all category</li>
</ul>

Categories

Resources