Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jquery multiple div toggle

OK. It won't take anybody long to work out that I am learning jQuery here and might have gone about this in THE most cack-handed way possible. That's why I'm here though.

I have been creating a "panel" based menu system that provides a number of different functions (menu, filter, search, basket and account). I have it 99% where I want to be. Indeed if you click on the menu icon (as an example) you will see the exact effect. Click it again and everything is perfect.

My problem comes when the user clicks on another icon with their initial "panel" open. Now you can see the gaps in my knowledge.

Please note the effect is on a different div for the panel and on the same div each time (main). Naturally it would be best if either: a) when clicking on a new icon without closing a panel the jQuery closes the previous panel, removes the close-btn, slides back the main and then opens fires the new panel. or b) it closes the previous panel, removes the close-btn but keeps the main open (I think this is over complicating).

HTML

<div id="mainpanel">
<div class="menunav">
    <div class="toggle menu-btn"></div>
    <div class="toggle filter-btn"></div>
    <div class="toggle search-btn"></div>
    <div class="toggle basket-btn"></div>
    <div class="toggle account-btn"></div>
</div>
</div>
<div class="togglepanel mainmenu">
menu here
</div>
<div class="togglepanel filter">
filter here
</div>
<div class="togglepanel search">
search here
</div>
<div class="togglepanel basket">
basket here
</div>
<div class="togglepanel account">
account here
</div>
<main>
content will be here
</main>

CSS

#mainpanel {
position: fixed;
display: table;
top: 0;
left: 0;
width: 125px;
height: 100%;
background: #206ba4;
vertical-align: middle;
z-index: 9999;}

main {
position: relative;
top: 0;
margin-left: 125px;
transform: translateX(0);
transform: translateY(0);
transition: transform .5s;}

.move {
transform: translateX(300px) !important;}

.menunav {
display: table-cell;
color: #fff;
z-index: 1001;
margin: 20px 0 0;
text-align: center;
vertical-align: middle;}

.menunav div {
display: block;
width: 100%;
margin: 0 0 30px;
text-align: center;}

.menu-btn:after, .filter-btn:after, .search-btn:after, .basket-btn:after, .account-btn:after, .close-btn:after {
font-family: FontAwesome;
content: "menu";
font-size: 1.8em;
font-weight: 200;
color: #fff;
display: block;
height: 1em;
width: 1em;
margin: 0 0 0 30%;
cursor: pointer;}

.filter-btn:after {
content: "filter";}

.search-btn:after {
content: "search";}

.basket-btn:after {
content: "basket";}

.account-btn:after {
content: "account";}

.close-btn:after {
content: "close";}

.mainmenu, .filter, .search, .basket, .account {
position: fixed;
width: 300px;
top: 0;
left: 125px;
height: 100%;
background: #54a4de;
transform: translateX(-100%);
transition: transform .5s;
z-index: -1;}

.expand {
transform: translateX(0px);}

jQuery

jQuery(function($){
    $('.menu-btn').click(function(){
    $('.mainmenu').toggleClass('expand')
    $('main').toggleClass('move')
    $('.menu-btn').toggleClass('close-btn')
     })
})
jQuery(function($){
    $( '.filter-btn' ).click(function(){
    $('.filter').toggleClass('expand')
    $('main').toggleClass('move')
    $('.filter-btn').toggleClass('close-btn')
     })
})
jQuery(function($){
    $( '.search-btn' ).click(function(){
    $('.search').toggleClass('expand')
    $('main').toggleClass('move')
    $('.search-btn').toggleClass('close-btn')
 })
})  
jQuery(function($){
    $( '.basket-btn' ).click(function(){
    $('.basket').toggleClass('expand')
    $('main').toggleClass('move')
    $('.basket-btn').toggleClass('close-btn')
     })
})  
jQuery(function($){
    $( '.account-btn' ).click(function(){
    $('.account').toggleClass('expand')
    $('main').toggleClass('move')
    $('.account-btn').toggleClass('close-btn')
     })
})

Here is the jsfiddle

Many thanks, in advance, for any pointers....my head hurts!

like image 286
Justin Thomas Avatar asked Nov 09 '15 06:11

Justin Thomas


2 Answers

DEMO HERE

Many redundant code in your attempt, but still a good attempt to achieve this. So below are my suggestions to achieve this.

