I've been coming up with a JQuery toggle with the help of Nicolas R that saves the state of the toggle using a cookie but am currently having trouble implementing it as it pulls in the same title for for all the buttons once activated.
Please find below:
HTML:
<div>
Slide Toggle +
<div id="slide1panel" style="display:none; background-color:#4CF;width:100px;height:200px;"></div>
</div>
<div>
Slide Toggle +
<div id="slide2panel" style="display:none; background-color:#4CF;width:100px;height:200px;"></div>
</div>
JQuery
$(document).ready(function() {
// check the cookies when the page loads
// 1st panel
if ($.cookie('currentToggleslide1panel') === 'visible') {
togglePanel($('#slide1panel'), $('#slide1'), true, 0);
}
// 2nd panel
if ($.cookie('currentToggleslide2panel') === 'visible') {
togglePanel($('#slide2panel'), $('#slide2'), true, 0);
}
//handle the clicking of the show/hide toggle button of the 1st panel
$('#slide1').click(function() {
//toggle the panel as required, base on current state
if ($('#slide1').text() === "Slide Toggle +") {
togglePanel($('#slide1panel'), $('#slide1'), true, 'slow');
}
else {
togglePanel($('#slide1panel'), $('#slide1'), false, 'slow');
}
});
//handle the clicking of the show/hide toggle button of the 2nd panel
$('#slide2').click(function() {
//toggle the panel as required, base on current state
if ($('#slide2').text() === "Slide Toggle +") {
togglePanel($('#slide2panel'), $('#slide2'), true, 'slow');
}
else {
togglePanel($('#slide2panel'), $('#slide2'), false, 'slow');
}
});
});
function togglePanel(panel, button, show, toggleSpeed) {
if(toggleSpeed > 0 || toggleSpeed === 'slow' || toggleSpeed === 'fast') {
panel.slideToggle(toggleSpeed);
} else {
panel.toggle();
}
if (show) {
// Set a cookie containing the panel name
$.cookie('currentToggle' + panel.attr('id'), 'visible', { path: '/' });
button.text('Slide Toggle -');
} else {
// Set a cookie containing the panel name
$.cookie('currentToggle' + panel.attr('id'), 'hidden', { path: '/' });
button.text('Slide Toggle +');
}
}
JS Fiddle
Thanks!
Cozmoz,
I updated the referenced cookie script in your JS Fiddle (see external resources): it seems to work now. When I first tried the cookie was causing a bug.
The text is changing independtly, can you check if you have a bug in the fiddle?
EDIT: new response: the text are different between the panels, in this sample I use the current text and replace the last character by a plus/minus symbol
http://jsfiddle.net/xVa7e/6/
$(document).ready(function() {
// check the cookies when the page loads
// 1st panel
if ($.cookie('currentToggleslide1panel') === 'visible') {
togglePanel($('#slide1panel'), $('#slide1'), 0);
}
// 2nd panel
if ($.cookie('currentToggleslide2panel') === 'visible') {
togglePanel($('#slide2panel'), $('#slide2'), 0);
}
//handle the clicking of the show/hide toggle button of the 1st panel
$('#slide1').click(function() {
//toggle the panel as required
togglePanel($('#slide1panel'), $('#slide1'), 'slow');
});
//handle the clicking of the show/hide toggle button of the 2nd panel
$('#slide2').click(function() {
//toggle the panel as required
togglePanel($('#slide2panel'), $('#slide2'), 'slow');
});
});
function togglePanel(panel, button, toggleSpeed) {
var panelPreviousStateVisible = panel.is(':visible');
// Toggle the div
if (toggleSpeed > 0 || toggleSpeed === 'slow' || toggleSpeed === 'fast') {
panel.slideToggle(toggleSpeed);
} else {
panel.toggle();
}
// Once toggled, set the cookie and the text
if (!panelPreviousStateVisible) {
$.cookie('currentToggle' + panel.attr('id'), 'visible', { path: '/' });
// Set the text by removing the last char and add a minus symbol
button.text(button.text().slice(0,-1) + "-");
} else {
$.cookie('currentToggle' + panel.attr('id'), 'hidden', { path: '/' });
// Set the text by removing the last char and add a plus symbol
button.text(button.text().slice(0,-1) + "+");
}
}
Related
I am having a menu as shown in this fiddle:
http://jsfiddle.net/Gk_999/mtfhptwo/3
(function ($) {
$.fn.menumaker = function (options) {
var cssmenu = $(this), settings = $.extend({
title: "Menu",
format: "dropdown",
sticky: false
}, options);
return this.each(function () {
cssmenu.prepend('<div id="menu-button">' + settings.title + '</div>');
$(this).find("#menu-button").on('click', function () {
$(this).toggleClass('menu-opened');
var mainmenu = $(this).next('ul');
if (mainmenu.hasClass('open')) {
mainmenu.hide().removeClass('open');
}
else {
mainmenu.show().addClass('open');
if (settings.format === "dropdown") {
mainmenu.find('ul').show();
}
}
});
cssmenu.find('li ul').parent().addClass('has-sub');
multiTg = function () {
cssmenu.find(".has-sub").prepend('<span class="submenu-button"></span>');
cssmenu.find('.submenu-button').on('click', function () {
$(this).toggleClass('submenu-opened');
if ($(this).siblings('ul').hasClass('open')) {
$(this).siblings('ul').removeClass('open').hide();
}
else {
$(this).siblings('ul').addClass('open').show();
}
});
};
if (settings.format === 'multitoggle') multiTg();
else cssmenu.addClass('dropdown');
if (settings.sticky === true) cssmenu.css('position', 'fixed');
resizeFix = function () {
if ($(window).width() > 768) {
cssmenu.find('ul').show();
}
if ($(window).width() <= 768) {
cssmenu.find('ul').hide().removeClass('open');
}
};
resizeFix();
return $(window).on('resize', resizeFix);
});
};
})(jQuery);
(function ($) {
$(document).ready(function () {
$("#cssmenu").menumaker({
title: "Menu",
format: "multitoggle"
});
});
})(jQuery);
Now, in jsFiddle, since the menu is responsive, is working fine.
However, if we run it on full screen, upon hover on the parent li list, its children appears compulsorily on the right as shown below.
The problem is that, if we have too many elements in the parent list, & if we hover on the elements at extreme right, its children appear compulsorily on right, & move out of the screen window, as a result, a horizontal scroll-bar appears.
So I want to get the children on the left, rather than right when they are moving out of the screen.
EDIT:
Check fullscreen output here : https://jsfiddle.net/Gk_999/mtfhptwo/3/embedded/result/
Any Help...???
This can only be done with JavaScript is my guess.
Update your ready function with the following mouseenter event. It will fire when somebody moves the mouse over an li with has-sub class.
(function ($) {
$(document).ready(function () {
$("#cssmenu").menumaker({
title: "Menu",
format: "multitoggle"
});
$("li.has-sub").on("mouseenter", function(){
var element = this).find("ul");
//remove the class beforehand so it always defaults to the right.
$(element.removeClass("showleft");
//if the rendered menu and it's page offset are wider then the body
if (element.offsetWidth + element.offset().left > document.body.offsetWidth)
{
element.addClass("showleft");
}
});
});
Add this to the css:
.showleft {
left : -230px !important;
}
It works, look here:
http://jsfiddle.net/mtfhptwo/4/
First, do one thing, get the width of the document using java script and your sub div, set min width of generating div on hover of sub menu if it is greater than minimum height than animate your sub menu(sub div) to wherever you want or you can also give style using java script css property.
i have an accordion but i want the content to slide in from the left after the accordion has come down.
my code so far however this makes the original slide jumpy.
I also have a fiddle showing the original code...
$(function () {
$(".expand").on("click", function () {
$(this).next().toggle("slide", {
direction: "left"
});
$expand = $(this).find(">:first-child");
if ($expand.text() == "\u25B6") {
$expand.text("\u25BC");
} else {
$expand.text("\u25B6");
}
});
});
Try this fiddle.
$(".expand").on("click", function () {
$('.detail').toggle('slide');
})
I use in menu icon search for show in wordpress search toogle bar. Wordpress theme use simple js custom file. This is all about website and menu. But for newsletter i have take plugin newsletter subscription.
If you see menu icons position visit website here
My problem is : I want to block in menu bar icon search and newsletter icon the same position. Now if you click search icon you will see change newsletter position.
This is my js file :
jQuery(document).ready(function( $ ) {
//Javascript Detection
$('body').removeClass('no-js');
//Read More Link
function readmorelink() {
$('a.more-link').closest('p').css('text-align', 'center');
}
readmorelink();
//Flexslider
function flexslider() {
$('.flexslider').flexslider({
animation: "fade",
slideshow: false,
});
$(".flex-next").html('<i class="icon-chevron-right"></i>');
$(".flex-prev").html('<i class="icon-chevron-left"></i>');
}
flexslider();
//Fitvid
function fitvids() {
$(".featured-preview").fitVids();
}
fitvids();
//Comments Toggle
$(".comments-wrapper").hide();
$("#comments-title").attr('class', 'comments-close');
$("#comments-title").toggle(function () {
$(".comments-wrapper").slideDown();
$(this).attr('class', 'comments-open');
$('html, body').animate({
scrollTop: $("#comments-title").offset().top
}, 0);
return false;
}, function (){
$(".comments-wrapper").slideUp();
$(this).attr('class', 'comments-close');
return false;
})
//Infinite Scroll
if ((custom_js_vars.infinite_scroll) == 'no') {
} else {
$('.posts').infinitescroll({
loading: {
msgText: "...Loading Posts...",
finishedMsg: "- End of Posts -"
},
nextSelector: '.post-nav-next a',
navSelector: '.post-nav',
itemSelector: 'article',
contentSelector: '.posts',
appendCallback: true
},function () {
fitvids();
readmorelink();
flexslider();
});
}
$( ".icon-medium.icon-search" ).click(function() {
$(".nksub-tab-icon").toggleClass("newClass");
});
$( ".icon-medium.icon-search" ).click(function() {
$(".nksub-tab-icon").delay(1000).queue(function(next){
$(this).toggleClass("newClass");
next();
});
});
//Cabinet Toggle
$('#cabinet-toggle, #cabinet-toggle-mobile').click(function () {
$("#cabinet-slider").slideToggle(0);
$(".icon-plus-sign").attr('class', 'icon-minus-sign');
return false;
}, function () {
$("#cabinet-slider").slideToggle(0);
$(".icon-minus-sign").attr('class', 'icon-plus-sign');
return false;
});
//Responsive Menu
$('.nav').mobileMenu();
$('select.select-menu').each(function(){
var title = $(this).attr('title');
if( $('option:selected', this).val() != '' ) title = $('option:selected',this).text();
$(this)
.css({'z-index':10,'-khtml-appearance':'none'})
.after('<span class="select"></span>')
});
});
In your CSS, you have this:
body:not([class*=nksub_mobile]) .nks_cc_trigger_tabs.nksub_tab {
top: 327px !important;
}
This will make the icon appear 327 pixels from the top of the screen always. So, when you click on the search icon, the search field appears on top and the 327px is not enough to keep the email newsletter icon on the same level with the search icon.
Workaround: in your:
$( ".icon-medium.icon-search" ).click(function() {
$(".nksub-tab-icon").toggleClass("newClass");
});
In the above function, add some CSS Class to your newsletter selector to adjust the position. Something around 327px + the height of the search box that appears on top.
Hope this helps!
At the moment it shows the divs instead of hiding them and on click it hides just so you can see the movement. Should be .show instead of .hide. On clicking the link, li should slide down and on mouseleave slide back up.
Working example http://jsfiddle.net/DTqDD/3/
jQuery:
$(function() {
var toggleMenu = function(e) {
var self = $(this),
elemType = self[0].tagName.toLowerCase(),
//get caller
menu = null;
if (elemType === 'a') {
//anchor clicked, nav back to containing ul
menu = self.parents('ul').not('ul#mainmenu');
} else if (elemType === 'ul') {
//mouseleft ul, ergo menu is this.
menu = self;
}
if (menu) {
menu.hide('medium');
}
e.preventDefault();
return false;
};
$(document).ready(function() {
$('a.drop').click(function(e) {
$('li#mainmenudrop').show('medium');
console.log('div clicked');
e.preventDefault();
return false;
});
$('li#mainmenudrop a').click(toggleMenu);
$('li#mainmenudrop').mouseleave(toggleMenu);
});
});
On li tags change id="mainmenudrop" to class="mainmenudrop" since it ain't valid HTML. Then use the following jQuery code.
$(document).ready(function() {
$('a.drop').click(function(e) {
$(this).next("div").show('medium');
console.log('div clicked');
e.preventDefault();
return false;
});
$('li.mainmenudrop').mouseleave(function() {
$(this).children("div").hide('medium');
});
});
Could this possibly be what you are trying to accomplish?
EDIT:
If you want the divs hidden at the beginning, just add this CSS:
.mainmenudrop div {
display: none;
}
I need my javascript to only do the callback when I OPEN a section on the accordion, as of right now it does a callback when I open OR close a section because I'm only using a click function. Is there a way I can modify my existing click function to only run when the given section is activated?
My current click function:
$("a#mimetypes").click(function() {
$("span#mimetypesthrobber").loading(true, { max: 1500 })
$.getJSON("../mimetypes", function(data) {
//callback
});
});
Thanks!
EDIT:
I already tried this with another part of the accordion and it wasn't working properly:
$('.ui-accordion').bind('accordionchange', function(event, ui) {
if (ui.newHeader == "Encoders") {
EncodersGet();
}
});
you can use the the "change event"
$('.ui-accordion').bind('accordionchange', function(event, ui) {
ui.newHeader // jQuery object, activated header
ui.oldHeader // jQuery object, previous header
ui.newContent // jQuery object, activated content
ui.oldContent // jQuery object, previous content
});
and access the "newHeadert" for example and do your processing
EDIT
according to the new info {collapsible: true, active: false}
$(document).ready(function() {
var $acc = $('#accordion').accordion({ collapsible: true,
active : false ,
change : function (event, ui)
{
var index = $acc.accordion( "option", "active");
if( index === false){
// all are close
}
else{
// 0-based index of the open section
}
}
});
});
the "option, active" would return you the index of the open section or "false" if all sections are closed
One improvement on undertakerors answer: use triple equals when comparing index to false to avoid the first accordion element to match.
if (index === false) {
// All are closed
} else {
// 0-based index of the open section
}
Please remember that double equals will perform type conversion when evaluating conditions.
If all the accordion sections are closed by dfault you could replace the click event with toggle and have the second function simple do nothing.
$("a#mimetypes").toggle(function() {
$("span#mimetypesthrobber").loading(true, { max: 1500 });
$.getJSON("../mimetypes", function(data) {
//callback
});
},
function() {
//do nothing
});
The better solution would be to add a class to the active section and check for that class before calling the load.
$("a#mimetypes").click(function() {
if ($(this).hasClass("active")) {
$(this).removeClass("active");
}
else {
$(".active").removeClass("active"); //Edit - remove all active classes to account for this section being closed by the opening of another
$(this).addclass("active");
$("span#mimetypesthrobber").loading(true, { max: 1500 });
$.getJSON("../mimetypes", function(data) {
//callback
});
}
});