I am building a project that has multiple panels, triggered by one of three buttons. When a button is clicked, a panel slides out, and any existing panels slide away. I started off using toggles, but I needed all of the toggles to work with eachother, so I changed the event to a click.
Everything is working great, but I have run into a problem closing up the panels. You can see a jsfiddle demo here: http://jsfiddle.net/3W4uG/1/
As you can see, the panels open up just great; however, you cannot close them by pressing the button again.
My JQuery looks like this:
$("a.button").on("click", function(e){
idClick = $(this).attr("id");
newSelector = $("#pane"+idClick);
//close panes and remove active classes
$(".pane").removeClass("panelUp");
$("a.button").removeClass("activeBtn");
//make active
$(this).addClass("activeBtn");
newSelector.addClass("panelUp");
e.preventDefault();
});
I was thinking about implementing a conditional statement so emulate a toggle like so:
var thisBtn = $(this);
if(thisBtn.hasClass("activeBtn")){
$(this).removeClass("activeBtn"); //remove active state
newSelector.removeClass("panelUp"); //remove panel with css3
}
else{
$(".pane").removeClass("panelUp"); //closes down any other pane
$("a.button").removeClass("activeBtn"); //removes all other active classes
$(this).addClass("activeBtn"); //add active class to button just clicked
newSelector.addClass("panelUp"); //slides up new pane with css3
}
This didnt work. In fact, it stopped all the panels from working all together. What can I do to make this work without switching to a toggle?
http://jsfiddle.net/3W4uG/5/
$("a.button").on("click", function(e){
var idClick = $(this).attr("id");
var newSelector = $("#pane"+idClick);
var isCurrentPane= $(this).hasClass("activeBtn");
$(".pane").removeClass("panelUp");
$(".button").removeClass("activeBtn");
if(!isCurrentPane)
{
$(this).addClass("activeBtn");
newSelector.addClass("panelUp");
}
e.preventDefault();
});
One possible solution is remembering original state of the current panel (see wasActive bellow), and not reopening the panel if it was originally opened.
$("a.button").on("click", function(e) {
idClick = $(this).attr("id");
newSelector = $("#pane" + idClick);
var wasActive = newSelector.hasClass('panelUp'); // newly added
//close panes and remove active classes
$(".pane").removeClass("panelUp");
$("a.button").removeClass("activeBtn");
if (!wasActive) { // newly added
//make active
$(this).addClass("activeBtn");
newSelector.addClass("panelUp");
}
e.preventDefault();
});
Updated FIDDLE.
Related
I have a table. Each column has a button at the top. If the td elements below within the column have content in them, then hide the button. If not then display the button and onClick add class active too the td element.
$(document).ready(function (){
$('.button-fill').on("click", function() {
var i=$(this).parent().index();
if($(this).closest("tr").siblings().find("td:eq("+i+")").text()=="")
$(this).hide();
else
$(this).show();
});
<!-- Fill in the td -->
$('.button-fill').on("click", function() {
var i=$(this).parent().index();
$(this).closest("tr").siblings().find("td:eq("+i+")").addClass("active");
//});
});
});
http://jsfiddle.net/ujw0u6au/
I've created a jsfiddle. I don't know what i'm doing wrong? Thank you
Since you have bind the button toggle logic inside button click - you will always have the button in the starting. When you will click on the button only then it will first hide the button and then make the content active.
In case you want this behavior in the starting as soon as the page loads, you should change below line (the 2nd line in your code) from your code -
$('.button-fill').on("click", function() {
to
$('.button-fill').each( function(i,e) {
also, you should not use <!-- Fill in the td --> style of commenting in JavaScript.
I can see you are having two "click" event handler on same class. Instead of it, you can merge it as well.
Here is the optimized version of your code :
JavaScript :
$(document).ready(function (){
$('.button-fill').on("click", function() { //Only one click event handler
var $this = $(this);
var i=$this.parent().index();
var $trSibling = $this.closest("tr").siblings();
$this.toggle($trSibling.find("td:eq("+i+")").addClass("active").text() != ""); //adds the class as well and check the text as well.
})
$(".button-fill").trigger("click");
// explicitly clicking on button to make sure that initially button should not be shown if column text is not empty
});
JSFiddle link : http://jsfiddle.net/ujw0u6au/1/
Is this the same what you want?
#Vijay has the right answer, but as a side note, you need to change this:
if($(this).closest("tr").siblings().find("td:eq("+i+")").text()=="")
to this
if($(this).closest("tr").siblings().find("td:eq("+i+")").text()!="")
if you want to hide the button when there is content, instead of the other way around (notice the != near the end).
I am using a 3 tab menu when active tag being on form 1 when page loads. When each tab is clicked the active tag should be removed and applied to the new selected form. form1 form2 form3
This works fine when I do not add the forms to each tab. But when I do add the forms the problem persist.
I am making the forms with contact 7 the wordpress plugin. Would my javascript be conflicting with something existing?
This is my javascript? Is there a way I could change it to make it work better with contact 7 plugin?
<script>
$('#myForm a').click(function (e) {
var tab = $(this);
if(tab.parent('li').hasClass('active')){
window.setTimeout(function(){
$(".tab-pane").removeClass('active');
tab.parent('li').removeClass('active');
},1);
}
});
</script>
You can see the site im working on Click Here
The forms on the home page in the tabs.
You can simplify your logic by removing the active class on all of it's sibling li elements and then add the active class to the one that was clicked.
$('#myForm a').click(function (e) {
var tab = $(this);
tab.parent('li').siblings('li').removeClass('active');
tab.parent('li').addClass('active');
});
So far I have this drop-down menu. When I click on either "Menu", "Menu1" or "Menu2", the links under it will drop down.
The problem:
I need to display only one drop-down at a time, so that the user can switch between them.
I tried to apply css('overflow', 'hidden'); to the menu currently dropped down, but it won't work, since the overflow: visible !important; is applied to the .clicked class.
Please help, anything will be highly appreciated!
Try when you click on a element remove class clicked from all elements and add class clicked to the element that is clicked
$("#product-menu>ul>li").click(function () {
var hidden = $(this).find('.clicked');
$("#product-menu>ul>li").removeClass('clicked');
$(this).addClass('clicked');
$('.productSubmenu').width(menuWidth);
});
DEMO
UPDATE
If you want also on second click menu to be closed try checking if clicked item has already class clicked:
$("#product-menu>ul>li").click(function () {
var hidden = $(this).find('.clicked');
if ($(this).hasClass('clicked')) {
$(this).removeClass('clicked')
} else {
$("#product-menu>ul>li").removeClass('clicked');
$(this).addClass('clicked');
}
$('.productSubmenu').width(menuWidth);
});
DEMO2
You also might want to close the links
$("#product-menu>ul>li").click(function () {
var hidden = $(this).find('.clicked');
$("#product-menu>ul>li").removeClass('clicked');
$("#product-menu .productSubmenu2").hide(); // this one I added
$(this).addClass('clicked');
$('.productSubmenu').width(menuWidth);
});
I have created a collapsible menu in JQuery with the help of some coding I've found around this site.
And everything work. But now it's time for me to understand how and why it works.
The JQuery:
jQuery(document).ready(function($) {
var submenu = $('.submenu').hide();
$('.open').click(function() {
$this = $(this);
$target = $this.parent().next();
if(!$this.hasClass('close')){
$('.open').removeClass('close');
submenu.slideUp();
$this.addClass('close');
$target.slideDown();
}else{
$target.slideUp();
$this.removeClass('close');
}
});
});
The HTML and CSS are in here: JSFIDDLE!
Can someone break the code down for me, and explain what it does.
I know that it hides my .submenu class when the page loads.
And when I click the class .open the .submenu. slides down
But then I am a bit lost to what it does with my .close class.
Thanks in advance!
No problems :)
Let's start with this:
jQuery(document).ready(function($){});
this wraps around all jQuery code. it defines an anonymous function and attaches it to the event $(document).ready meaning - this code runs only after the entire DOM is loaded. This is needed because if the following code will run before the elements were loaded it will have no effect on them,
var submenu = $('.submenu').hide();
This line picks all elements with class="submenu", hides them - and returns an array of all submenus to the submenu variable. The rest of the explanation will be commented on each line:
$('.open').click(function() { // the following code will run if you click an element with class="open"
$this = $(this); // $this will hold the element you clicked
$target = $this.parent().next(); // $target will hold the next element (relevant single submenu)
if(!$this.hasClass('close')){ // if the current element is open (marked by class="closed")
$('.open').removeClass('close'); // remove the "close" class from all main menu items
submenu.slideUp(); // close all submenus
$this.addClass('close'); // add "close" class only to the clicked main menu item
$target.slideDown(); // open the correct submenu (the element after the clicked main menu item)
}else{ // if current submenu is already open
$target.slideUp(); // close it
$this.removeClass('close'); // remove class "close" from the main menu item.
}
});
When user clicks on a menu group, you need to consider two cases:
The clicked menu group is closed (i.e. it doesn't have the close class)
!$this.hasClass('close')
If so, you first have to close all open menus, and set their class accordingly:
$('.open').removeClass('close');
submenu.slideUp();
Then you can expand the clicked menu group, and mark it as currently open:
$this.addClass('close');
$target.slideDown();
The clicked menu group is already open. The only thing that needs to be done in that case is closing the menu:
$target.slideUp();
$this.removeClass('close');
I know with jQuery it is quite easy to see if a user has clicked outside of a particular element and then react to it, much like how clicking outside of an open drop down menu will close it.
I am trying to achieve something similar with JavaScript alone, no jQuery. Here is my current code:
window.onload = function() {
var nav = document.querySelectorAll('ul li.current_page_item');
var navList = nav[0].parentNode;
//Open the navigation menu list
nav[0].onclick = function() {
navList.className = 'open';
}
}
As of now, the code will apply a class of open to an unordered list if its child element li.current_page_item is clicked on.
I would like to trigger an event (to remove the open class) if the user clicks outside of the li.current_page_item list item.
Could someone show how I could listen for then react to an event that would do something like this with JavaScript alone?
Thank you for your time.
Add click on the document that will close the div, and remember to stopPropagation in the li handler or it will propagate to the document as well.
document.onclick = function(e) {
navList.className = 'close';
}
nav[0].onclick = function(e) {
navList.className = 'open';
e.stopPropagation(); // <----
}