Tips:

  • Do not include multiple jQuery(function as this is equivalent to $(document).ready function and its good if you have only one per js file
  • Write a single common event to all the buttons and differentiate based on $(this) for each click that happens

  • Add an extra data-* attribute to your .toggle element, say here data-target, to target its corresponding panel-body

So below are some changes I made to your code..

HTML

<div class="menunav">
    <!--data-target to each of its corresponding body class-->
    <div class="toggle menu-btn" data-target=".mainmenu"></div>
    <div class="toggle filter-btn" data-target=".filter"></div>
    <div class="toggle search-btn" data-target=".search"></div>
    <div class="toggle basket-btn" data-target=".basket"></div>
    <div class="toggle account-btn" data-target=".account"></div>
</div>

JS

jQuery(function($){
    //click event to one common class i.e toggle
    $('.toggle').click(function(){
        var target=$(this).data('target'); //get the clicked element's target property
        $('.togglepanel').not($(target)).removeClass('expand');
        //remove class from all the togglepanel elements except the current element's target
        $('.toggle').removeClass('close-btn');
        //general action in any scenario to remove close-btn
        if($(target).hasClass('expand'))
        {
            //if target has expand class then remove it and do necessary changes
            $(target).removeClass('expand')
            $('main').removeClass('move')
            $(this).removeClass('close-btn')
        }
        else
        {
            //else add necessary classes
            $(target).addClass('expand')
            $('main').addClass('move')
            $(this).addClass('close-btn')
        }
     })
})
like image 83
Guruprasad J Rao Avatar answered Sep 22 '22 04:09

Guruprasad J Rao


jQuery(function($){
        $(document).on('click', '.toggle', function (){
            
            // to close all open contents
            $('.togglepanel').removeClass('expand');
            $('main').removeClass('move');
            
           var target = $(this).data("target");
            
            if( $(this).hasClass('close-btn') ){
              $('.toggle').toggleClass('close-btn', false);
               $('main').toggleClass('move', false)
               $(target).toggleClass('expand', false);
            }else{
              $('.toggle').toggleClass('close-btn', false);
              $(this).toggleClass('close-btn', true);
              $('main').toggleClass('move', true)
               $(target).toggleClass('expand', true);
            }
            
        });
    
	})
#mainpanel {
	position: fixed;
	display: table;
	top: 0;
	left: 0;
	width: 125px;
	height: 100%;
	background: #206ba4;
	vertical-align: middle;
	z-index: 9999;
}

main {
    position: relative;
	top: 0;
	margin-left: 125px;
	transform: translateX(0);
	transform: translateY(0);
	transition: transform .5s;
}

.move {
	transform: translateX(300px) !important;
}

.menunav {
	display: table-cell;
	color: #fff;
	z-index: 1001;
	margin: 20px 0 0;
	text-align: center;
	vertical-align: middle;
}

.menunav div {
	display: block;
	width: 100%;
	margin: 0 0 30px;
	text-align: center;
}

.menu-btn:after, .filter-btn:after, .search-btn:after, .basket-btn:after, .account-btn:after, .close-btn:after {
	font-family: FontAwesome;
	content: "menu";
	font-size: 1.8em;
	font-weight: 200;
	color: #fff;
	display: block;
	height: 1em;
	width: 1em;
	margin: 0 0 0 30%;
	cursor: pointer;
}

.filter-btn:after {
	content: "filter";
}

.search-btn:after {
	content: "search";
}

.basket-btn:after {
	content: "basket";
}

.account-btn:after {
	content: "account";
}

.close-btn:after {
    content: "close";
}
}

.close-btn:after {
	content: "\f00d";
}

.mainmenu, .filter, .search, .basket, .account {
	position: fixed;
	width: 300px;
	top: 0;
	left: 125px;
	height: 100%;
	background: #54a4de;
	transform: translateX(-100%);
	transition: transform .5s;
	z-index: -1;
}

.expand {
	transform: translateX(0px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mainpanel">
    <div class="menunav">
        <div class="toggle menu-btn" data-target=".mainmenu"></div>
        <div class="toggle filter-btn" data-target=".filter"></div>
        <div class="toggle search-btn" data-target=".search"></div>
        <div class="toggle basket-btn" data-target=".basket"></div>
        <div class="toggle account-btn" data-target=".account"></div>
    </div>
</div>
<div class="togglepanel mainmenu">
    menu here
</div>
<div class="togglepanel filter">
    filter here
</div>
<div class="togglepanel search">
    search here
</div>
<div class="togglepanel basket">
    basket here
</div>
<div class="togglepanel account">
    account here
</div>
<main>
    content will be here
</main>

You are actually doing a lot of codes which can be converted to a single line. Instead of adding a click event on each buttons, try something like this:

First, add a data-target attribute to your buttons, something like:

<div class="toggle menu-btn" data-target=".mainmenu"></div>
<div class="toggle filter-btn" data-target=".filter"></div>
<div class="toggle search-btn" data-target=".search"></div>
<div class="toggle basket-btn" data-target=".basket"></div>
<div class="toggle account-btn" data-target=".account"></div>

And on your jQuery:

jQuery(function($){
    $(document).on('click', '.toggle', function (){

        // to close all open contents
        $('.togglepanel').removeClass('expand');
        $('main').removeClass('move');

       var target = $(this).data("target");

        if( $(this).hasClass('close-btn') ){
           $('.toggle').toggleClass('close-btn', false);
           $('main').toggleClass('move', false)
           $(target).toggleClass('expand', false);
        }else{
           $('.toggle').toggleClass('close-btn', false);
           $(this).toggleClass('close-btn', true);
           $('main').toggleClass('move', true)
           $(target).toggleClass('expand', true);
        }

    });
});
like image 20
Dexter Bengil Avatar answered Sep 23 '22 04:09

Dexter Bengil