How to activate menu tab after refreshing - javascript

How can I activate a menu tab after refreshing?
Here are my code
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<style>
.menu{width: 600px; height: 25; font-size: 18px;}
.menu li{list-style: none; float: left; margin-right: 4px; padding: 5px;}
.menu li:hover, .menu li.active {
background-color: #f90;
}
</style>
</head>
<body>
<ul class="menu">
<li><a href='#'>One</a></li>
<li><a href='#'>Two</a></li>
<li><a href='#'>Three</a></li>
<li><a href='#'>Four</a></li>
</ul>
<script type="text/javascript">
var make_button_active = function()
{
//Get item siblings
var siblings =($(this).siblings());
//Remove active class on all buttons
siblings.each(function (index)
{
$(this).removeClass('active');
}
)
//Add the clicked button class
$(this).addClass('active');
}
//Attach events to menu
$(document).ready(
function()
{
$(".menu li").click(make_button_active);
}
)
</script>
Can anyone tell me How to resolve this issue ?

Just like #Johan said, store your last active tab in a localStorage or cookie. Since there is no noticeable difference in performance between the two. I suggest you use localStorage because it's much easier to use. Like this:
function make_button_active(tab) {
//Get item siblings
var siblings = tab.siblings();
//Remove active class on all buttons
siblings.each(function(){
$(this).removeClass('active');
})
//Add the clicked button class
tab.addClass('active');
}
//Attach events to menu
$(document).ready(function(){
if(localStorage){
var ind = localStorage['tab']
make_button_active($('.menu li').eq(ind));
}
$(".menu li").click(function () {
if(localStorage){
localStorage['tab'] = $(this).index();
}
make_button_active($(this));
});
});
Check out this fiddle.

Related

Dropdown Menu Closes On Hover (Error)

