Parent collapses when expanding child using toggle and page scrolls to top - javascript

I asked two questions related to my current problem, but the way I asked and the code that I provided wasn't been enough to solve it, so I present the problem (that was raised from the previous solutions attempts) in a more complete way on this code snippet.
Basically I want this PHP generated file tree to expand/collapse the way it should. With the JQuery code that some nice people here at SO provided me it's almost solved.
The problem is now that when you expand a child the parent collapses, you will see this running the code below.
Notes:
-I'm using Wordpress and for some reason you need to make sure that the tree is collapsed at first, otherwise it's displayed fully expanded.
-I have a related side problem: When you click to toggle, the scroll goes all the way up.
function init_php_file_tree() {
$('.pft-directory')
.on('click', function() {
$(this).children('ul').toggle();
})
.children("ul").hide();
};
jQuery(init_php_file_tree);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<ul class="file">
<ul>
<li class="pft-directory">Parent Directory
<ul>
<li class="pft-directory">Child directory
<ul>
<li class="pft-file ext-pdf">somefile.pdf
<ul></ul> <!-- this HTML code is generated from a php recursive function you will see it a lot (I'll fix that later) -->
</li>
<li class="pft-file ext-doc">somefile2.doc
<ul></ul>
</li>
</ul>
<ul></ul>
</li>
</ul>
</li>
<li class="pft-directory">Another parent directory
<ul>
<li class="pft-directory">Child directory
<ul>
<li class="pft-file ext-docx">V1.docx
<ul></ul>
</li>
</ul>
<ul>
<li class="pft-directory">Child directory 2
<ul>
<li class="pft-file ext-pdf">V2.pdf
<ul></ul>
</li>
<li class="pft-file ext-png">HH-V1.png
<ul></ul>
</li>
</ul>
<ul></ul>
</li>
<li class="pft-directory">Child directory
<ul></ul>
</li>
</ul>
</li>
<li class="pft-directory">Child directory 2
<ul>
<li class="pft-file ext-pdf">HH-V1.pdf
<ul></ul>
</li>
</ul>
<ul>
<li class="pft-directory">Child directory 3
<ul>
<li class="pft-file ext-pdf">HH-V1.pdf
<ul></ul>
</li>
</ul>
<ul></ul>
</li>
<li class="pft-directory">Child directory 4
<ul>
<li class="pft-file ext-pdf">HH-V1.pdf
<ul></ul>
</li>
</ul>
<ul></ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</ul>
</body>
</html>

You can stop the bubbling that occurs by using event.stopPropagation() (https://api.jquery.com/event.stoppropagation/).
Regarding your second problem, that the page scrolls up, that is very likely due to your a href="#"'s. Replace them with url's or use a href="javascript:;".
Example below:
function init_php_file_tree() {
$('.pft-directory')
.on('click', function(e) {
e.stopPropagation();
$(this).children('ul').toggle();
})
.children("ul").hide();
};
jQuery(init_php_file_tree);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<ul class="file">
<ul>
<li class="pft-directory">Parent Directory
<ul>
<li class="pft-directory">Child directory
<ul>
<li class="pft-file ext-pdf">somefile.pdf
<ul></ul> <!-- this HTML code is generated from a php recursive function you will see it a lot (I'll fix that later) -->
</li>
<li class="pft-file ext-doc">somefile2.doc
<ul></ul>
</li>
</ul>
<ul></ul>
</li>
</ul>
</li>
<li class="pft-directory">Another parent directory
<ul>
<li class="pft-directory">Child directory
<ul>
<li class="pft-file ext-docx">V1.docx
<ul></ul>
</li>
</ul>
<ul>
<li class="pft-directory">Child directory 2
<ul>
<li class="pft-file ext-pdf">V2.pdf
<ul></ul>
</li>
<li class="pft-file ext-png">HH-V1.png
<ul></ul>
</li>
</ul>
<ul></ul>
</li>
<li class="pft-directory">Child directory
<ul></ul>
</li>
</ul>
</li>
<li class="pft-directory">Child directory 2
<ul>
<li class="pft-file ext-pdf">HH-V1.pdf
<ul></ul>
</li>
</ul>
<ul>
<li class="pft-directory">Child directory 3
<ul>
<li class="pft-file ext-pdf">HH-V1.pdf
<ul></ul>
</li>
</ul>
<ul></ul>
</li>
<li class="pft-directory">Child directory 4
<ul>
<li class="pft-file ext-pdf">HH-V1.pdf
<ul></ul>
</li>
</ul>
<ul></ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</ul>
</body>
</html>

The reason is when you are clicking on child node it's click event is pass to it's parent node so you have to stop that passing. and for doing so you have to use stopPropagation() which will not pass event to it's parent element. For more info on stopPropagation() see this
function init_php_file_tree() {
$('.pft-directory')
.on('click', function(e) {
$(this).children('ul').toggle();
e.stopPropagation();
})
.children("ul").hide();;
};
jQuery(init_php_file_tree);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<ul class="file">
<ul>
<li class="pft-directory">Parent Directory
<ul>
<li class="pft-directory">Child directory
<ul>
<li class="pft-file ext-pdf">somefile.pdf
<ul></ul> <!-- this HTML code is generated from a php recursive function you will see it a lot (I'll fix that later) -->
</li>
<li class="pft-file ext-doc">somefile2.doc
<ul></ul>
</li>
</ul>
<ul></ul>
</li>
</ul>
</li>
<li class="pft-directory">Another parent directory
<ul>
<li class="pft-directory">Child directory
<ul>
<li class="pft-file ext-docx">V1.docx
<ul></ul>
</li>
</ul>
<ul>
<li class="pft-directory">Child directory 2
<ul>
<li class="pft-file ext-pdf">V2.pdf
<ul></ul>
</li>
<li class="pft-file ext-png">HH-V1.png
<ul></ul>
</li>
</ul>
<ul></ul>
</li>
<li class="pft-directory">Child directory
<ul></ul>
</li>
</ul>
</li>
<li class="pft-directory">Child directory 2
<ul>
<li class="pft-file ext-pdf">HH-V1.pdf
<ul></ul>
</li>
</ul>
<ul>
<li class="pft-directory">Child directory 3
<ul>
<li class="pft-file ext-pdf">HH-V1.pdf
<ul></ul>
</li>
</ul>
<ul></ul>
</li>
<li class="pft-directory">Child directory 4
<ul>
<li class="pft-file ext-pdf">HH-V1.pdf
<ul></ul>
</li>
</ul>
<ul></ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</ul>
</body>
</html>

Related

how to remove all class from child node using pure javascript?

[![enter image description here][1]][1]
it have ul li structure menu.
i want remove all menushow class from submenu_1.
i have multiple submenu_1 class.
demo example :
<ul class="submenu_1 menushow">
<li class="sub">
<ul class="submenu_2 menushow">
<li>
<ul class="submenu_2 menushow">
<li>
<ul class="submenu_2 menushow">
<li></li>
</ul>
</li>
</ul>
</li>
<li></li>
</ul>
</li></ul>
To remove all class .menushow from elements from ul.submenu_1.menushow you can use el.classList.remove('menushow'):
document
.querySelectorAll('ul.submenu_1.menushow, ul.submenu_1 .menushow')
.forEach(function(el) {
el.classList.remove('menushow');
})
<ul class="submenu_1 menushow">
<li class="sub">
<ul class="submenu_2 menushow">
<li>
<ul class="submenu_2 menushow">
<li>
<ul class="submenu_2 menushow">
<li></li>
</ul>
</li>
</ul>
</li>
<li></li>
</ul>
</li>
</ul>

DOM traversal from a span element inside an anchor to list

I can't figure how to travers the DOM, starting from <span class = "open-menu-link">, I want to reach <ul class="sub-menu"> .
The script
<script> $('.open-menu-link').click(function(e){
alert(e.currentTarget);
});
</script>
return a Object HTMLSpanElement, but if I code e.currentTarget.parentNode; it returns http://localhost/mysite/home.php. Doing e.currentTarget.children; I get Object HTMLCollection, but if I try e.currentTarget.children[1] I get undefined... so how can I reach <ul class="sub-menu">?
The snippet is the follow:
<ul class="menu">
<li>Work</li>
<li class="menu-item-has-children">Haschildren <span class = "open-menu-link">+</span>
<ul class="sub-menu">
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
</ul>
</li>
<li>Careers</li>
<li>Contact</li>
</ul>
$(function() {
$('.open-menu-link').click(function(e){
console.log(e.target.parentNode.nextElementSibling);
console.log(e.target.parentNode.parentNode.children[1]);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="menu">
<li>Work</li>
<li class="menu-item-has-children">
Haschildren <span class="open-menu-link">+</span>
<ul class="sub-menu">
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
</ul>
</li>
<li>Careers</li>
<li>Contact</li>
</ul>
There are couple of options:
$('.open-menu-link').click(function(e){
console.log(e.target.parentNode.nextElementSibling);
console.log(e.target.parentNode.parentNode.children[1]);
});
The <span class = "open-menu-link"> in your code has only one child i.e text node + this is the reason why e.currentTarget.children[1] is giving you undefined.
Coming to the dom traversal, you should start with node <li class="menu-item-has-children"> . Well that is what I can infer from your question.
You need to use preventDefault() because you'r class is a link. By clicking, it'll redirect you to the link.
$('.open-menu-link').click(function(e) {
console.log($(this).parent().next())
e.preventDefault()
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="menu">
<li>Work
</li>
<li class="menu-item-has-children">
Haschildren <span class = "open-menu-link">+</span>
<ul class="sub-menu">
<li>Child 1
</li>
<li>Child 2
</li>
<li>Child 3
</li>
</ul>
</li>
<li>Careers
</li>
<li>Contact
</li>
</ul>

jquery mtree onload open last clicked node with cookie option

I am using mtree( sample you can seehere for display my menu list nodes When i click on the node text (hyperlink) . I want to open the node which i clicked and all other nodes should be closed. I am using the following code.
In main.html page i have list with Africa,America,Asia,Europe,Oceania,Arctica and
Antarctica
Africa is having sub menu as: Algeria,Marocco,Libya,Somalia,Kenya,Mauritania and South Africa( all are hyperlink text)
when I click on kenya text hyperlink it will redirects to kenya.html page so on load of kenya.html i want Africa menu list should open with Kenya text highlighted
main.html
<body>
</div>
<ul class="mtree transit">
<li id ="shiva" class ="shiva">Africa
<ul>
<li>Algeria</li>
<li>Marocco</li>
<li>Libya</li>
<li>Somalia</li>
<li>Kenya</li>
<li>Mauritania</li>
<li>South Africa</li>
</ul>
</li>
<li>America
<ul>
<li>North-America
<ul>
<li>Canada</li>
<li>USA
<ul>
<li>New York</li>
<li>California
<ul>
<li>Los Angeles</li>
<li>San Diego</li>
<li>Sacramento</li>
<li>San Francisco</li>
<li>Bakersville</li>
</ul>
</li>
<li>Lousiana</li>
<li>Texas</li>
<li>Nevada</li>
<li>Montana</li>
<li>Virginia</li>
</ul>
</li>
</ul>
</li>
<li>Middle-America
<ul>
<li>Mexico</li>
<li>Honduras</li>
<li>Guatemala</li>
</ul>
</li>
<li>South-America
<ul>
<li>Brazil</li>
<li>Argentina</li>
<li>Uruguay</li>
<li>Chile</li>
</ul>
</li>
</ul>
</li>
<li>Asia
<ul>
<li>China</li>
<li>India</li>
<li>Malaysia</li>
<li>Thailand</li>
<li>Vietnam</li>
<li>Singapore</li>
<li>Indonesia</li>
<li>Mongolia</li>
</ul>
</li>
<li>Europe
<ul>
<li>North
<ul>
<li>Norway</li>
<li>Sweden</li>
<li>Finland</li>
</ul>
</li>
<li>East
<ul>
<li>Romania</li>
<li>Bulgaria</li>
<li>Poland</li>
</ul>
</li>
<li>South
<ul>
<li>Italy</li>
<li>Greece</li>
<li>Spain</li>
</ul>
</li>
<li>West
<ul>
<li>France</li>
<li>England</li>
<li>Portugal</li>
</ul>
</li>
</ul>
</li>
<li>Oceania
<ul>
<li>Australia</li>
<li>New Zealand</li>
</ul>
</li>
<li>Arctica</li>
<li>Antarctica</li>
</ul>
<script src="jquery.min.js"></script>
<script src='jquery.velocity.min.js'></script>
<script src="mtree.js"></script>
<script src="shiva.js"></script>
THIS IS MAIN PAGE
</body>
kenya.html
<body onload="clickButton()">
</div>
<ul class="mtree transit">
<li id ="shiva" class ="shiva">Africa
<ul id = "shiva">
<li>Algeria</li>
<li>Marocco</li>
<li>Libya</li>
<li>Somalia</li>
<li>Kenya</li>
<li>Mauritania</li>
<li>South Africa</li>
</ul>
</li>
<li>America
<ul>
<li>North-America
<ul>
<li>Canada</li>
<li>USA
<ul>
<li>New York</li>
<li>California
<ul>
<li>Los Angeles</li>
<li>San Diego</li>
<li>Sacramento</li>
<li>San Francisco</li>
<li>Bakersville</li>
</ul>
</li>
<li>Lousiana</li>
<li>Texas</li>
<li>Nevada</li>
<li>Montana</li>
<li>Virginia</li>
</ul>
</li>
</ul>
</li>
<li>Middle-America
<ul>
<li>Mexico</li>
<li>Honduras</li>
<li>Guatemala</li>
</ul>
</li>
<li>South-America
<ul>
<li>Brazil</li>
<li>Argentina</li>
<li>Uruguay</li>
<li>Chile</li>
</ul>
</li>
</ul>
</li>
<li>Asia
<ul>
<li>China</li>
<li>India</li>
<li>Malaysia</li>
<li>Thailand</li>
<li>Vietnam</li>
<li>Singapore</li>
<li>Indonesia</li>
<li>Mongolia</li>
</ul>
</li>
<li>Europe
<ul>
<li>North
<ul>
<li>Norway</li>
<li>Sweden</li>
<li>Finland</li>
</ul>
</li>
<li>East
<ul>
<li>Romania</li>
<li>Bulgaria</li>
<li>Poland</li>
</ul>
</li>
<li>South
<ul>
<li>Italy</li>
<li>Greece</li>
<li>Spain</li>
</ul>
</li>
<li>West
<ul>
<li>France</li>
<li>England</li>
<li>Portugal</li>
</ul>
</li>
</ul>
</li>
<li>Oceania
<ul>
<li>Australia</li>
<li>New Zealand</li>
</ul>
</li>
<li>Arctica</li>
<li>Antarctica</li>
</ul>
<script src="jquery.min.js"></script>
<script src='jquery.velocity.min.js'></script>
<script src="mtree.js"></script>
<script src="shiva.js"></script>
THIS IS Kenya PAGE
</body>

How to split a <ul> into multiple lists based on the CSS class and contents of <li> elements

I have a big unordered list inside a div that I need to be split into multiple lists. The reason for this is that I need to split this stuff into 5 columns for Bootstrap so all the responsive stuff works correctly. I want to split specifically on the About Us, Technology, Patients, and Site Map list elements.
I have tried using jQuery .before to insert some HTML before the "About Us" list item, but the resulting code is messed up because it is invalid HTML. I tried to do something like this, but it didn't work:
var footerLinks = $('#footer ul li');
footerLinks.each(function() {
if ($(this).attr('class') === 'list-header') {
if ($(this).find('a').text() === "About Us") {
$(this).before('</ul></div><div class="span2"><ul>');
}
}
});
Any thoughts? Thanks for your help!
What I have Now
<div class="span2 offset1">
<ul>
<li class="list-header">Home</li>
<li>LASIK</li>
<li>CATARACT</li>
<li>PATIENTS</li>
<li>Cataract Self Evaluation</li>
<li>New Patient Information</li>
<li>Patient Education</li>
<li>3D Eye Library</li>
<li>Vitreo-Retinal Fellowships</li>
<li class="list-header">About Us</li>
<li class="list-header">Doctors</li>
<li class="list-header">Services</li>
<li>Laser Cataract</li>
<li>Cornea</li>
<li>Diabetic Eye Care</li>
<li>Dry Eyes</li>
<li>Flashers & Floaters</li>
<li>Glaucoma</li>
<li>Macular Degeneration</li>
<li>Retinal Detachments</li>
<li class="list-header">Technology</li>
<li class="list-header">News</li>
<li class="list-header">Locations</li>
<li>West Mifflin</li>
<li>Butler</li>
<li>Greensburg</li>
<li>Meadville</li>
<li>Monroeville</li>
<li>Uniontown</li>
<li>Wheeling</li>
<li class="list-header">Patients</li>
<li>Literature</li>
<li>Forms</li>
<li>Patient Education</li>
<li>My AIO</li>
<li class="list-header">Testimonials</li>
<li class="list-header">Clinical Trials</li>
<li class="list-header">Careers</li>
<li class="list-header">Contact Us</li>
<li class="list-header">Site Map</li>
<li class="list-header">Privacy Policy</li>
<li class="list-header">Fellowship</li>
</ul>
</div>
What I want
<div class="span2 offset1">
<ul>
<li class="list-header">Home</li>
<li>LASIK</li>
<li>CATARACT</li>
<li>PATIENTS</li>
<li>Cataract Self Evaluation</li>
<li>New Patient Information</li>
<li>Patient Education</li>
<li>3D Eye Library</li>
<li>Vitreo-Retinal Fellowships</li>
</ul>
</div>
<div class="span2">
<ul>
<li class="list-header">About Us</li>
</ul>
<ul>
<li class="list-header">Doctors</li>
</ul>
<ul>
<li class="list-header">Services</li>
<li>Laser Cataract</li>
<li>Cornea</li>
<li>Diabetic Eye Care</li>
<li>Dry Eyes</li>
<li>Flashers & Floaters</li>
<li>Glaucoma</li>
<li>Macular Degeneration</li>
<li>Retinal Detachments</li>
</ul>
</div>
<div class="span2">
<ul>
<li class="list-header">Technology</li>
</ul>
<ul>
<li class="list-header">News</li>
</ul>
<ul>
<li class="list-header">Locations</li>
<li>West Mifflin</li>
<li>Butler</li>
<li>Greensburg</li>
<li>Meadville</li>
<li>Monroeville</li>
<li>Uniontown</li>
<li>Wheeling</li>
</ul>
</div>
<div class="span2">
<ul>
<li class="list-header">Patients</li>
<li>Literature</li>
<li>Forms</li>
<li>Patient Education</li>
<li>My AIO</li>
</ul>
<ul>
<li class="list-header">Testimonials</li>
</ul>
<ul>
<li class="list-header">Clinical Trials</li>
</ul>
<ul>
<li class="list-header">Careers</li>
</ul>
<ul>
<li class="list-header">Contact Us</li>
</ul>
</div>
<div class="span2">
<ul>
<li class="list-header">Site Map</li>
</ul>
<ul>
<li class="list-header">Privacy Policy</li>
</ul>
<ul>
<li class="list-header">Fellowship</li>
</ul>
</div>
My advice is to do the following:
First, create an array of arrays and fill it with references to the list items as you want them in the separate lists.
Generate the new elements outside of the DOM, moving the list items into them.
Last, replace the existing element in the DOM with the newly created elements.
This has three benefits:
It is most efficient to modify the DOM in a single call.
The DOM will never be in an invalid state.
The code to generate the elements should be simpler if you determine the separate lists first.

Make ul-li navigation dynamically

I have following html:
<div id="nav">
<ul>
<li class="keyitem">keyitem 1</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li class="keyitem">keyitem 2</li>
<li>item</li>
<li>item</li>
<li class="keyitem"></li>
<li>item</li>
<li>item</li>
</ul>
</div>
But i want to make the above like following:
<div id="nav">
<ul>
<li class="keyitem">one
<ul>
<li class="child_one">item</li>
<li class="child_one">item</li>
<li class="child_one">item</li>
</ul>
</li>
<li class="keyitem">two
<ul>
<li class="child_two">item</li>
<li class="child_two">item</li>
</ul>
</li>
<li class="keyitem">three
<ul>
<li class="child_three">item</li>
<li class="child_three">item</li>
</ul>
</li>
</ul>
</div>
Not possible to change the first snippet of code structure. I have to make the first snippet like second snippet and replace with the first one.
please help.
Thanks in advance..
var childClasses = ['child_one', 'child_two', 'child_three' /* more here */];
$('#nav li.keyitem').each(function(i) {
var $li = $(this),
$sub = $li.nextUntil('li.keyitem').addClass(childClasses[i]);
$('<ul />').appendTo($li).append($sub);
});
Will produce:
<div id="nav">
<ul>
<li class="keyitem">keyitem 1
<ul>
<li class="child_one">item</li>
<li class="child_one">item</li>
<li class="child_one">item</li>
</ul>
</li>
<li class="keyitem">keyitem 2
<ul>
<li class="child_two">item</li>
<li class="child_two">item</li>
</ul>
</li>
<li class="keyitem">keyitem 3
<ul>
<li class="child_three">item</li>
<li class="child_three">item</li>
</ul>
</li>
</ul>
</div>
(demo)

Categories

Resources