Troubleshooting the sidebar pin-unpin problem using Jquery and CSS

I have created a single side panel that allows me to toggle between opening and closing the sidebar by hovering on it. I can also pin and unpin the sidebar by clicking on the pin image. Now, I want to open the sidebar onClick instead of onHover and remove the onHover functionality. Additionally, I wish to add a feature where clicking on the box to open the sidebar automatically pins it, eliminating the need for manual pinning. Once the sidebar is opened with a click, it should remain open until clicked again. To close the sidebar, I must click on the same box used to open it.

Code Sample

HTML

<ul id="dock">
            <li id="files">
                <ul class="free">
                    <li class="header"><a href="javascript:void(0);" class="dock"><IMG SRC="https://cdn2.iconfinder.com/data/icons/snipicons/500/pin-128.png" WIDTH="16" HEIGHT="16" BORDER="0" ALT="Dock"  style = "padding-top: 12px;"></a><a href="#" class="undock"><IMG SRC="https://cdn2.iconfinder.com/data/icons/oxygen/48x48/actions/note2.png" WIDTH="16" HEIGHT="16" BORDER="0" ALT=""  style = "padding-top: 12px;"></a><H5 ID="colorgreen">DISCOVER </h4></li>
                    <div id="accordion">
                      <h3>Section 1</h3>
                      <div class = "accordionheight">
                        <p>
                        accordion 1 content
                        </p>
                      </div>
                      <h3>Section 2</h3>
                      <div class = "accordionheight">
                        <p>
                        accordion 2 content
                        </p>
                      </div>
                      <h3>Section 3</h3>
                      <div class = "accordionheight">
                        <p>
                        accordion 3 content
                        </p>
                      </div>
                    </div>
                </ul>
            </li>

            <li id="tools">
                <ul class="free">
                    <li class="header"><a href="#" class="dock"><IMG SRC="https://cdn2.iconfinder.com/data/icons/snipicons/500/pin-128.png" WIDTH="16" HEIGHT="16" BORDER="0" ALT="Dock"></a><a href="#" class="undock"><IMG SRC="https://cdn2.iconfinder.com/data/icons/oxygen/48x48/actions/note2.png" WIDTH="16" HEIGHT="16" BORDER="0" ALT="Undock"></a><H5 ID="colorgreen">FACT FILE</H5></li>
                    <li><a href="#">This is one item</a></li>
                    <li><a href="#">This is one item</a></li>
                    <li><a href="#">This is one item</a></li>
                    <li><a href="#">This is one item</a></li>
                    <li><a href="#">This is one item</a></li>
               </ul>
            </li>
        </ul>

JS

            $(document).ready(function(){
            var docked = 0;

            $("#dock li ul").height($(window).height());

            $("#dock .dock").click(function(){
                $(this).parent().parent().addClass("docked").removeClass("free");

                docked += 1;
                var dockH = ($(window).height()) / docked
                var dockT = 0;               

                $("#dock li ul.docked").each(function(){
                $(this).height(dockH).css("top", dockT + "px");
                dockT += dockH;
                });
                $(this).parent().find(".undock").show();
                $(this).hide();

                if (docked > 0)
                $("#content").css("margin-left","250px");
                else
                $("#content").css("margin-left", "60px");
            });

            $("#dock .undock").click(function(){
                $(this).parent().parent().addClass("free").removeClass("docked")
                .animate({right:"-80px"}, 200).height($(window).height()).css("top", "0px");

                docked = docked - 1;
                var dockH = ($(window).height()) / docked
                var dockT = 0;               

                $("#dock li ul.docked").each(function(){
                $(this).height(dockH).css("top", dockT + "px");
                dockT += dockH;
                });
                $(this).parent().find(".dock").show();
                $(this).hide();

                if (docked > 0)
                $("#content").css("margin-left", "40px");
                else
                $("#content").css("margin-left", "80px");
            });

            $("#dock li").hover(function(){
                $(this).find("ul").animate({right:"40px"}, 200);
                }, function(){
                    $(this).find("ul.free").animate({right:"-80px"}, 200);
                });
            }); 