Whhenever I hover over the menu it works fine. But, when I try to get to the submenu links and children, the menu closes
/*----------------------------------------------------
/* Dropdown menu
/* ------------------------------------------------- */
jQuery(document).ready(function($) {
function mtsDropdownMenu() {
var wWidth = $(window).width();
if (wWidth > 865) {
$('#navigation ul.sub-menu, #navigation ul.children').hide();
var timer;
var delay = 100;
$('#navigation li').hover(
function() {
var $this = $(this);
timer = setTimeout(function() {
$this.children('ul.sub-menu, ul.children').slideDown('fast');
}, delay);
},
function() {
$(this).children('ul.sub-menu, ul.children').hide();
clearTimeout(timer);
}
);
} else {
$('#navigation li').unbind('hover');
$('#navigation li.active > ul.sub-menu, #navigation li.active > ul.children').show();
}
}
mtsDropdownMenu();
$(window).resize(function() {
mtsDropdownMenu();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li id="menu-item-513" class="menu-item "><i class="fa fa-calculator"></i> OFFERTE AANVRAGEN
<ul class="sub-menu">
<li id="menu-item-1146" class="menu-item">Zonnepanelen installatie (Belgiƫ)
</li>
<li id="menu-item-1144" class="menu-item">Zonnepanelen reinigen (Belgiƫ)
</li>
<li id="menu-item-1145" class="menu-item">Zonnepanelen installatie (Nederland)
</li>
</ul>
</li>
The code you posted works just fine; here's a plnkr to prove it: https://plnkr.co/edit/IFaueUhKE3J1K9vY1NkQ?p=preview
(simply wrapped a <div id='navigation'><ul> round the top li).
If you still loose the hover over the child-elements, it's caused by something you're not showing in the original question. E.g. adding this css:
li.menu-item {
position: relative;
top: 50px;
left: 300px;
}
would make it difficult to reach the child items because you, briefly, lose the parent-hover while moving to the child.

Use of this in javascript/Jquery

I have an anchor tag as below :
<a href='#' class='control_next_photo'>></a>
I have set an event on click of the above anchor as follows:
$('a.control_prev_photo').click(function () {
moveLeft();
return false;
});
Below is the moveLeft function.
function moveLeft() {
$('#post-text-slider ul').animate({
left: + slideWidth
}, 200, function () {
$('#post-text-slider ul li:last-child').prependTo('#post-text-slider ul');
$('#post-text-slider ul').css('left', '');
});
};
Now my concerns is that the above is working perfectly when there is only one "post-text-slider" DIV inside which we have an anchor tag. when a user is clicking on the anchor tag the moveLeft() is getting called which in turn moving the slide to left.
But actually, I have several "post-text-slider" DIVs inside which have their own anchor tag. Now in that case if a user clicks on the anchor tag, it will trigger the moveLeft() for all the "post-text-slider" which is not desirable.
Can someone please assist me with the solution for this.
If I figured out correctly your problem I suggest you:
convert post-text-slider from ID to class
use $(e.target).closest('div.post-text-slider') to get the current div
pass to moveLeft as argument the div element
var slideWidth = 100;
function oldMoveLeft() {
$('.post-text-slider ul').animate({
left: + slideWidth
}, 200, function () {
$('.post-text-slider ul li:last-child').prependTo('.post-text-slider ul');
$('.post-text-slider ul').css('left', '');
});
}
function moveLeft(element) {
var ulEle = element.find('ul');
ulEle.animate({
left: + slideWidth
}, 200, function () {
ulEle.find('li:last-child').prependTo(ulEle);
ulEle.css('left', '');
});
}
$(function () {
$('a.control_prev_photo').click(function (e) {
e.preventDefault();
moveLeft($(e.target).closest('div.post-text-slider'));
});
// old one
$('a.old').click(function () {
oldMoveLeft();
return false;
});
});
.post-text-slider {
width: 100%;
}
.control_prev_photo {
appearance: button;
-moz-appearance: button;
-webkit-appearance: button;
text-decoration: none; font: menu; color: ButtonText;
display: inline-block; padding: 2px 8px;
}
ul {
position: relative;
}
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<div class="post-text-slider">
<a class="control_prev_photo">Click Me</a>
<a class="control_prev_photo old">Old Click Me behoviour</a>
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
</div>
<div class="post-text-slider">
<a class="control_prev_photo">Click Me</a>
<a class="control_prev_photo old">Old Click Me behoviour</a>
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
</div>
<div class="post-text-slider">
<a class="control_prev_photo">Click Me</a>
<a class="control_prev_photo old">Old Click Me behoviour</a>
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
</div>

JQuery contextmenu Not Working On Appended Elements

JSFiddle Demo
On my mail side nav I have a custom right-click hijack of which I have just made it so you can add a new sub-folder as partly seen below;
if ($(this).hasClass('NewSubFolder')) {
if($('ul.inbox-nav li.Clicked').find('ul').length) {
$('ul.inbox-nav li.Clicked > ul').prepend("<li class='NewSubFolder'><input type='text'></li>");
} else {
$('ul.inbox-nav li.Clicked').append('<ul><li class="NewSubFolder"><input type="text"></li></ul>');
}
$("ul.inbox-nav li.Clicked").removeClass('Clicked');
}
This will add another tier where there is not one to prepend where there is, an input field. Currently you have to hit the enter key after typing something for the new folder name and then it will have worked its magic...
...However this newly appended list item does not work when you right-click it.
Hopefully this gets what you need done.
Let me know if the comments are not clear enough.
EDIT
Made an edit to combine the two on(contextmenu) calls into one function. No need for redundancy.
$(document).ready(function() {
// Trigger action when the contexmenu is about to be shown
$('#inbox-nav').on("contextmenu", 'a', function(event) {
event.preventDefault();
$('.clicked').removeClass('clicked'); //Gets rid of all other clicked elements
$(this).closest('li').addClass('clicked');
//Clicks the closest li element
var menu = ($(this).is('#inbox-nav>li>a')) ? 'MailMenuFirstTier' : 'MailMenuSecondTier';
/*This is an inline if statement, read in words it goes like this:
if this element is a direct level link, then we're going to need to use the first menu tier.
else we're going to need use the second menu tier.
*/
$("#" + menu).finish().show(100)
//dynamically calls the menu we're using.
.css({
left: event.pageX,
top: event.pageY
}); //Moves the first mail menu to the event position
});
/*
check the element to see which menut to show instead of using two different things.
*/
$(document).on('mousedown', function(e) {
//Mouse down events!
if ($('.custom-menu').is(':visible') && !$(e.target).parent().hasClass('custom-menu')) {
/*
In English:
if a custom menu is visible, AND the target of the click DOES NOT have the custom-menu class, hide the custom menu.
*/
$('.custom-menu').finish().hide();
}
if ($(e.target).parent().hasClass('custom-menu')) {
//Figure out what to do since your element is a child of the custom menu
$('.custom-menu').finish().hide();
var action = $(e.target).data('action');
//Gets our action element
var clicked = $('.clicked');
//gets the clicked element we will be working on.
switch (action) {
case 'new-folder':
//If the clicked element does not have a child ul element, add one.
$('input.rename').focusout();
//Any current input.renames will have their focus out method called
if (clicked.children('ul').length == 0) {
clicked.append($('<ul></ul>'))
}
var ul = clicked.children('ul');
//Either this child element existed before or we just made it the step before.
var input = $('<input />', {
type: 'text',
value: 'New Sub Folder',
class: 'rename',
'data-start': 'New Sub Folder',
focusout: function() {
var value = ($(this).val() == '') ? $(this).data('start') : $(this).val();
$(this).siblings('a').html(value).show();
$(this).remove();
},
autofocus: true
});
//Creates an input tag of type text, with class rename, a placeholder value, and a focusout function.
var anchor = $('<a>', {
href: '#',
css: {
display: 'none'
}
});
//Creates an anchor tag that is originally hidden
ul.append($('<li>').append([input, anchor]));
ul.find('input').click();
//Adds the (should be selected) element and the anchor
//The input element takes care of things from there
break; // end new-folder case
case 'rename-folder':
$('input.rename').focusout();
//any current input.rename items will have their focusout method called
var anchor = clicked.find('a');
//get our closest anchor of our clicked element
anchor.before($('<input />', {
type: 'text',
value: anchor.html(),
class: 'rename',
'data-start': anchor.html(),
focusout: function() {
var value = ($(this).val() == '') ? $(this).data('start') : $(this).val();
$(this).siblings('a').html(value).show();
$(this).remove();
},
autofocus: true
})).hide();
//Creates an input element, adds it before the anchor element,
//hides anchor element. the newly created input element takes care of things from there
break;
/*
ADD NEW ACTIONS HERE
*/
default:
return;
break;
}
}
}).on('keyup', 'input.rename', function(e) {
//Used for laziness. If a user hits enter in the input.rename tag, we fire the focusout target
e.preventDefault();
if (e.keyCode == 13) {
$(e.target).focusout();
}
});
});
.custom-menu {
display: none;
z-index: 1000;
position: absolute;
margin: 0;
padding: 0;
list-style: none;
overflow: hidden;
border: 1px solid #CCC;
white-space: nowrap;
font-family: sans-serif;
background: #FFF;
color: #333;
border-radius: 5px;
font-size: 12px;
}
.custom-menu li {
padding: 8px 12px;
cursor: pointer;
}
.custom-menu li:hover {
background-color: #DEF;
}
menu {
position: absolute;
}
.custom-menu .divider {
content: " ";
height: 1px;
margin: 4px 10px;
background: #929292;
}
#MailBodyList.custom-menu li.Title {
color: #929292;
}
#MailBodyList.custom-menu li.Title:hover {
background: #FFF;
cursor: default;
}
#MailBodyList.custom-menu li.ForThisSenderMore {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="inbox-nav" id="inbox-nav">
<li class="active">
<a href="javascript:;" data-type="inbox" data-title="Inbox">
<div class="Arrow"></div>Inbox
</a>
<ul>
<li>Sub-Folder 1
</li>
<li>Sub-Folder 2
</li>
<li>
Sub-Folder 3
<ul>
<li>Sub-Folder 1
</li>
<li>Sub-Folder 2
</li>
</ul>
</li>
<li>Sub-Folder 4
</li>
<li>Sub-Folder 5
</li>
</ul>
</li>
<li>
Important
</li>
<li>
Sent
</li>
<li>
<a href="javascript:;" data-type="draft" data-title="Draft"> Draft
<span class="badge badge-danger">8</span>
</a>
</li>
<li>
<a href="javascript:;" class="sbold uppercase" data-title="Trash"> Trash
<span class="badge badge-info">23</span>
</a>
</li>
<li>
<a href="javascript:;" data-type="inbox" data-title="Promotions"> Promotions
<span class="badge badge-warning">2</span>
</a>
</li>
<li>
News
</li>
</ul>
<ul id="MailMenuFirstTier" class="custom-menu">
<li>Mark All As Read</li>
<li>Empty Folder</li>
</ul>
<ul class="custom-menu" id="MailMenuSecondTier">
<li class="NewSubFolder" data-action="new-folder">New Sub-Folder</li>
<li class="Rename" data-action="rename-folder">Rename</li>
<li class="Delete" data-action="delete-folder">Delete</li>
<li>Mark All As Read</li>
<li>Empty Folder</li>
</ul>
You can use .contextmenu() to overwrite right-clic behavior.
$('.NewSubFolder').contextmenu(function() {
console.log("Right clic detected!");
});
Documentation here: https://api.jquery.com/contextmenu/
I hope it helps! :)

why doesn't this drop-down menu work with mouseover and leave?

I want it to display "you" under "Home" when hovering and disappearing when mouse leaving:
// HTML
<ul>
<li><a id="homeBox" href="#">Home</a>
<ul><li><a id="homeSub" href="#">you</a></li></ul>
</li>
</ul>
// javaScript
var homeB= document.getElementById("homeBox");
var homeS = document.getElementById("homeSub")
homeBox.mouseover = function() {
var homeS = document.getElementById("homeSub").style.display= "block";
}
homeBox.mouseleave = function() {
var homeS = document.getElementById("homeSub").style.display= "none";
}
// CSS
<style>
ul li ul li a #homeSub {display: hidden;}
</style>
Why Javascript? Use simple CSS Solution.
ul li ul{display: none;}
ul li:hover ul{display: block;}
DEMO
There were quite a few issues. If you have any questions let me know
homeBox.mouseover
There is no homeBox use homeB, and mouseover isnt an event handler onmouseover is.
homeB.onmouseover
ul li ul li a #homeSub {display: hidden;}
This is looking for a link with a child that has the id homeSub, and display: hidden should be display: none
ul li ul li a#homeSub {display: none;}
var homeS = document.getElementById("homeSub").style.display= "block";
You've already defined homeS
homeS.style.display = 'block';
var homeB = document.getElementById("homeBox");
var homeS = document.getElementById("homeSub");
homeB.onmouseover = function() {
homeS.style.display = "block";
}
homeB.onmouseout = function() {
homeS.style.display = "none";
}
ul li ul li a#homeSub {
display: none;
}
<ul>
<li><a id="homeBox" href="#">Home</a>
<ul><li><a id="homeSub" href="#">you</a></li></ul>
</li>
</ul>
You don't need any javascript for this functionality. Just use CSS - http://jsfiddle.net/akq1e5o6/
P.S.: there is no avaliable hidden value for display property
<ul>
<li><a id="homeBox" href="#">Home</a>
<ul><li><a id="homeSub" href="#">you</a></li></ul>
</li>
</ul>
-Use onmouseover instead of mouseover
-Put your Javascript between script-tags, and in a function that will execute after the page has loaded (and use 'none' instead of 'hidden').
<script>
(function() {
var homeB= document.getElementById("homeBox");
var homeS = document.getElementById("homeSub");
homeB.onmouseover = function() {
homeS.style.display = "block";
}
homeB.onmouseleave = function() {
homeS.style.display= "none";
}
})();
</script>
-And adjust your stylesheet:
<style>
#homeSub {display: none;}
</style>

