Im a jquery noob and I cant figure out how to get the next level expanding in a clickable accordion like menu.
Here is the fiddle:
https://jsfiddle.net/hinterseer/gaxm6uqo/29/
Html
<div class="navbar-collapse">
<ul class="nav">
<li class="subMenu">Archive <span class="caret toggle">+</span>
<ul class="subMenu-link">
<li>Test 1</li>
<li>Test 2</li>
</ul>
</li>
<li class="subMenu"> Archive 2 <span class="caret toggle">+</span>
<ul class="subMenu-link">
<li class="subMenu">Archive 3 <span class="caret toggle">+</span>
<ul class="subMenu-link">
<li>Test 3</li>
<li>Test 4</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
css
.subMenu-link {
display: none;
}
.subMenu {
list-style: none;
}
jQyery
(function($) {
$("li.subMenu").unbind().click(function () {
var slideDown = $(this).find(".toggle").text() == "+" ? false : true;
$(".subMenu-link").slideUp();
$(".toggle").text('+');
if (!slideDown) {
$(this).find('.subMenu-link').slideDown();
$(this).find('.toggle').text('-');
}
});
})(jQuery);
I've refactored things a bit further to enable toggling of each list item and their children independently. I've listed the changes below:
change the listener to $(".toggle").on('click', function() {...
change slideDown to const and modify selector $(this).find(".caret:first")...
use .siblings() for slide up/down functionality, $(this).siblings(".subMenu-link").slideUp()
restructure HTML to wrap li text in its own span so that the text triggers the toggle instead of the whole element (and its children)
add cursor: pointer to .toggle for visual cue to user indicating click
Saw this and thought I'd give things a shot even if it was more than asked.
(function($) {
$(".toggle").on('click', function() {
const slideDown = $(this).find(".caret:first").text() == "+" ? false : true;
$(this).siblings(".subMenu-link").slideUp();
$(this).find(".caret").text('+');
if (!slideDown) {
$(this).siblings('.subMenu-link').slideDown();
$(this).find('.caret').text('-');
}
});
})(jQuery);
.subMenu-link {
display: none;
}
.subMenu {
list-style: none;
}
.toggle {
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="navbar-collapse">
<ul class="nav">
<li class="subMenu"><span class="toggle">Archive <span class="caret">+</span></span>
<ul class="subMenu-link">
<li>Test 1</li>
<li>Test 2</li>
</ul>
</li>
<li class="subMenu"><span class="toggle">Archive 2 <span class="caret">+</span></span>
<ul class="subMenu-link">
<li class="subMenu"><span class="toggle">Archive 3 <span class="caret">+</span></span>
<ul class="subMenu-link">
<li>Test 3</li>
<li>Test 4</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
Just add :first in this line:
var slideDown = $(this).find(".toggle:first").text() == "+" ? false : true;
Related
When I selected dropdown, the selected list did not close quickly it will take a long time. how can solve this
You can try looking at the following JS, CSS and HTML snippets:
\\JS
document.addEventListener("click", toggleDropdown);
function toggleDropdown(event) {
var dropdown = document.getElementById("dropdown");
if (event.target.classList.contains('test')){
dropdown.classList.toggle('show');
} else {
dropdown.classList.remove('show');
}
\\CSS
.dropdownMenu.show {
overflow:visible;
height:200px;
}
\\HTML
<li id="products" class="products">Test
<ul id="dropdown" class="dropdownMenu">
<li>test 1</li>
<li>test 2</li>
<li>test 3</li>
<li>test 4</li>
</ul>
</li>
Is it possible to style a nested ul>li into a treeview like this plugin does?
http://www.easyjstree.com/
I was originally using this plugin, but I am in a situation where I can't use JavaScript/jQuery, but has to be done in CSS. Is this even doable for the following HTML?
<div id="navigator">
<ul>
<li class="isFolder isExpanded">
XYZ CORP HR TIME SELF SERVICE
<ul>
<li class="isFolder isExpanded">
Time
<ul>
<li>Create Timecard</li>
<li>Recent Timecards</li>
<li>Templates</li>
<li>Timecard Search</li>
</ul>
</li>
</ul>
</li>
<li class="isFolder isExpanded">
XYZ CORP EXP ENTRY
<ul>
<li>Expense Home</li>
</ul>
</li>
<li class="isFolder isExpanded">
XYZ HR EMP SELF SERVICE
<ul>
<li>Accommodation Request</li>
<li>Additional Personal Information</li>
<li>All Actions Awaiting Your Attention</li>
<li>Appraisals</li>
</ul>
</li>
</ul>
</div>
Any help or guide would be much much appreciated!!
Not too hard to do without animations, thanks to the + selector. Unfortunately needs to use ids on the checkboxes for the labels to work. Parent selector when.
If you do want to animate it later, you'll wanna hide via max-height:0; rather than display:none;, and animate the max-height. Downside, that'll impose a max-height. If you wanna fake that animation, stick with display:none; and animate a vertical padding instead, letting the user's eye do the work. Y'know. Standard animation tricks.
ul.asTree {
list-style-type:none;
padding:0;
margin:0;
text-indent:1em;
}
ul.asTree ul{
display:none;
list-style-type:none;
}
ul.asTree li{/*lets us position the label's ::before*/
position:relative;
}
ul.asTree label{
cursor:pointer;
}
ul.asTree label:hover{
box-shadow: 0 0 5px 0 rgba(128,155,200,0.5) inset;
}
ul.asTree label::before{
content:"\25B7";
position:absolute;
left:-1em;
top:-2px;
}
ul.asTree input:checked + label::before{
content:"\25E2";
}
ul.asTree input:checked + label + ul{
display:block;
}
<ul class="asTree">
<li>item 1</li>
<li>item 2</li>
<li>
<input type="checkbox" hidden id="treeExp_3" />
<label for="treeExp_3">item 3</label>
<ul>
<li>item 3.1</li>
<li>
<input type="checkbox" hidden id="treeExp_3_2" />
<label for="treeExp_3_2">item 3.2</label>
<ul>
<li>item 3.2.1</li>
<li>item 3.2.2</li>
</ul>
</li>
<li>item 3.3</li>
</ul>
</li>
<li>
<input type="checkbox" hidden id="treeExp_4" />
<label for="treeExp_4">item 4</label>
<ul>
<li>item 4.1</li>
<li>item 4.2</li>
</ul>
</li>
</ul>
Alternately available on Dabblet
Really simple guys: making a collapsible list in html and css and trying to move the checkbox that controls the drop down to the FRONT of the text, as well as get rid of the dot to list the items. Right now the checkbox is placed at the end of the text. I tried to simply switch the order of the html but that screws up the drop down action.
Here is the fiddle: https://jsfiddle.net/gyetxsLu/
HTML:
<div class="CHECKBOXMENU">
<ul class="collapsibleList">
<li>
<label for="mylist-node1">Click to open list 1</label>
<input type="checkbox" id="mylist-node1" />
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</li>
<li>
<label for="mylist-node2">Click to open list 2 with subfolders</label>
<input type="checkbox" id="mylist-node2" />
<ul>
<li>
<label for="mylist-node3">Click to expand</label>
<input type="checkbox" id="mylist-node3" />
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</li>
</ul>
</div>
CSS:
.collapsibleList li > input + * {
display: none;
}
.collapsibleList li > input:checked + * {
display: block;
}
.collapsibleList label {
cursor: pointer;
}
No need to restructure the HTML. float: left the required checkboxes and remove the bullets using list-style-type: none
ul.collapsibleList,
ul.collapsibleList ul {
list-style-type: none;
}
#mylist-node1,
#mylist-node2,
#mylist-node3 {
float: left;
margin-right: 5px;
}
JSfiddle
at the moment, i am using the selectable JQUERY function
<style>
#selectable .ui-selecting { background: #FECA40; }
#selectable .ui-selected { background: #F39814; color: white; }
</style>
<ol id="selectable">
<li class="ui-widget-content">Item 1</li>
<li class="ui-widget-content">Item 2</li>
<li class="ui-widget-content">Item 3</li>
<li class="ui-widget-content">Item 4</li>
<li class="ui-widget-content">Item 5</li>
<li class="ui-widget-content">Item 6</li>
<li class="ui-widget-content">Item 7</li>
</ol>
but for some reason, when i select an element, the color will not change to bright orange but revert to the default gray of ui-state-default like below:
But if I go to the Chrome debugger and uncheck the background in ui-state-default in the style section, it works perfectly.
Is it because of this snippet:
var nodes = document.getElementById('selectable').getElementsByClassName('ui-widget-content');
if (nodes.length > 0)
{
nodes[0].innerHTML = getSymbol();
nodes[0].setAttribute("class", "ui-state-default");
}
How do i go around this problem, such that when i click on the element of interest, the color will change like i specified in the <style> tag.
With jQuery, this is quite simple.
$('.ui-widget-content') will select all of your LI elements. (alternately you could use $('#selectable li'))
$('.ui-widget-content').click(function() {
$(.'ui-widget-content').removeClass('.ui-state-default'); <-- this clears previous selections
$(this).addClass('.ui-state-default'); <-- this adds the class to the clicked item
})
How can I use CSS selectors to apply a style only to the inner item in a list. Example:
HTML fragment:
<ul class="list">
<li>Item 1</li>
<li>
<ul class="list">
<li>Subitem 1</li>
<li>Subitem 2</li>
<li>
<ul class="list">
<li>Subitem 1.1</li>
</ul>
</li>
</ul>
</li>
</ul>
CSS fragment:
ul.list {
border: 1px solid red;
}
What I need is to have a border only arround the "Subitem 1.1" string. The list is generated and it's not possible to add an extra class or id and as the list has no fixed depth it's not an option to specify an "ul > ul > ul.list" or similar selector.
I believe you cannot do this with only CSS if it is not possible to use an Id or unique class. In this case I think jQuery is the way to go:
$("li").children().eq( $("li").children().length - 1 ).
css('border', '1px solid red');
The idea is to use eq() to pinpoint the deepest child.
Hope this helps
it's not an option to specify an "ul > ul > ul.list" or similar selector.
Why not? This, or adding a class, is the solution.
You've basically specified a requirement to identify an element, then rejected all the approaches that you could use to do so.
<html>
<head>
<style type="text/css">
li.list {
border: 1px solid red;
}
</style>
</head>
<body>
<ul >
<li>Item 1</li>
<li>
<ul >
<li>Subitem 1</li>
<li>Subitem 2</li>
<li>
<ul >
<li class="list">Subitem 1.1</li>
</ul>
</li>
</ul>
</li>
</ul>
</body>
</html>
I Hope This ma help you..
JoseSantos is correct in that it can't be done with pure CSS. Here's how I'd do it in jQuery:
$("ul").each(function(){
if ($(this).find("ul").length == 0)
$(this).addClass("list");
});