CSS

                 #dock{margin:0px; padding:0px; list-style:none; position:fixed; top:0px; height:100%; 
          z-index:9999; background-color:#f0f0f0; right:0px;}
    #dock > li {width:40px; height:8.3%; margin: 0 0 1px 0; background-color:#dcdcdc;
                 background-repeat:no-repeat; background-position:left center;}

    #dock #files {background-image:url(../images/menu.png);}
    #dock #tools {background-image:url(../images/menu.png);}

    /*#dock > li:hover {background-position:-40px 0px;}*/

    /* panels */
    #dock ul li {padding:5px; border: solid 1px #F1F1F1;}


    #dock > li:hover ul {display:block;}
    #dock > li ul {position:absolute; top:0px; right: 40px;  z-index:-1;width:180px; display:none;
                   background-color:#F1F1F1; border:solid 1px #969696; padding:0px; margin:0px; list-style:none;}
    #dock > li ul.docked { display:block;z-index:-2;}

    .dock,.undock{float:left;}
   .undock {display:none;}
    #sidepanelcontent {margin: 10px 0 0 60px;}

    #colorgreen {color:green;}

View JsFiddle Example

Answer №1

Would you like something similar to this example http://jsfiddle.net/W7sNp/1/

I have incorporated a click event and made some adjustments by transferring code from hover. Additionally, I made slight modifications to the CSS

The tabs are hidden until you click on the boxes

Update:

I've included a quick demo http://jsfiddle.net/W7sNp/3/ which completely disregards hover effects

HTML remains unchanged

CSS

  1. Removed :hover selector
  2. Modified
    #dock > li ul {position:absolute; top:0px; right: -40px; z-index:-1;width:0px; display:block;
    It is now visible but shifted out of view with a width of 0px

Script

All functions are now triggered by $("#dock li").click(), determining whether to open or close a tab based on its width