How to convert unordered list into nicely styled <select> dropdown using jquery?

How do I convert an unordered list in this format
<ul class="selectdropdown">
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
<li>five</li>
<li>six</li>
<li>seven</li>
</ul>
into a dropdown in this format
<select>
<option value="one.html" target="_blank">one</option>
<option value="two.html" target="_blank">two</option>
<option value="three.html" target="_blank">three</option>
<option value="four.html" target="_blank">four</option>
<option value="five.html" target="_blank">five</option>
<option value="six.html" target="_blank">six</option>
<option value="seven.html" target="_blank">seven</option>
</select>
using jQuery?
Edit: When selecting an entry from the select/dropdown the link should open in a new window or tab automatically. I also want to able to style it like: http://www.dfc-e.com/metiers/multimedia/opensource/jqtransform/
$(function() {
$('ul.selectdropdown').each(function() {
var $select = $('<select />');
$(this).find('a').each(function() {
var $option = $('<option />');
$option.attr('value', $(this).attr('href')).html($(this).html());
$select.append($option);
});
$(this).replaceWith($select);
});
});
EDIT
As with any jQuery code you want to run on page load, you have to wrap it inside $(document).ready(function() { ... }); block, or inside it's shorter version $(function() { ... });. I updated the function to show this.
EDIT
There was a bug in my code also, tried to take href from the li element.
$('ul.selectdropdown').each(function() {
var select = $(document.createElement('select')).insertBefore($(this).hide());
$('>li a', this).each(function() {
var a = $(this).click(function() {
if ($(this).attr('target')==='_blank') {
window.open(this.href);
}
else {
window.location.href = this.href;
}
}),
option = $(document.createElement('option')).appendTo(select).val(this.href).html($(this).html()).click(function() {
a.click();
});
});
});
In reply to your last comment, I modified it a little bit but haven't tested it. Let me know.
$('ul.selectdropdown').each(function() {
var list = $(this), select = $(document.createElement('select')).insertBefore($(this).hide());
$('>li a', this).each(function() {
var target = $(this).attr('target'),
option = $(document.createElement('option'))
.appendTo(select)
.val(this.href)
.html($(this).html())
.click(function(){
if(target==='_blank') {
window.open($(this).val());
}
else {
window.location.href = $(this).val();
}
});
});
list.remove();
});
This solution is working also in IE and working with selected item (in anchor tag).
$('ul.selectdropdown').each(function(){
var list=$(this),
select=$(document.createElement('select')).insertBefore($(this).hide()).change(function(){
window.location.href=$(this).val();
});
$('>li a', this).each(function(){
var option=$(document.createElement('option'))
.appendTo(select)
.val(this.href)
.html($(this).html());
if($(this).attr('class') === 'selected'){
option.attr('selected','selected');
}
});
list.remove();
});
Thank you all for posting the codes. My scenario is similar but my situation is for Responsiveness that for x-size it would switch to a dropdown list, then if not x-size, using csswatch to check for the "display" properties of an element that has certain amount of width set to it (eg: 740px). Thought I share this solution for anyone who is interested. This is what I have combined with Tatu' codes. Instead of replacing the html, I created then hide the new html then only add them when necessary:
var $list = $('ul.list');
(listFunc = function(display){
//Less than x-size turns it into a dropdown list
if(display == 'block'){
$list.hide();
if($('.sels').length){
$('.sels').show();
} else {
var $select = $('<select class="sels" />');
$list.find('a').each(function() {
var $option = $('<option />');
$option.attr('value', $(this).attr('href')).html($(this).html());
$select.append($option);
});
$select.insertAfter($list);
$('.sels').on('change', function(){
window.location = this.value;
});
}
} else {
$('.sels').hide();
$list.show();
}
})(element.css('display'));
element.csswatch({
props: 'display'
}).on('css-change', function (event, change) {
return listFunc(change.display);
});
I have recently created a solution where the ul transformed, mimics nearly completely the select.
It has in adition a search for the options of the select and supports the active state. Just add a class with name active and that option will be selected.
It handles the keyboard navigation.
Take a look at the code here: GitHub Code
And a live example here: Code Example
The unordered list must be in the form:
<ul id="...">
<li>...</li>
<li>...</li>
<li><a class="active" href="...">...</a></li>
...
</ul>
To convert the ul to select just call:
$(window).on("load resize", function() {
ulToSelect($("ul#id"), 767);
});
Where #id is an id for the unordered list and 767 is the minimum width of the window for the convertion to take place. This is very useful if you want the convertion to take place only for mobile or tablet.
I found this gorgeous CodePen from #nuckecy for anyone interested:
https://codepen.io/nuckecy/pen/ErPqQm
$(".select").click(function() {
var is_open = $(this).hasClass("open");
if (is_open) {
$(this).removeClass("open");
} else {
$(this).addClass("open");
}
});
$(".select li").click(function() {
var selected_value = $(this).html();
var first_li = $(".select li:first-child").html();
$(".select li:first-child").html(selected_value);
$(this).html(first_li);
});
$(document).mouseup(function(event) {
var target = event.target;
var select = $(".select");
if (!select.is(target) && select.has(target).length === 0) {
select.removeClass("open");
}
});
His default CSS rules:
.select li {
display: none;
cursor: pointer;
padding: 5px 10px;
border-top: 1px solid black;
min-width: 150px;
}
.select li:first-child {
display: block;
border-top: 0px;
}
.select {
border: 1px solid black;
display: inline-block;
padding: 0;
border-radius: 4px;
position: relative;
}
.select li:hover {
background-color: #ddd;
}
.select li:first-child:hover {
background-color: transparent;
}
.select.open li {
display: block;
}
.select span:before {
position: absolute;
top: 5px;
right: 15px;
content: "\2193";
}
.select.open span:before {
content: "\2191";
}

Categories