Check out the treatments menu on right hand side of this website. It has a set of <dt> tags with an <a> tag and a <ul> list of submenu <li> links inside. The top level link and sumbmenu links are grouped together using the rel attribute.
As you can see the submenu slides down when you click the top level link. What I'm trying to do is maintain state between page loads so that if any of the links in the submenus are clicked it will stay open. I am trying to use the rel attribute to do this.
Here is my code so far, I am getting a bit confused with the logic:
function initMenu() {
$('.menu ul:not(.active)').hide();
var checkCookie = $.cookie("nav-item");
if (checkCookie != "") {
$('.menu').each(function () {
var state = $(this).find('a:first-child').attr('rel');
if (state == checkCookie) {
alert(state);
$(this).next().slideToggle('normal');
}
})
}
$('.menu > a:first-child').click(function(e) {
e.preventDefault();
var navIndex = $(this).attr('rel');
$.cookie("nav-item", navIndex);
$(this).next().slideToggle('normal');
});
}
$(function() {
initMenu();
});
EDIT**
I have changed the first part of the code to this in order to try and use the active class. But what its doing is opening all the ul's instead of just the ul that contains the li with the active class.
$('.menu ul:not(.active)').hide();
$('.menu').each(function (){
if ($(this).children(".active")){
$(this).children('ul').slideToggle('normal');
}
});
Update *after update of original question*
Use for the if
if ($(this).find(".active").length){
$(this).children('ul').slideToggle('normal');
}
Original answer
One thing is with
if (state == checkCookie) {
alert(state);
$(this).next().slideToggle('normal');
}
this in this context refers to .menu and not the a link.
You should change it to
if (state == checkCookie) {
alert(state);
$(this).children('ul').slideToggle('normal');
}
The other is that the cookie plugin creates (by default) cookies that belong to the page that created them. So when you change a page it does not have access to a cookie created by another page.
Use the path option when saving $.cookie("nav-item", navIndex, {path: '/'});
The correct way
It would be best though not to rely on cookies for navigation as it will become problematic when a user starts using the back button ..
You should really pass the rel value to the url as the hash #relvalue and use that instead.
(hint: check out window.location.hash)
Related
I‘m using Pollate Template for creating polls. There is a list of user's created Polls, after clicking 3 dots (menu icon), the dropdown list shows up with the option to delete this poll. If the submenu is shown and you click anywhere on the screen it hiding.
But I found a bug, that if you clicking on another sub-menu icon it not hiding other sub-menus (look at the image below).
It should be hidden when clicking anywhere, even if it's a sub-menu icon of another entry.
There is HTML structure:
<div class="pl-options">
<ul class="dropdown"></ul>
</div>
<div class="pl-options">
<ul class="dropdown"></ul>
</div>
After clicking a - dropdown shows up.
There is JQuery:
$.puerto_droped = function( prtclick, prtlist = "ul.dropdown" ){
$(prtclick).livequery('click', function(){
var ul = $(this).parent();
if( ul.find(prtlist).hasClass('open') ){
ul.find(prtlist).removeClass('open');
$(this).removeClass('active');
if(prtclick == ".pl-mobile-menu") $('body').removeClass('active');
} else {
ul.find(prtlist).addClass('open');
$(this).addClass('active');
if(prtclick == ".pl-mobile-menu") $('body').addClass('active');
}
return false;
});
$("html, body").livequery('click', function(){
$(prtclick).parent().find(prtlist).removeClass('open');
$(prtclick).removeClass('active');
if(prtclick == ".pl-mobile-menu") $('body').removeClass('active');
});
}
prtclick -> .pl-user-options
I think that this function $("html, body").livequery('click', function(){... should be edited, but can't achieve it successfully. I've tried in many ways but failed.
One of my tries was:
$(prtclick).click(function(evt){
$(prtclick).find(prtlist).removeClass('open');
$(prtclick).removeClass('active');
if(prtclick == ".pl-mobile-menu") $('body').removeClass('active');
});
But now it not showing sub-menu at all. I need to make an exception for the current entry. Have you any ideas? Thank you.
Before you check for .open class, you can toggle off all other ul.dropdowns.
$(this).closest('.row').siblings('.row').removeClass('active')
.find('ul.dropdown').removeClass('open');
Get current clicked a main parent which has 'row' class,
get its siblings, remove 'active' class of them,
get all ul.dropdowns inside those siblings and remove 'open' class of those uls
Here’s a toggle menu who works perfectly:
If I click on the link (HTML code below), the menu folds. But I want if the users reload the page to keep the state of menu (expand / collapse).
$('#menu_toggle').click(function () {
if ($('body').hasClass('nav-md')) {
$('body').removeClass('nav-md');
$('body').addClass('nav-sm');
$('.left_col').removeClass('scroll-view');
$('.left_col').removeAttr('style');
$('.sidebar-footer').hide();
if ($('#sidebar-menu li').hasClass('active')) {
$('#sidebar-menu li.active').addClass('active-sm');
$('#sidebar-menu li.active').removeClass('active');
}
} else {
$('body').removeClass('nav-sm');
$('body').addClass('nav-md');
$('.sidebar-footer').show();
if ($('#sidebar-menu li').hasClass('active-sm')) {
$('#sidebar-menu li.active-sm').addClass('active');
$('#sidebar-menu li.active-sm').removeClass('active-sm');
}
}
});
<a id="menu_toggle"><i class="fa fa-bars"></i></a>
How to remember the state?
Full project: http://demo.kimlabs.com/gentelella/production/index.html
Thanks
You should use cookies to store booleans, of if the menu has been opened or closed. Then when a page is loaded, it checks for any stored cookies, and by default uses those variables.
For example:
on page load:
var menuOutBoolean = Cookies.get("menuOutB") || false;
if (menuOutBoolean == true || menuOutBoolean == "true"){
//put the menu out
}
else {
//put menu in
}
On change:
if (/*out*/){
Cookies.set("menuOutB","true");
}
else{
Cookies.set("menuOutB","false");
}
Note:
Here I have used this JavaScript API (Jquery Plugin).
This is the sort of thing I'd use localStorage for. Just set some kind of flag in localStorage when the state changes and fetch it when your page loads.
I should add that using css classes to represent view state isn't a good idea and will bite you if your UI gets much more complicated.
I'm using Bootstrap Tab and applying the Drag effect of jQuery Sortable. So far it's working fine on the first level including the Bootstrap Tab. But when it goes to the level 3 of nested level, drag effect is not working properly.
Also the Bootstrap Tab view on the 2nd and 3rd level, each of it's link is not loading the corresponding div view (the one with .tab-pane and reference id), but the first level is working fine. I created a click function of each links to remove the parent 'active' class which displays the links view div upon clicked but seems nothing to work.
var nestedList = $("ul.nested_with_switch li ul").children("li");
nestedList.click(function(){
$(this).data('clicked', true);
})
nestedList.click(function(){
if($(this).data('clicked') === true){
nestedList.parents("ul li").removeClass("active");
nestedList.find("li").removeClass("active");
}
})
Here's the Code.
Start with removing what seems to be code that does nothing... replace:
nestedList.click(function(){
$(this).data('clicked', true);
})
nestedList.click(function(){
if($(this).data('clicked') === true){
nestedList.parents("ul li").removeClass("active");
nestedList.find("li").removeClass("active");
}
})
with:
nestedList.click(function(){
nestedList.parents("li").removeClass("active");
nestedList.find("li").removeClass("active");
})
Next, you probably want to use .children("li") instead of .find("li"), but I'm not 100% sure what you're trying to accomplish with your code.
I have built a simple accordian style menu. It works, but I would like it to have a specific section toggled open when in a path related to that menu. So if I would be in the "Mens" part of the clothing store, the Mens section of the menu with the child would be visible or toggled. Right now you can click and toggle open each section, but they are all closed when the page first loads. The website section I am referring to is here: http://bemidjisports.designangler.com/men The menu is on the left side.
I assume it has something to do with the jQuery .toggle() method, but I am not sure. Could someone give me an example of this based on the code below?
$(document).ready(function() {
$("#nav_1489829 li.link-header a").click(function(e) {
e.preventDefault();
$(this).siblings("ul").slideToggle("fast");
});
});
$(document).ready(function() {
$("#nav_1489829 li.link-header a").click(function(f) {
var href = this.href;
window.location = href;
});
});
$(document).ready(function() {
$("#nav_1489829 li.selected").ready(function(g) {
$("li.selected").toggle();
});
});
Try
$("#nav_1489829 li.selected a").trigger('click');
I'm making a website that uses a Javascript sorter. In addition to the sorter, I also put in some custom javascript, to make certain div's clickable. My reasoning was that using the property just couldn't do all that we wanted it to do, so I stuck with divs, and used javascript to make them function.
Take a look here --
http://www.opohills.com/taipei-rentals.php
You can scroll down to where you see the search bar, and click on one of the apartments. When you go back click (1 bedroom), you'll see that clicking on the apartments doesn't work anymore.
I'm not quite sure what to make of this at all. The javascript for the clickability is at the bottom of the page.
What are your thoughts on this?
Here's my javasscript
<script type='text/javascript'>
$(".box_1").click(function(){
window.location=$(this).find("a").attr("href");
return false;
});
$(".box_2").click(function(){
window.location=$(this).find("a").attr("href");
return false;
});
$(".box_3").click(function(){
window.location=$(this).find("a").attr("href");
return false;
});
$(".apt2").click(function(){
window.location=$(this).find("a").attr("href");
return false;
});
</script>
Thoughts?
UPDATE
In accordance to the suggestions, I've updated the code by moving the javascript for clickability above jquery.quicksand, and initiated it only after the document was ready.
Even with these changes, I'm still having trouble getting it to work.
The latest version of the site can be seen here---
http://www.opohills.com/taipei-rentals.php
Your thoughts greatly appreciated
the script basically works for me (and should for you). your problem is probably that sometimes your dom is not ready:
$(document).ready(function() {
// your code here
});
2 more things.
1.) add "cursor: pointer;" to your css for the clickable boxes (usability)
2.) just trigger the click of your link:
$(".apt2").click(function(){
$(this).find("a").trigger('click');
return false;
});
When I'm using the chorme built in debuger on your website, if I create custome fields like ID on you "li" tags, they are deleted after a filter. I think quicksand is creating a cache during the page loading. You are creating you .click() event only after the initialisation of the quicksand library and it is possible that theses click events are deleted because quicksand replaces your li tags.
Try to initialize your click like
$(function() {
$("#ourHolder li").click(function() { window.location.href=$(this).find('a').attr('href')});
});
You should add an id="ourHolder" to your ul tag to optimize the script speed.
And only after this initialisation start your quicksand object initialisation. Move your
<script src="js/jquery.quicksand.js"></script>
<script src="js/sorter-settings.js"></script>
after the previous click functions.
So you can try to edit our file sorter-settings.js and replace by this code (based on the documentation available here (http://razorjack.net/quicksand/docs-and-demos.html) :
$(document).ready(function() {
// get the action filter option item on page load
var $filterType = $('#filterOptions li.active a').attr('class');
// get and assign the ourHolder element to the
// $holder varible for use later
var $holder = $('ul#ourHolder');
// clone all items within the pre-assigned $holder element
var $data = $holder.clone();
// attempt to call Quicksand when a filter option
// item is clicked
$('#filterOptions li a').click(function(e) {
// reset the active class on all the buttons
$('#filterOptions li').removeClass('active');
// assign the class of the clicked filter option
// element to our $filterType variable
var $filterType = $(this).attr('class');
$(this).parent().addClass('active');
if ($filterType == 'all') {
// assign all li items to the $filteredData var when
// the 'All' filter option is clicked
var $filteredData = $data.find('li');
}
else {
// find all li elements that have our required $filterType
// values for the data-type element
var $filteredData = $data.find('li[data-type=' + $filterType + ']');
}
// call quicksand and assign transition parameters
$holder.quicksand($filteredData, {
duration: 800,
easing: 'easeInOutQuad',
enhancement: function() {
$("#ourHolder li").click(function() { window.location.href=$(this).find('a').attr('href')});
}
}
);
return false;
});
});
Additinaly, I think that this code is useless on your html content.
<!--Begin Sorter-->
<script type='text/javascript'>
$(document).ready(function() {
$('#source').quicksand( $('#destination li') );
});
</script>