$(document).ready(function(){
var docked = 0;

$("#dock li ul").height($(window).height());

$("#dock li").click(function(){
var test = $(this).find("ul").css('width');
if (test=="0px"){
$(this).find("ul").addClass("docked").removeClass("free").animate({right:"40px",width:'180px'}, 200);
docked += 1;
}else{
$(this).find("ul").addClass("free").removeClass("docked").animate({right:"-40px",width:'0px'}, 200);
docked = docked - 1;
}
console.log(docked);

var dockH = ($(window).height()) / docked;
var dockT = 0;

$("#dock li ul.docked").each(function(){
$(this).height(dockH).css("top", dockT + "px");
dockT += dockH;
});

if (docked > 0)
$("#content").css("margin-left","250px");
else
$("#content").css("margin-left", "60px");
});
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the importance of using a polyfill in Babel instead of automatically transpiling certain methods?

Recently, I have been diving into a course that delves into the use of babel in JavaScript. It was explained to me that babel, with the preset "env," is able to transpile newer versions of ES into ES5. However, I found myself facing a situation where the a ...

Real-time data and dynamic checkbox functionality in AngularJS

I am working on an onclick function that involves data stored in objects. $scope.messages = [ {"id": "1"}, {"id": "2"}, {"id": "3"}, {"id": "4"}, ]; $scope.selection = { ids: {} }; $scope.sendMe = function(message) { //send the data with `id` and ...

Alteration in relational shift of division placement

My webpage is divided into three sections with the following proportions: 15% - 65% - 20% In the right section, there is a div with the ID alchemy. I want to set the height of this div using <div style="height:150px;">. However, when I set the heig ...

Tips for incorporating a download button into a video player using Plyr JS

I'm using Plyr JS and I am trying to add a download option for each video. Here is what I've done so far to make the download option work: Even though I have included: controlsList="nodownload" <video controls crossorigin playsinline contro ...

Identify the active slide and execute a corresponding function in ANgularJS

I am currently using a slider jQuery plugin to rotate images on a timer. The plugin is minified so I am unable to read the source code. My goal is to have Angular automatically update a model every time the slide changes, which will then update content o ...

Trouble with escaping characters in Javascript?

My code looks like this: `message.channel.send( const Discord = require('discord.js'); const client = new Discord.Client(); const token = 'your bot token here'; client.on('ready', () => { console.log('I am ready!& ...

Put dashes in the middle of each MongoDB post title

In my express app, users can create and view posts. Currently, I search for posts by their title. However, I am encountering an issue when the post title contains spaces. The search function works perfectly for titles without spaces, but it gives an error ...

How can DataTables (JQuery) filter multiple columns using a text box with data stored in an array?

I've been attempting to create a multi-column filter similar to what's shown on this page () using an array containing all the data (referred to as 'my_array_data'). However, I'm facing issues with displaying those filter text boxe ...

Prevent Bootstrap 5 input fields from automatically adjusting to the height of a CSS grid cell

Below is some Bootstrap 5 markup that I need help with. The first example is incorrect. I don't want the Bootstrap input to be the same height as the grid cell. The second example is right, but I want to achieve the same result without using a wrapp ...

Displaying or concealing HTML elements using AngularJS while a modal is open

Looking for a way to display a loading spinner icon on my page when a user triggers a button that opens a modal, and then have the spinner disappear once the modal is open and its content has loaded. Currently, I've managed to make the spinner show up ...

The values in my JavaScript don't correspond to the values in my CSS

Is it possible to retrieve the display value (display:none; or display:block;) of a div with the ID "navmenu" using JavaScript? I have encountered an issue where I can successfully read the style values when they are set within the same HTML file, but not ...

Using Javascript Reduce to Manipulate Objects

Here is the data I am working with: let info = [ {id: 1, name: "John Doe", type: "A", amount: 100}, {id: 2, name: "Jane Smith", type: "B", amount: 150}, {id: 3, name: "Alice Johnson" ...

Sorry, the provided text is already unique as it is an error message

I'm currently using the react-highlight-words package to highlight text inputted into a textbox After checking out the react-highlight-words documentation, I noticed that they are using searchWords as an array. https://www.npmjs.com/package/react-high ...

div containing various images of varying sizes

I am working with a layout that requires 4 images to be displayed together within a container. One image should be larger and positioned on the left, while the other three should be uniform in size and placed next to it on the right. Despite my efforts t ...

Testing Async operations in the browser with Mocha and Chai

I'm having trouble running async tests with mocha. Below is the snippet of my code: describe('Brightcove Wrapper',function(){ describe("#init()", function() { it("Should inject the brightcove javascript", function(callback){ ...

Guide to creating several AJAX requests using a for loop

I'm currently experimenting with the Star Wars API (SWAPI) and attempting to display the names of all the planets. However, the planet information is spread across multiple pages. How can I go about making several AJAX requests in order to retrieve an ...

Error importing React Icons with the specific icon FiMoreHorizontal

Currently following a guide to create a Twitter-like application and I need to add the following imports: import { FiMoreHorizontal } from 'react-icons/fi' 2.3K (gzipped: 1K) import { VscTwitter } from 'react-icons/vsc' 3.1K (gzipped: ...

Vuetify's Handy Helper Classes

Hey everyone, I'm working on a vuetify project and I need to convert inline styles to utility classes (if possible) font-size: 24px; font-weight :600 I checked the documentation and noticed that it only provides options for setting size and weight wi ...

Looking to retrieve the name of an article by its ID using asynchronous methods in Symfony 2.8. How can this be accomplished?

Hello everyone, I'm currently seeking a solution to retrieve the name of a product when a user enters the product ID into an input field. Here's what I have tried with JavaScript: function showHint(str) { if (str.length == 13) { $.ajax({ ...

Is there a way to update the Angular component tag after it has been rendered?

Imagine we have a component in Angular with the selector "grid". @Component({ selector: 'grid', template: '<div>This is a grid.</div>', styleUrls: ['./grid.component.scss'] }) Now, when we include this gri ...