Reputation: 18883
The below HTML, CSS, Bootstrap 4 code produces an accordion-style expandable/collapsible sidebar menu that looks like this:
What I'm trying to do
Either via Bootstrap 4 OR jQuery OR straight Javascript...
If I click the "Push Mowers" link and then click back, I want the sidebar to expand all parent nodes above showing the "Push Mowers" item again. This means the sidebar would need to expand (show): Gardening, Equipment and Lawn Mowers in-order to show the previously-clicked item "Push Mowers".
My first attempt to solve this is to add a URL Fragment to the last item clicked using Javascript:
<script>
$('.list-group').on('click', '.list-group-item', function(){
var clickedID = this.id;
// alert(clickedID);
window.location.hash = clickedID;
});
</script>
Next, I'm not sure how to proceed. I started down this path but this looks horribly and inefficient especially since I'm using Bootstrap 4.
// probably a terrible idea
<script>
if(window.location.hash) {
var hash = window.location.hash.slice(1);
var elem = document.getElementById(hash);
var node = elem.hash.slice(1);
var x = document.getElementById(node);
x.classList.add('show');
console.log(x);
var pn = x.parentNode;
console.log(pn.getAttribute('href'))
} else {
// Fragment doesn't exist
}
</script>
I'm really unclear how to recursively expand all parent categories above a given node.
The Reproducible HTML, CSS, Bootstrap:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css">
<style>
.leve-0 {
padding-left: 15px;
}
.level-1 {
padding-left: 30px;
}
.level-2 {
padding-left: 45px;
}
.level-3 {
padding-left: 60px;
}
</style>
<div class="container-fluid">
<div class="row">
<div class="text-nowrap">
<div id="sidebar">
<div class="list-group panel">
<a href="#node11" class="list-group-item level-0" data-parent="#sidebar" data-toggle="collapse"
aria-expanded="true" id="gardening">Gardening <i class="fa fa-caret-down"></i></a>
<div class="collapse" id="node11">
<a href="#node13" class="list-group-item level-1" data-parent="#node13" data-toggle="collapse"
id="lawn-chemicals">Lawn Chemicals <i class="fa fa-caret-down"></i></a>
<div class="collapse" id="node13">
<a href="gardening/lawn-chemicals/moss-control/" class="list-group-item level-2" data-parent="#node13"
id="moss-control">Moss Control</a>
</div>
<a href="#node14" class="list-group-item level-1" data-parent="#node14" data-toggle="collapse"
id="equipment">Equipment <i class="fa fa-caret-down"></i></a>
<div class="collapse" id="node14">
<a href="#node15" class="list-group-item level-2" data-parent="#node15" data-toggle="collapse"
id="lawn-mowers">Lawn Mowers <i class="fa fa-caret-down"></i></a>
<div class="collapse" id="node15">
<a href="gardening/equipment/lawn-mowers/push-mowers/" class="list-group-item level-3" data-parent="#node15"
id="push-mowers">Push Mowers</a>
<a href="gardening/equipment/lawn-mowers/riding-mowers/" class="list-group-item level-3" data-parent="#node15"
id="riding-mowers">Riding Mowers</a>
</div>
<a href="gardening/equipment/weed-wackers/" class="list-group-item level-2" data-parent="#node15"
id="weed-wackers">Weed Wackers</a>
</div>
</div>
</div>
</div>
</div>
</div>
Upvotes: 0
Views: 614
Reputation: 3091
You need only to traverse DOM up and it is quite easy with jQuery:
// just mocking history back
var historyHashArray = [
"push-mowers",
"equipment",
"gardening",
"moss-control",
];
var currentHistoryIndex = 0;
// get reverse order of $ elements
jQuery.fn.reverse = [].reverse;
function expandTree() {
if (currentHistoryIndex < historyHashArray.length) {
console.log(historyHashArray[currentHistoryIndex]);
$('.collapse').removeClass('show'); // resets
$('#' + historyHashArray[currentHistoryIndex])
.parents('.collapse')
.reverse()
.collapse('show');
currentHistoryIndex++;
}
}
document.getElementById('back-btn').onclick = expandTree;
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css">
<style>
.leve-0 {
padding-left: 15px;
}
.level-1 {
padding-left: 30px;
}
.level-2 {
padding-left: 45px;
}
.level-3 {
padding-left: 60px;
}
</style>
<button type="button" id="back-btn" class="mb-3">History Back</button>
<div class="container-fluid">
<div class="row">
<div class="text-nowrap">
<div id="sidebar">
<div class="list-group panel">
<a href="#node11" class="list-group-item level-0" data-toggle="collapse"
aria-expanded="true" id="gardening">Gardening <i class="fa fa-caret-down"></i></a>
<div class="collapse" id="node11">
<a href="#node13" class="list-group-item level-1" data-toggle="collapse"
id="lawn-chemicals">Lawn Chemicals <i class="fa fa-caret-down"></i></a>
<div class="collapse" id="node13">
<a href="gardening/lawn-chemicals/moss-control/" class="list-group-item level-2" id="moss-control">Moss Control</a>
</div>
<a href="#node14" class="list-group-item level-1" data-toggle="collapse" id="equipment">Equipment <i class="fa fa-caret-down"></i></a>
<div class="collapse" id="node14">
<a href="/" class="list-group-item level-2" data-toggle="collapse" id="lawn-mowers">Lawn Mowers <i class="fa fa-caret-down"></i></a>
<div class="collapse" id="node15">
<a href="/" class="list-group-item level-3" id="push-mowers">Push Mowers</a>
<a href="/" class="list-group-item level-3" id="riding-mowers">Riding Mowers</a>
</div>
<a href="gardening/equipment/weed-wackers/" class="list-group-item level-2" id="weed-wackers">Weed Wackers</a>
</div>
</div>
</div>
</div>
</div>
</div>
Update: So with your click event, it should be something like
$(document).ready(function() {
if (window.location.hash) {
var id = window.location.hash; // luckily it already includes #
$(id).parents('.collapse').collapse('show');
}
});
Upvotes: 1