I have some links I'd like to be highlighted when you select them, but only one at a time. I found this JQuery code, however, I can't get it to work. The links won't highlight even when I click it. I had a really straight forward Javascript function that changed the color of the link with the onlick. But I would like for it to only highlight the most recently clicked link.
The new JQuery is presented in the code, it appears like it should work I just don't know why it's not. The Javascript function, selectedLink(), I used to call on the onlick method. I'm willing to use either or, I just want the functionality.
.highlight {
color: #3385D6;
border: 1px solid;
border-color: #BBBBBB;
background:#70AAE2;
font-weight: bold;
}
function selectedLink(id){
var sublink = document.getElementById(id);
sublink.style.background = "#CCCCCC";
sublink.style.color = "#3385D6";
sublink.style.fontWeight = "bold";
sublink.style.border = "1px solid";
sublink.style.borderColor = "#BBBBBB";
}
<input type="radio" name="UItab" id="tabf" >
<label for="tabf"><span>Menu Item</span></label>
<div>
<div>
<ul class="sub-menu">
<li id="">SecondLevel A</li></td>
<li id="">SecondLevel B</li>
<li id="">SecondLevel C</li>
</ul>
</div>
<div id="togglebox">
<li id="">ThirdLevel A</li>
<li id="">ThirdLevel B</li>
<li id="">ThirdLevel C</li>
</div>
<div id="barbox">
<li id="">Fourth Level A</li>
<li id="">Fourth Level B</li>
<li id="">Fourth Level C</li>
</div>
<div id="piebox">
<li id="">Fourth Level A</li>
<li id="">Fourth Level B</li>
<li id="">Fourth Level C</li>
</div>
<script>
$('a').click(
function(e){
e.preventDefault;
$('.highlight').removeClass('highlight');
$(this).addClass('highlight')
});
</script>
Code is fine just wrap around a $(function(){/*here*/});
$(function () {
$('a').click(function (e) {
e.preventDefault();
$('.highlight').removeClass('highlight');
$(e.target).addClass('highlight');
});
});
function selectedLink(id) {
var sublink = document.getElementById(id);
sublink.style.background = "#CCCCCC";
sublink.style.color = "#3385D6";
sublink.style.fontWeight = "bold";
sublink.style.border = "1px solid";
sublink.style.borderColor = "#BBBBBB";
}
function toggle_visibility(s) {}
.highlight {
color: #3385D6;
border: 1px solid;
border-color: #BBBBBB;
background:#70AAE2;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="radio" name="UItab" id="tabf" >
<label for="tabf"><span>Menu Item</span></label>
<div>
<div>
<ul class="sub-menu">
<li id="">SecondLevel A</li>
<li id="">SecondLevel B</li>
<li id="">SecondLevel C</li>
</ul>
</div>
<div id="togglebox">
<li id="">ThirdLevel A</li>
<li id="">ThirdLevel B</li>
<li id="">ThirdLevel C</li>
<li id="">ThirdLevel D</li>
<li id="">ThirdLevel E</li>
<li id="">ThirdLevel F</li>
</div>
<div id="barbox">
<li id="">Fourth Level A</li>
<li id="">Fourth Level B</li>
<li id="">Fourth Level C</li>
</div>
instead of removing class to .highlight, remove class for all a elements
$(a).removeClass('highlight');
It may not be the solution but it looks like you should use e.preventDefault() instead of e.preventDefault
may be this will work:
$(document).ready(function(){
$('a').click(function(e){
e.preventDefault();
//All a tag having class highlight
$('a.highlight').removeClass('highlight');
$(this).addClass('highlight');
});
});
Try this:
$('a').click(
function(e){
e.preventDefault();
$(this).addClass('highlight').siblings().removeClass('highlight');
});
Related
I am trying to make a menu that collapses on click.
I also want to add some more changes on that same function.
For instance I want to change the background of another object.
In this snippet you can see it works on only the first link. The other toggleable link is not targeted.
var pill = document.querySelector(".navpill");
var sub = document.querySelector(".submenu");
pill.onclick = () => {
sub.classList.toggle("collapse");
pill.classList.toggle("active");
}
.mainmenu {
background-color: #1f1f1f;
}
.navpill {
padding: 15px;
}
.navpill.active {
background: red;
}
.navpill a {
text-decoration: none;
color: white;
}
.submenu {
display: none;
}
.submenu.collapse {
display: block;
}
<div>
<ul class="mainmenu">
<li class="navpill">Link collapse 1
<ul class="submenu">
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
</ul>
</li>
<li class="navpill">Link collapse 2
<ul class="submenu">
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
</ul>
</li>
<li class="navpill">no link</li>
<li class="navpill">no link</li>
</ul>
</div>
From a previous answer I got this piece of code which makes it work on all the links, but I have no idea how to add more var and toggles to the function.
var pills = document.querySelectorAll(".expand");
pills.forEach(function(pill) {
pill.onclick = () => {
var sub = pill.querySelector(".submenu");
sub.classList.toggle("collapse");
}
});
I tried adding this to the code but it does not work.
var navpill = pill.querySelector(".navpill");
navpill.classList.toggle("active");
If possible I would also like a way of clearing what has been done when clicked on the next submenu.
If I use the code above. It stays open when I click on the second link and then they are both open. I want the first one to close if the second is clicked.
I think this is probably closer to what you want.
(It's unclear if you wanted the submenu items to be highlighted when they're clicked - currently, clicking them just collapses the menu anyway so you wouldn't see. Also I removed the hrefs because they aren't adding anything useful.)
var pills = document.querySelectorAll(".expand");
var subs = document.querySelectorAll(".submenu");
pills.forEach(function(pill) {
pill.addEventListener("click", function() {
var sub = pill.querySelector(".submenu");
var alreadyOpen = false;
if (sub.classList.contains("collapse")) alreadyOpen = true;
pills.forEach(function(pill2) {
pill2.classList.remove("active");
});
subs.forEach(function(sub2) {
sub2.classList.remove("collapse");
});
if (!alreadyOpen) {
sub.classList.toggle("collapse");
this.classList.add("active");
}
});
});
.expand.active {
background-color: red;
}
.expand.active > .submenu
{
background-color: #1f1f1f;
}
.mainmenu {
background-color: #1f1f1f;
}
.navpill {
padding: 15px;
color: white;
}
.submenu {
display: none;
}
.submenu.collapse {
display: block;
}
<div>
<ul class="mainmenu">
<li class="navpill expand">Link collapse 1
<ul class="submenu">
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
</ul>
</li>
<li class="navpill expand">Link collapse 2
<ul class="submenu">
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
</ul>
</li>
<li class="navpill">no link</li>
<li class="navpill">no link</li>
</ul>
</div>
I wanted to slideToggle menu items with toggleclass, .opened class should be added and removed for menu items. This is working for me when I toggle different menu item but for same menu item when I click this, .opened class won't get removed here is my code
Html menu tag
<ul id="menu-main-menu">
<li class="menu-item"><a href="link_url">text<a>
<ul class="sub-menu">
<li class="menu-item">
<ul class="sub-menu">
<li class="menu-item"><a href="link_url">second sub item<a></li>
</ul>
</li>
<li class="menu-item"><a href="link_url">first sub item<a></li>
<li class="menu-item"><a href="link_url">first sub item<a></li>
</ul>
</li>
<li class="menu-item"><a href="link_url">text<a></li>
</ul>
jquery code
$('.menu-item').on('click', function(e) {
$('.menu-item').removeClass('opened')
$(this).toggleClass('opened');
if ($('.sub-menu', this).length >=1) {
e.preventDefault();
}
$(this).children('ul').slideToggle('fast');
$(this).siblings('li').find('ul').hide('slow')
e.stopPropagation();
});
I am not sure what I am doing wrong. Can you please help me for this?
Thanks
There is a basic mistake in your code.
Close Anchor tags, you have an opening anchor tag on both the ends.
then use the logic to get your result, see the example, If need anything else, please let me know
Add sub items Achor or li text, that depends on your requirement, but for UX you should add some text so users can get that there is still some more content to see.
$('.menu-item').click(function(e){
$(this).siblings().find('> .sub-menu').slideUp();
$(this).find('> .sub-menu').slideToggle();
$(this).siblings().removeClass('opened');
$(this).toggleClass('opened');
e.stopPropagation();
});
.sub-menu {
display: none;
}
.menu-item a{
display: inline-block;
margin-bottom: 10px;
}
.menu-item {
margin-bottom: 10px;
}
.menu-item.hasSubmenu {
border-bottom: 1px solid;
}
.menu-item a {
background-color: red;
color: white;
}
.hasSubmenu {
position: relative;
}
.hasSubmenu:after {
position: absolute;
right: 10px;
top: 0px;
content: "+";
display: block;
font-size: 20px;
font-weight: bold;
}
.hasSubmenu.opened:after {
content: "-";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="menu-main-menu">
<li class="menu-item hasSubmenu">
text
<ul class="sub-menu">
<li class="menu-item hasSubmenu">
First level
<ul class="sub-menu">
<li class="menu-item">second sub item</li>
<li class="menu-item">second sub item</li>
</ul>
</li>
<li class="menu-item">first sub item</li>
<li class="menu-item">first sub item</li>
</ul>
</li>
<li class="menu-item hasSubmenu">
text
<ul class="sub-menu">
<li class="menu-item hasSubmenu">
First level
<ul class="sub-menu">
<li class="menu-item">second sub item</li>
</ul>
</li>
<li class="menu-item">first sub item</li>
<li class="menu-item">first sub item</li>
</ul>
</li>
</ul>
$('.menu-item').on('click', function(e) {
$(this).toggleClass('opened');
$('.menu-item').not($(this)).removeClass('opened');
if ($('.sub-menu', this).length >= 1) {
e.preventDefault();
}
$(this).children('ul').slideToggle('fast');
$(this).siblings('li').find('ul').hide('slow')
e.stopPropagation();
});
Change the order of removing classes, then skip the current element.
I have some nested lists. Some go as deep as 4-5 level deep. For example:
<ul>
<li>
<span class="is-parent">parent</span>
<ul class="children">
<li class="no-child">child</li>
<li class="no-child">child</li>
<li class="no-child">child</li>
</ul>
</li>
<li>some child</li>
<li>another child</li>
<ul>
This list is displayed in a css grid column, the first one to be specific. I have set the columns using
grid-template-columns: repeat(5, 1fr);
When I click on parent, I want the nested <ul> to display on the next column.
What is the best way to do that using vanila JavaScript?
Something like the example here: https://mynameistechno.github.io/finderjs/#examples
But without the use of a library or plugin.
HTML
<ul>
<li>
<span class="is-parent">parent</span>
<ul class="children hide">
<li class="no-child">child</li>
<li class="no-child">child</li>
<li class="no-child">child</li>
</ul>
</li>
<li>some child</li>
<li>another child</li>
<ul>
CSS
ul {
grid-template-columns: repeat(auto-fill, 1fr);
}
.hide {
display: none;
}
JS
document.querySelectorAll('is-parent').forEach(node =>
node.parentNode.addEventListener('click', (ev) => {
let cl = ev.currentTarget.querySelector('ul').classList
cl.contains('hide') ? cl.remove('hide') : cl.add('hide')
}
}
It's really hard to do this without the jQuery library.
But here I wrote an example using only javascript.
The idea is when you click on is-parent you clone the Children and append to container.
You could build on this example.
I hop this help you somehow
var x = document.getElementsByClassName("is-parent");
var container = document.getElementsByClassName("container")[0];
function bind(items){
new Array(items).forEach(function(item, index){
item = item[0]
item.addEventListener("click", function(){
var children= [].filter.call(item.parentElement.childNodes, function(node) {
return node.className == "children"
})[0];
var i= children.cloneNode(true);
container.appendChild(i);
i.style.display = "block";
i.className = index;
});
});
}
bind(x);
.children{
display:none;
}
ul{
pointer:default;
}
div{
display: grid;
grid-template-columns: auto auto auto;
background-color: #2196F3;
padding: 10px;
}
<div class="container">
<ul>
<li>
<span class="is-parent">parent</span>
<ul class="children">
<li class="no-child">child</li>
<li class="no-child">child</li>
<li class="no-child">child</li>
</ul>
</li>
<li>some child</li>
<li>another child</li>
</ul>
</div>
I want the menu to work like this. When you click Main1 it becomes active and the list will show, when you click it again the list will hide. When Main1 is active and you click Main2, then the Main1 should be inactive and Main2 active.
But my Javascript doesn't seem to make it work well. It makes the Main1 inactive when you click Main2 and the other way, but if you click on any of the active Main it doesn't become incactive. Please help
<div class="directory-section-list">
<ul class="list_item">
<li class="li_lvl lvl0" id="bx_1847241719_2">Main1</li>
<ul>
<li class=""><span class="li_lvl lvl1">1.5-4.5</span>
<ul>
<li>FD 15</li>
<li>FD 18</li>
</ul>
</ul>
<ul class="list_item">
<li class="li_lvl lvl0" id="bx_1847241719_2">Main2</li>
<ul>
<li class=""><span class="li_lvl lvl1">1.5-4.5</span>
<ul>
<li>FD 15</li>
<li>FD 18</li>
</ul>
</ul >
</div>
Javascript
$(' .list_item .lvl0').click(function(){
$(".list_item.active").removeClass("active");
$(this).parent().toggleClass('active');
});
$(' .list_item .lvl1').click(function(){
$(this).parent().toggleClass('active');
});
Try this,
$('.list_item .lvl0').click(function(){
$('.directory-section-list .active').removeClass('active');
if ($(this).parent().hasClass('active'))
{
$(this).parent().removeClass('active');
}
else
{
$(this).parent().addClass('active');
}
});
$('.list_item .lvl1').click(function(){
$(this).parent().toggleClass('active');
});
Please try this
HTML
<div class="directory-section-list">
<ul class="list_item">
<li class="li_lvl lvl0" id="bx_1847241719_2">Main1</li>
<ul>
<li class=""><span class="li_lvl lvl1">1.5-4.5</span>
<ul>
<li>FD 15</li>
<li>FD 18</li>
</ul>
</ul>
</ul>
<ul class="list_item">
<li class="li_lvl lvl1" id="bx_1847241719_2">Main2</li>
<ul>
<li class=""><span class="li_lvl lvl1">1.5-4.5</span>
<ul>
<li>FD 15</li>
<li>FD 18</li>
</ul>
</ul>
</ul>
</div>
Java Script
$(' .list_item .lvl0').click(function () {
$(' .list_item .lvl1').parent().removeClass("active");
$(this).parent().toggleClass('active');
});
$(' .list_item .lvl1').click(function () {
$(' .list_item .lvl0').parent().removeClass("active");
$(this).parent().toggleClass('active');
});
Sorry but your HTML List had a couple of errors the
<li class=""><span class="li_lvl lvl1">1.5-4.5</span>
will never be closed...
its all about the HTML Structure - i've done another change -> check the HTML Structure of this JS Fiddle: http://jsfiddle.net/marco_rensch/hzu76hgt/32/
I think you want something like this?
$(document).ready(function(){
$('.maindiv').hide();
$( "button" ).click(function() {
$('.maindiv[data-link=' + $(this).data('link') + ']').toggle("fade",300);
});
});
div {
background-color: green;
color: white;
width: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<button class="show" data-link="main1">Main1</button>
<button class="show" data-link="main2">Main2</button>
<div>
<div class="maindiv" data-link="main1">
<h1>This is main1</h1>
</div>
<div class="maindiv" data-link="main2">
<h1>This is main2</h1>
</div>
</div>
Well Thank you all for your help. I managed to do it taking some of your examples and making it work my own way. Thank you again. I will post the Javascript fix.
$(document).ready(function() {
$('.li_lvl').click(function () {
if ($(this).parent().hasClass('active')) {
$(this).parent().removeClass('active');
}
else {
$('.directory-section-list .active').removeClass('active');
$(this).parent().addClass('active');
}
});
This will toggle class active of the parent .li_lvl which is the ul.list_item. If parent has class active it will remove class active. If any other list_item will have class active whilst you click on the other list_item, it will remove class active on the other list_item and make class active on the list_item you clicked.
Following is my html
<ul>
<li>
Women
<ul>
<li>Top
<ul>
<li>Short</li>
<li>Lengthy
<ul>
<li><a class="selected" href="">Child Parent</a></li>
<li>Child Parent</li>
<li>Child Parent</li>
<li>Child Parent</li>
</ul>
</li>
<li>Medium</li>
<li>Full Sleve</li>
</ul>
</li>
<li>Casuals</li>
<li>Jeans</li>
<li>Kurthah</li>
</ul>
</li>
<li>Men
<ul>
<li>Top</li>
<li>Casuals</li>
<li>Jeans</li>
<li>Kurthah</li>
</ul>
</li>
<li>Children</li>
<ul>
Here I have a class selected for a link which is selected. What I need is, I want to add a class to the parent li <li>Lengthy, its top parent <li>Top and its top parent <li>Women
All the parents should have different class.
Please find the fiddle here: http://jsfiddle.net/w3pjrxff/2/
Try this:
$(document).ready(function() {
$(document).find("a.selected").each(function(){
$(this).parents("li").each(function(i, v){
$(v).addClass('newPar' + i);
});
});
});
Where i is the index (0, 1, 2 and so on, for different classes), jQuery.parents() gets all parent elements, with the parameter 'li' it only retrieves all li parents.
You may try
$(document).ready(function() {
$("a").attr("href", "#"); // kind of disable all links
$("a").click(function () {
$("a").removeClass("selected");
$(this).addClass("selected");
$(this).parents("a").addClass("selected");
});
});
The problem with your html is, that the <a> are not parents but siblings of the next ul.
As I said in the comments, if you want to add a numerically incremented classes you can use(but then to remove those classes it will be difficult)
$(document).ready(function() {
var $selected = $('.selected');
var $parents = $selected.parent().parents('li');
$parents.children('a').addClass(function(i) {
return 'parent-' + (i + 1)
});
});
.selected {
color: #FF0000;
}
.parent-1 {
color: #00FF00;
}
.parent-2 {
color: #0000FF;
}
.parent-3 {
color: #FF00FF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>Women
<ul>
<li>Top
<ul>
<li>Short</li>
<li>Lengthy
<ul>
<li><a class="selected" href="">Child Parent</a></li>
<li>Child Parent</li>
<li>Child Parent</li>
<li>Child Parent</li>
</ul>
</li>
<li>Medium</li>
<li>Full Sleve</li>
</ul>
</li>
<li>Casuals</li>
<li>Jeans</li>
<li>Kurthah</li>
</ul>
</li>
<li>Men
<ul>
<li>Top</li>
<li>Casuals</li>
<li>Jeans</li>
<li>Kurthah</li>
</ul>
</li>
<li>Children</li>
<ul>
Another approach will be
$(document).ready(function() {
var $selected = $('.selected');
$selected.parent().parents('li').addClass('parent');
});
.selected {
color: #FF0000;
}
.parent > a {
color: #00FF00;
}
.parent .parent > a {
color: #0000FF;
}
.parent .parent .parent > a {
color: #FF00FF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>Women
<ul>
<li>Top
<ul>
<li>Short</li>
<li>Lengthy
<ul>
<li><a class="selected" href="">Child Parent</a></li>
<li>Child Parent</li>
<li>Child Parent</li>
<li>Child Parent</li>
</ul>
</li>
<li>Medium</li>
<li>Full Sleve</li>
</ul>
</li>
<li>Casuals</li>
<li>Jeans</li>
<li>Kurthah</li>
</ul>
</li>
<li>Men
<ul>
<li>Top</li>
<li>Casuals</li>
<li>Jeans</li>
<li>Kurthah</li>
</ul>
</li>
<li>Children</li>
<ul>
Here is another fiddle if you need to add different classes to each parent. This code, however, can be optimized.
$(document).ready(function() {
var curr_parent= $(document).find("a.selected").parent();
var parent1= $(curr_parent).parent().closest('li');
$(parent1).addClass('parent1')
var parent2 = $(parent1).parent().closest('li');
$(parent2).addClass('parent2')
var parent3 = $(parent2).parent().closest('li');
$(parent3).addClass('parent3')
});