So I'm working on this small frontend project with some jQuery I wanted to do something where there is a list of names and if you click it, a class of "selected" should be added, but I want to remove that class if some other option is selected.
So suppose Name-1 is selected It gets a background Color Change, but If Name-2 is selected right after the background color for Name-1 should go away and add to Name-2, and I have multiple names so I can't make a function for every single option.
I was wondering if there is a easier way to do it.
HTML
<ul class="names">
<li class="name selected">Name-1</li>
<li class="name">Name-2</li>
<li class="name">Name-3</li>
</ul>
CSS
.selected {
background-color: rgba(0, 0, 0, 0.3);
}
you can do it like this:
$("ul.names li").on("click", function(){
$("ul.names li").removeClass("selected");
$(this).addClass("selected");
})
EDIT - explanation
you select all the <li> tags by this selector ul.names li and manipulate them together, first you remove the selected class from all li tags by this $("ul.names li").removeClass("selected"); and then you add selected class to the chosen li tag represented by the this key word
$("ul.names li").on("click", function() {
$("ul.names li").removeClass("selected");
$(this).addClass("selected");
})
.selected {
background-color: rgba(0, 0, 0, 0.3);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="names">
<li class="name selected">Name-1</li>
<li class="name">Name-2</li>
<li class="name">Name-3</li>
</ul>
Something like this should work.
$('.name').on('click', function() {
$('.name').removeClass('selected').css('background','none');
$(this).addClass('selected').css('background',$(this).data('bg'));
});
$('.name.selected').css('background',$('.name.selected').data('bg'));
.selected {
color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="names">
<li class="name selected" data-bg="green">Name-1</li>
<li class="name" data-bg="red">Name-2</li>
<li class="name" data-bg="blue">Name-3</li>
</ul>
Related
So I have multiple LI's like below as it's a menu and I am trying to create a drop-down but for some reason, my jQuery code is not working. Can someone help me?
FYI I can't change HTML as it's dynamically generating in Shopify. I can only change jQuery and CSS
<li class="grid__item lvl-1 ">
<a class="site-nav lvl-1 light-body">Furry Artist</a>
<ul class="subLinks inactive">
<li class="lvl-2">
Erdbeer Joghurt
</li>
<li class="lvl-2">
Jeson RC
</li>
</ul>
</li>
$( document ).ready(function() {
$("ul.subLinks").addClass("inactive");
});
$('a.site-nav.lvl-1').click(function() {
$(this).find("ul.subLinks").toggleClass('active-drop-down');
});
.inactive {
display:none;
}
.active-drop-down {
display:block !important;
}
Your issue is $(this).find... in the a click handler - at this point, this is the a.
.find() looks at the selectors children - but the menu is not a child of the a, it's a sibling.
Change to
$(this).closest("li").find("ul.subLinks"...
(maybe $(this).next().toggleClass... with a caveat on .this() that it's always the very next element).
Updated snippet:
$('a.site-nav.lvl-1').click(function() {
$(this).closest("li").find("ul.subLinks").toggleClass('active-drop-down');
});
.inactive {
display:none;
}
.active-drop-down {
display:block !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ol>
<li class="grid__item lvl-1 ">
<a class="site-nav lvl-1 light-body">Furry Artist</a>
<ul class="subLinks inactive">
<li class="lvl-2">
Erdbeer Joghurt
</li>
<li class="lvl-2">
Jeson RC
</li>
</ul>
</li>
</ol>
I am trying to have a submenu dropdown inside a dropdown, using MaterializeCSS framework. I tried with the following code, but it didn't work.
<!-- this the main dropdown -->
<ul id="MainDropDown" class="dropdown-content">
<li>Dropdown1<span class="right caret">►</span></li>
<li>Dropdown2<span class="right caret">►</span></li>
<li>Dropdown3<span class="right scaret">►</span></li>
</ul>
<ul id="drop1" class="dropdown-content">
<li>Create</li>
</ul>
<ul id="drop2" class="dropdown-content">
<li>Create</li>
<li>Update</li>
</ul>
<ul id="drop3" class="dropdown-content">
<li>Create</li>
</ul>
I was having the same issue myself.
Turns out it's as simple as nesting another dropdown link,
setting an appropriate gutter, and making sure the overflow of
dropdown-content is set to visible.
Here is a link to the modified jsfiddle linked in Nested dropdowns in materialize
https://jsfiddle.net/fb0c6b5b/
$('.dropdown-button2').dropdown({
inDuration: 300,
outDuration: 225,
constrain_width: false, // Does not change width of dropdown to that of the activator
hover: true, // Activate on hover
gutter: ($('.dropdown-content').width()*3)/2.5 + 5, // Spacing from edge
belowOrigin: false, // Displays dropdown below the button
alignment: 'left' // Displays dropdown with edge aligned to the left of button
}
);
.dropdown-content{
overflow: visible !important;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.6/css/materialize.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class='dropdown-button btn' href='#' data-activates='dropdown1' data-beloworigin="true">Drop Me!</a>
<ul id='dropdown1' class='dropdown-content'>
<li>two</li>
<li class="divider"></li>
<li>three</li>
<li><a class='dropdown-button2 d' href='#' data-activates='dropdown2' data-hover="hover" data-alignment="left">Drop Me!</a></li>
</ul>
<ul id='dropdown2' class='dropdown-content'>
<li>one</li>
<li>two</li>
<li class="divider"></li>
<li>three</li>
</ul>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.6/js/materialize.min.js"></script>
I tried it here but my was aligned on the same line from the dropdown, then did it and it worked:
.dropdown-content {
overflow-y: visible;
}
.dropdown-content .dropdown-content {
margin-left: 100%;
}
Based on the answer from #LibanH and updated for version v1.0.0, you need some change.
constrain_width must be replaced by constrainWidth and gutter is no longer an option.
In order to display the nested dropdown at the good position, we need to get the height of the selected item in first dropdown and set position with CSS
$('.dropdown-button').dropdown({
onOpenStart: function() {
var selectedItem = $(this).find('.selected');
$('#dropdown2').css('top', selectedItem.outerHeight() + "px");
}
});
$('.dropdown-button2').dropdown({
constrainWidth: false //change
hover: true,
alignment: 'left'
}
);
and add some CSS
#dropdown2 {
position: absolute;
left: 100%;
}
We have tabs working correctly using this HTML
<div class="col-lg-3 col-md-3 panel-container">
<ul class="nav nav-pills nav-stacked">
<li class="active"><a data-toggle="pill" href="#general" ng-class="{true: 'invalid-tab', false: ''}[form.editTemplateGeneralForm.$invalid]">#Labels.general</a></li>
<li><a data-toggle="pill" href="#startingValues" ng-class="{true: 'invalid-tab', false: ''}[form.editTemplateStartingValuesForm.$invalid]">#Labels.startingValues</a></li>
</ul>
</div>
The invalid-tab used to work fine, and when the tab was invalid it was shown in red. Now it's no longer working and we suspect it's the newest version of AngularJS that broke that functionality. We're using v1.3.13.
Do you know what should be adjusted in that syntax above to make it work again (that is used in many pages of our application).
Here is the invalid-tab from our site.css:
.widget .invalid-tab * {
background-color: #F9EAF3;
/*color: #F9EAF3;*/
color: #d43f3a;
}
.widget .invalid-tab:hover * {
background-color: #E06B6C;
color: #ffffff;
}
The correct way to define ng-class is as follows: ng-class="{classname: expresstion}"
You also need to remove the asterisk from the css-selector - as you are selecting any child element. But the .invalid-tab has no child elements.
Another solution would be to move the .invalid-tab class out to the parent li-element
angular.module('myApp', [])
.directive('testApp', function(){
return {
link: function(scope) {
scope.form = {
editTemplateStartingValuesForm: {$invalid: true},
editTemplateGeneralForm: {$invalid: false}
};
}
};
});
.widget .invalid-tab {
background-color: #F9EAF3;
/*color: #F9EAF3;*/
color: #d43f3a;
}
.widget .invalid-tab:hover {
background-color: #E06B6C;
color: #ffffff;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
<div ng-app="myApp" class="widget" test-app>
<div class="col-lg-3 col-md-3 panel-container">
<ul class="nav nav-pills nav-stacked">
<li class="active">
<a data-toggle="pill" href="#general" ng-class="{'invalid-tab': form.editTemplateGeneralForm.$invalid}">#Labels.general</a>
</li>
<li>
<a data-toggle="pill" href="#startingValues" ng-class="{'invalid-tab': form.editTemplateStartingValuesForm.$invalid}">#Labels.startingValues</a>
</li>
</ul>
</div>
</div>
I have a list of items vertically. I want to select item from the list. Also, selected item will get green or any color. At a time, only one item can be selected from list. I can create the list. But, no idea how to make it selective and change color after selection by clicking mouse. Do I need to use any CSS for that?
<div class="items">
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
<ul>
</div>
Give each li element a tabindex, and add this CSS:
li:focus {
background: lightgreen;
}
<div class="items">
<ul>
<li tabindex="1">Item1</li>
<li tabindex="1">Item2</li>
<li tabindex="1">Item3</li>
<ul>
</div>
To do this in plain JavaScript:
Add a click event listener to the ul element.
If the event's target is an li element:
2a. If there's an existing li that's selected, remove its class.
2b. Add a selected class to the event's target.
document.querySelector('ul').addEventListener('click', function(e) { // 1.
var selected;
if(e.target.tagName === 'LI') { // 2.
selected= document.querySelector('li.selected'); // 2a.
if(selected) selected.className= ''; // "
e.target.className= 'selected'; // 2b.
}
});
.selected {
background: lightgreen;
}
<div class="items">
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
<ul>
</div>
Note that LI must be capitalized in e.target.tagName === 'LI'.
The HTML
<div class="items">
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
<ul>
</div>
And the Jquery
$(".items ul li").click(function(){
$(".items ul li").css("color","inherit");
$(this).css("color","green");
});
http://jsfiddle.net/74g21org/1/
You can use jquery as such:
$("ul li").on("click", function () {
$("ul li").removeClass('selected');
$(this).attr('class', 'selected');
});
.selected {
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
</ul>
You can do it with plain html and css like this:
.items li:active {
color: green;
}
http://jsfiddle.net/b8jwnfgp/1/
To expand on Bak's response, you will need to use Javascript to apply the styles such as color.
jQuery is probably the easiest way to go about doing as he suggested. This is a good place to start: https://learn.jquery.com/about-jquery/how-jquery-works/
Also, don't forget to close your list item tags:
<li>Item1< / li>
Here is my code:
a) I have a row of buttons at the top formatted horizontally as such:
HTML:
<ul class="nav">
Work
Volunteer
Education
Skills
References
Images
</ul>
b) I have div blocks each displaying a paragraph:
<div class="jobs">
<h2>text</h2>
<h3>text</h3>
<h4>text</h4>
</div>
c) I want the CSS to not display the jobs div yet:
.jobs {
display: none;
}
d) Now that I hover over the first button I want the jobs div to display:
.button1:hover+.jobs {
display: block
}
e) Repeat for all other div sections
.volunteer {
display: none;
}
.button2:hover+.volunteer {
display:block
}
You will need to markup HTML differently.
.jobs, .volunteer {
display: none;
}
.button1:hover+.jobs, .button2:hover+.volunteer {
display: block;
/* position the divs under the navigation links */
position: absolute;
top: 120px;
}
<ul class="nav">
<li>
Work
<div class="jobs">
<h2>h2 jobs</h2>
<h3>h3 jobs</h3>
<h4>h4 jobs</h4>
</div>
</li>
<li>
Volunteer
<div class="volunteer">
<h2>h2 volunteer</h2>
<h3>h3 volunteer</h3>
<h4>h4 volunteer</h4>
</div>
</li>
<li> Education</li>
<li> Skills</li>
<li> References</li>
<li> Images</li>
</ul>
This is impossible, as described, with your current HTML, with only HTML and CSS (though only perhaps until the reference and :matches() pseudo-selectors arrive). However, if, rather than :hover you'd be willing to work with clicks on the list-elements, it can be done (without JavaScript). Given the corrected HTML:
<ul class="nav">
<li>Work
</li>
<li> Volunteer
</li>
<!-- and so on... -->
</ul>
<div id="details">
<div id="jobs"></div>
<div id="volunteer"></div>
<!-- and so on... -->
</div>
The following CSS will show the relevant div element once the <a> element has been clicked on (note that the use of an id is essential for this to work):
#details > div {
/* to hide the eleemnt(s) initially: */
display: none;
}
#details > div:target {
/* to show the relevant element once the relevant link is clicked: */
display: block;
}
#details > div[id]::after {
content: attr(id);
}
#details > div {
display: none;
}
#details > div:target {
display: block;
}
<ul class="nav">
<li>Work
</li>
<li> Volunteer
</li>
<li> Education
</li>
<li> Skills
</li>
<li> References
</li>
<li> Images
</li>
</ul>
<div id="details">
<div id="jobs"></div>
<div id="volunteer"></div>
<div id="education"></div>
<div id="skills"></div>
<div id="references"></div>
<div id="images"></div>
</div>
With plain JavaScript, on the other hand, it can be achieved with:
// the 'e' argument is automatically to the function by addEventListener():
function toggleRelevant (e) {
// caching the 'this' element:
var self = this,
// finding the div element with a class equal to the href of the 'a' element
// (though we're stripping off the leading '#':
relevantElement = document.querySelector('div.' + self.getAttribute('href').substring(1) );
// if the event we're responding to is 'mouseover' we set the display of the
// found div to 'block', otherwise we set it to 'none':
relevantElement.style.display = e.type === 'mouseover' ? 'block' : 'none';
}
// finding all the a elements that are in li elements:
var links = document.querySelectorAll('li a');
// iterating over those a elements, using Array.prototype.forEach:
[].forEach.call(links, function(linkElem){
// adding the same event-handler for both mouseover and mouseout:
linkElem.addEventListener('mouseover', toggleRelevant);
linkElem.addEventListener('mouseout', toggleRelevant);
});
function toggleRelevant(e) {
var self = this,
relevantElement = document.querySelector('div.' + self.getAttribute('href').substring(1));
relevantElement.style.display = e.type === 'mouseover' ? 'block' : 'none';
}
var links = document.querySelectorAll('li a');
[].forEach.call(links, function(linkElem) {
linkElem.addEventListener('mouseover', toggleRelevant);
linkElem.addEventListener('mouseout', toggleRelevant);
});
div[class] {
display: none;
}
div[class]::before {
content: attr(class);
color: #f00;
border: 1px solid #f00;
padding: 0.2em;
}
<ul class="nav">
<li>Work
</li>
<li> Volunteer
</li>
<!-- and so on... -->
</ul>
<div class="jobs">
<h2>text</h2>
<h3>text</h3>
<h4>text</h4>
</div>
<div class="volunteer">
<h2>text</h2>
<h3>text</h3>
<h4>text</h4>
</div>
<!-- and so on... -->
I don't think this is do able in css since display blocks (job, volonteer, ...) and button are not parent. But in jQuery this is fairly simple :
$('.buttonX').hover(
function() {
// Styles to show the box
$('.boxX').css(...);
},
function () {
// Styles to hide the box
$('.boxX').css(...);
}
);
It sounds like you're trying to do some kind of a tab menu where pressing a specific button shows a different content. Here's a SO page that describes how it's done: How to make UL Tabs with only HTML CSS