I am using 'slideToggle' to open a couple divs on a site and want to ensure all of the divs are closed before another is opened. Is there a way to run a if..then to ensure a toggled div isn't open before opening another?
Here is my script;
<script type="text/javascript">
$(function()
{
$("a#toggle").click(function() {
$("#contact").slideToggle(500);
return false;
});
$("a#toggle_about").click(function(){
$("#about").slideToggle(500);
return false;
});
});
</script>
Calling tag;
<li>Contact Me</li>
And called div;
<div id="contact">blah, blah...</div>
And CSS;
#contact{display: none; padding: 7px; font-size: 14px;}
Thanks,
------EDIT------
This seems to work ok, I can control the transition by setting speed to 500 or 0. It just seems like a lot of code for a simple if..then.
Thanks for the suggestions and possible solutions.
<script type="text/javascript">
$(function()
{
$("a#toggle").click(function(){
if ($("#about").is(':hidden')){
$("#contact").slideToggle(500);
return false;
}else{
$("#about").slideToggle(500);
$("#contact").slideToggle(500);
return false;
}
});
$("a#toggle_about").click(function(){
if ($("#contact").is(':hidden')){
$("#about").slideToggle(500);
return false;
}else{
$("#contact").slideToggle(500);
$("#about").slideToggle(500);
return false;
}
});
});
</script>
Fiddle Example
If you add appropriate classes to your html and change the href to target the div it needs to open, you can significantly simplify your code.
<ul>
<li>Contact Me</li>
<li>About Me</li>
</ul>
<div id="contact" class="toggleable">blah, blah...</div>
<div id="about" class="toggleable">blah, blah...</div>
Now you can handle both links with a single event.
$(".toggler").click(function (e) {
e.preventDefault();
var target = $(this).attr("href");
$(".toggleable").not(target).hide();
$(target).slideToggle();
});
the end result is when you click on "Contact Me", about will hide if it is open, and contact will show if it is hidden or hide if it is shown.
http://jsfiddle.net/nYLvw/
You could implement a helper function to collapse any visible elements with a certain class, and then call that every time you're about to toggle a div.
The markup:
<div id="contact" class="toggle-content">blah, blah...</div>
The code:
function hideToggleContent() {
$('.toggle-content:visible').slideUp( 500 );
}
$(function() {
$("#toggle").click( function() {
var isVisible = $("#contact").is(':visible');
hideToggleContent();
if( isVisible ) {
return false;
}
$("#contact").slideDown( 500 );
return false;
});
$("#toggle_about").click( function() {
var isVisible = $("#about").is(':visible');
hideToggleContent();
if( isVisible ) {
return false;
}
$("#about").slideDown( 500 );
return false;
});
});
You might also check out the jQuery UI accordion, it's default behavior accomplishes the same. http://jqueryui.com/accordion/
UPDATE: Added Fiddle Link For Example
There are several ways to solution this problem.
Whenever you are tweening for effect, and you want to only tween if not already tweening, you will want to track the state of your tween.
Typically, you might have a trigger/toggler, and a target. I like to use closures to accomplish the state tracking. I might use something like this:
$(function () {
// closures
var $togglers = $('[selector][, selector]');
var $target = $('[selector]');
$target.tweening = false;
var tweenStop = function () {
$target.tweening = false;
};
var togglerClick = function () {
if (!$target.tweening) {
$target.tweening = true;
$target.slideToggle(500, tweenStop);
}
};
// handle the event
$togglers.click(togglerClick);
});
>> SAMPLE FIDDLE <<
Related
Hi all I am using a down menu on our website and it is all working fine except when you activate one of the drop-downs you can also activate any other drop-down menu without the previous one closing and it looks messy. Can anyone please suggest a way to make the previous menu close when you click on another one?
Here is my script
<script type="text/javascript">
function DropDown(el) {
this.dd1 = el;
this.initEvents();
}
DropDown.prototype = {
initEvents : function() {
var obj = this;
obj.dd1.on('click', function(event){
$(this).toggleClass('active');
event.stopPropagation();
});
}
}
$(function() {
var dd1 = new DropDown( $('#dd1') );
$(document).click(function() {
// all dropdowns
$('.wrapper-dropdown-5').removeClass('active');
});
});
</script>
And here is the HTML
<div id="dd1" class="wrapper-dropdown-5" tabindex="1">School Information
<ul class="dropdown">
<li><i></i>Break and Breakfast Price List</li>
<li><i> </i>Bus Timetables</li>
Many Thanks
J Tech
Instead of removing a class, you need to blur the selects:
$('.wrapper-dropdown-5').blur()
I think you're looking for accordion menu . Here it's example. Demo Download
I'm facing the following issue: I'm working with Angular1.x and I have a subpage with small, clickable images and some other stuff below these imgs.
Only the images should be visible, all the other things should be hidden.
When the user clicks on an image, this hidden-visible has to flip, so the whole image session goes hidden and the content below comes visible.
I have a jQuery solution, but I'm seeking a more semantic one with Angular.
(function($){
$(document).ready(function(){
$('.showOverlay').click(function(){
$('#container').hide();
$('#box').show();
});
$('.hideOverlay').click(function(){
$('#container').show();
$('#box').hide();
});
});
})(jQuery);
I hope this piece of code explains the idea behind.
When you click "Show overlay", it will call the showOverlay() function, same for "Hide overlay":
<div ng-click="showOverlay()">Show overlay</div>
<div ng-click="hideOverlay()">Hide overlay</div>
<div ng-show="container">Shown when $scope.container is true</div>
<div ng-show="box">Shown when $scope.box is true</div>
Add the following functions in your controller:
$scope.showOverlay = function() {
$scope.container = false;
$scope.box = true;
}
$scope.hideOverlay = function() {
$scope.container = true;
$scope.box = false;
}
I would suggest using ng-hide:
in your html
<div ng-hide="myValue"></div>
<button ng-click="show()">show</button
<button ng-click="hide()">hide</button
then in your javascript:
$scope.show = function(){
$scope.myValue = false;
}
$scope.hide = function(){
$scope.myValue = true;
}
Is there any instance when both the container and box should be visible? If not, I dare say you should use the same variable for both of them, like so:
<img ng-src="{{img}}.png" ng-click="hideImage()" ng-show="imageShown">
<div ng-click="showImage()" ng-show="!imageShown">
And in your controller:
$scope.hideImage = function() {
$scope.imageShown = false
}
$scope.showImage = function() {
$scope.imageShown = true
}
Maintaining two variables for values that always mirror each other just seems irresponsible.
I am making a FAQ that ask you 3 question to give you the correct answer. It works in the same way as this website: Nokia Lumia FAQ.
The code works. You have 3 level of content to see depending on the button you press. When a button is pressed on level 1, level 2 and level 3 it will change color so you end with three button that have changed color, its easier to understand in that way you wanted help for Example: Phone - Andriod - Simcard help.
Notice that level 1 and level 2 content have much simliar in the JS code, but level 3 is a bit different because there your browser scroll you down when the content is displayed. And also level 3 does have hyperlink instead of button.
I have to manually dublicate part of this JS code for adding new buttons, and i think there can be an easier way. I really appreciate any help.
Here is the JS:
$(document).ready(function(){
// Level 1
function show(sel) {
var el = $(sel);
el.fadeToggle();
$('.showmore-1').not(el).fadeOut("slow");
}
$('.showmore-1').hide();
$('.click-1').click(function(){
$('.click-1').removeClass('clickcolor')
$(this).addClass('clickcolor');
});
$('#click-1a').click(function () {
show('#showmore-1a');
});
$('#click-1b').click(function () {
show('#showmore-1b');
});
$('#click-1c').click(function () {
show('#showmore-1c');
});
// Level 2
function show(sel) {
var el = $(sel);
el.fadeToggle();
$('.showmore-2').not(el).fadeOut("slow");
}
$('.showmore-2').hide();
$('.click-2').click(function(){
$('.click-2').removeClass('clickcolor')
$(this).addClass('clickcolor');
});
$('#click-2a').click(function () {
show('#showmore-2a');
});
$('#click-2b').click(function () {
show('#showmore-2b');
});
$('#click-2c').click(function () {
show('#showmore-2c');
});
// Level 3
function show(sel) {
var el = $(sel);
el.fadeToggle();
$('.showmore-3').not(el).fadeOut("slow");
}
$('.showmore-3').hide();
$('.click-3').click(function(){
$('.click-3').removeClass('clickcolortext') //Level 3 display text instead of button to be pressed and therefore another class of color.
$(this).addClass('clickcolortext');
});
$('#click-3a').click(function () {
show('#showmore-3a');
$('html, body').scrollTop($('#showmore-3a').offset().top);
return false;
});
$('#click-3b').click(function () {
show('#showmore-3b');
$('html, body').scrollTop($('#showmore-3b').offset().top);
return false;
});
$('#click-3c').click(function () {
show('#showmore-3c');
$('html, body').scrollTop($('#showmore-3c').offset().top);
return false;
});
});
enter code here
Here is a part of the HTML
<button class="click-1" id="click-1a">Mobile</button>
<button class="click-1" id="click-1b">PC</button>
<button class="click-1" id="click-1c">Tablet</button>
<div id="showmore-1a" class="showmore-1">View content for mobile help</div>
<div id="showmore-1b" class="showmore-1">View content for pc help</div>
<div id="showmore-1c" class="showmore-1">View content for tablet help</div>
enter code here
Here is the CSS
.clickcolor {
background-color: #4d4d4d !important;
}
.clickcolortext {
color: #4d4d4d !important;
}
Add a target attribute on buttons:
<button class="click-1" id="click-1a" data-target="#showmore-1a">Mobile</button>
<button class="click-1" id="click-1b" data-target="#showmore-1b">PC</button>
<button class="click-1" id="click-1c" data-target="#showmore-1c">Tablet</button>
JS
$('button.click-1').click(function(){
$('.click-1').removeClass('clickcolor')
$(this).addClass('clickcolor');
show($(this).data('target'));
});
To shorten this bit of code:
$('#click-1a').click(function () {
show('#showmore-1a');
});
$('#click-1b').click(function () {
show('#showmore-1b');
});
$('#click-1c').click(function () {
show('#showmore-1c');
});
Well, I could tell this:
$('[id^="click-"]').click(function () {
show('#showmore-' + this.id.replace("click-", ""));
});
I created expandable content using jquery on several divs with unique ids. The code is working but now I also want to trigger this function from a top navigation using an anchor. I have tried several things but nothing works. I am very new to jquery so any help would be greatly appreciated.
I am specifically trying to invoke the click() function on each anchor.
Here is my jquery:
(function($) {
$(document).ready(function () {
var panelspeed = 500;
var totalpanels = 6;
var defaultopenpanel = 0;
var accordian = true;
var panelheight = new Array();
var currentpanel = defaultopenpanel;
var iconheight = parseInt($('.icon-close-open').css('height'));
var highlightopen = true;
//Initialise collapsible panels
function panelinit() {
for (var i=1; i<=totalpanels; i++) {
panelheight[i] = parseInt($('#cp-'+i).find('.expandable-panel-content').css('height'));
$('#cp-'+i).find('.expandable-panel-content').css('margin-top', -panelheight[i]);
if (defaultopenpanel == i) {
$('#cp-'+i).find('.icon-close-open').css('background-position', '0px -'+iconheight+'px');
$('#cp-'+i).find('.expandable-panel-content').css('margin-top', 0);
}
}
}
$('.expandable-panel-heading').click(function() {
var obj = $(this).next();
var objid = parseInt($(this).parent().attr('ID').substr(3,2));
currentpanel = objid;
if (accordian == true) {
resetpanels();
}
if (parseInt(obj.css('margin-top')) <= (panelheight[objid]*-1)) {
obj.clearQueue();
obj.stop();
obj.prev().find('.icon-close-open').css('background-position', '0px -'+iconheight+'px');
obj.animate({'margin-top':0}, panelspeed);
if (highlightopen == true) {
$('#cp-'+currentpanel + ' .expandable-panel-heading').addClass('header-active');
}
} else {
obj.clearQueue();
obj.stop();
obj.prev().find('.icon-close-open').css('background-position', '0px 0px');
obj.animate({'margin-top':(panelheight[objid]*-1)}, panelspeed);
if (highlightopen == true) {
$('#cp-'+currentpanel + ' .expandable-panel-heading').removeClass('header-active');
}
}
});
function resetpanels() {
for (var i=1; i<=totalpanels; i++) {
if (currentpanel != i) {
$('#cp-'+i).find('.icon-close-open').css('background-position', '0px 0px');
$('#cp-'+i).find('.expandable-panel-content').animate({'margin-top':-panelheight[i]}, panelspeed);
if (highlightopen == true) {
$('#cp-'+i + ' .expandable-panel-heading').removeClass('header-active');
}
}
}
}
//Uncomment these lines if the expandable panels are not a fixed width and need to resize
$( window ).resize(function() {
panelinit();
});
$(window).load(function() {
panelinit();
}); //END LOAD
}); //END READY
})(jQuery);
The html for the expandable jquery content is:
<div class="expandable-panel" id="cp-3">
<div class="expandable-panel-heading">
<h2>Testimonials<span class="icon-close-open"></span></h2>
</div>
<div class="expandable-panel-content">
<p>Panel HTML...</p>
</div>
</div>
The html anchors that I want to trigger the click() function are:
<ul class="nav">
<li class="nav">What is Justice Court Judge?</li>
<li class="nav">About Reeves Jones</li>
<li class="nav">Testimonials</li>
<li class="nav">Polling Locations</li>
<li class="nav">Map</li>
<li class="nav">Contact</li>
</ul>
Thank you in advance for your help!
If I understand correctly, you don't want to trigger the click event for the anchors, but instead you want to trigger the click event of the corresponding navigation element when an anchor is clicked.
You can do that by adding the following code inside your document-ready function:
$('.nav a').click(function() {
$($(this).attr('href')).find('.expandable-panel-heading').click();
});
This code registers a click handler on all the <a> elements inside the .nav element. It uses the href value of the clicked <a> element to get a jQuery object representing the navigation element.
In this case, you should not place the "onclick" attribute on the <a> elements.
BTW: For valid HTML, you should nest the <a> elements inside the <li> elements, not the other way around.
I recommend not to use inline event handlers.
You can add the following to your jquery code:
$(".nav").find('a').trigger("click");
$(".nav").find('a').click(function(){
//your code
})
I'm trying to hide .menu_branch using jQuery slideUp() only if the user clicks off of .menu_root. I'm not getting any errors but the click() function is executing even if .menu_root is clicked. Any ideas? jQuery or straight JavaScript are both fine by me. Thanks!
HTML:
<span class="menu_root">Menu</span>
<ul class="menu_branch">
<li>Home</li>
<li>FAQ</li>
<li>About</li>
<li>Contact</li>
</ul>
CSS:
.menu_branch {
display:block;
}
Jquery:
$("body:not(.menu_root)").click(function(){
$(".menu_branch").slideUp("fast");
});
I've also tried:
$("body").not(".menu_root").click(function(){
$(".menu_branch").slideUp("fast");
});
As well as replacing body with * in both instances, all with the same result.
One possible solution is to prevent the propagation of click event from menu_root
$(document).click(function () {
$(".menu_branch").slideUp("fast");
});
$('.menu_root').click(function (e) {
e.stopPropagation();
})
Demo: Fiddle
Your code will ignore a body element with class menu_root like <body class="menu_root">
You can try this:
$("body").click(function(event){
if ( $(event.target).hasClass("menu_root") ) {
return false;
}
$(".menu_branch").slideUp("fast");
});
http://jsfiddle.net/WzW2D/2/
Late to the party again but this should work for you. Clicking .menu_root will toggle the menu. Clicking anywhere else will close it (if its open).
$(document).on("click", function(e) {//When the user click on any element:
if($(".menu_branch").is(":visible")){//If the menu is open...
$(".menu_branch").slideUp("fast");//close it.
} else if ($(e.target).hasClass("menu_root")){//Otherwise, if the user clicked menu_root...
$(".menu_branch").slideDown("fast");//open it.
}
});
http://jsfiddle.net/xGfTq/
try
$(document).click(function () {
$(".menu_branch").slideUp("fast");
});
$('.menu_root').click(function () {
return false;
})