0

I had code in my Rails application that successfully closed a toggled sidebar when clicking on X. I made other changes that somehow stopped my code from working. When I hover over the x it highlights as the other links but when I click it the window remains open and /# is appended at the end of the current link. When I click the other links in the sidebar they display the correct view and the sidebar closes. I changed something that I cannot find.

My sidebar where the X is defined:

<ul class="sidebar-nav">
  <li class="sidebar-close"><%= link_to "#" do %><i class="fa fa-times"></i><% end %></li>
  .....
</ul>

CSS for sidebar-close:

.sidebar-nav > .sidebar-close { height: 50px; font-size: 150%; line-height: 200%; color: $sideBarClose; text-align: right; padding-right: 10px; }
.sidebar-nav > .sidebar-close a { color: $sideBarLink; }
.sidebar-nav > .sidebar-close a:hover { color: $white; background: none; }

My menu button:

<div class="menu-button"><%= link_to "#menu-toggle", class: "btn btn-default btn-lg", id: "menu-toggle" do %><i class="fa fa-bars"></i><%= " #{t :menu}" %><% end %></div>

CSS for the menu button:

.menu-button { padding-top: 10px; position: absolute; left: 15px; top: 0px; z-index: 1; }

Script (includes code to close the window if you click outside of the sidebar:

$("body, html").not('#menu-toggle').click(function(e) {
  console.log(e.target);
  if($('#wrapper').hasClass("toggled") && !$(e.target).is('#menu-toggle, #sidebar-wrapper, #sidebar-wrapper *'))
  {
  //alert('asd');
  $("#menu-toggle").trigger("click");
  }   
});
$("#menu-toggle").click(function(e) {
  e.preventDefault();
  $("#wrapper").toggleClass("toggled");
});

I will mention that I did not have any special Javascript for this to work. I'm just not seeing what I changed where clicking X no longer closes the window.

Update: With help from @Justastudent I was able to create a JSFiddle. When you click the Menu button it toggles just fine. If you have the sidebar open and click outside of the sidebar the sidebar will close. If you click the X on the top right of the sidebar it does not work. It seems to get stuck. When the X is clicked on my system the page scrolls down and I cannot scroll it back to the top. I have to close the tab and access the link in new tab to get the top of the fiddle page to display.

https://fiddle.jshell.net/lightbe/x0n151rt/5/

  • Can you maybe create a [mcve] so that it is easier to reproduce the problem? – Just a student May 04 '17 at 06:31
  • I don't know how more minimal I can get with this. Please stop the madness. I'm not going to have some hot shot post something just to show off. – Pamela Cook - LightBe Corp May 04 '17 at 12:38
  • If I put all of my code I will be told to streamline the code. It's obvious Just a student did nothing but bark. I already streamlined the code. I can reproduce it just fine. Constructive criticism I will accept. Not childish rubbish. – Pamela Cook - LightBe Corp May 04 '17 at 12:44
  • Let's keep it civil and professional, please. I linked to the help page, but should have maybe stated this more clearly: I specifically meant that it would be nice if your code was easily *verifiable*. In particular, it would be nice to have a small HTML/CSS/JS [snippet](https://stackoverflow.blog/2014/09/16/introducing-runnable-javascript-css-and-html-code-snippets/) or fiddle that demonstrates the issue. Right now, a lot of HTML is missing, or implicitly given as Ruby on Rails directives. I am only trying to be constructive. – Just a student May 04 '17 at 12:57
  • I took the effort to create a [JSFiddle](https://fiddle.jshell.net/x0n151rt/). I replaced your Ruby on Rails directives with something I think makes sense, filled in your SCSS variables with something I think makes sense, added Bootstrap and Font Awesome and clicked *Tidy*. What is the problem I should observe? Again, I am trying to be constructive and solve your problem *with* you. All I am saying is that you will get more help when you make it easier for others to help you. – Just a student May 04 '17 at 14:13
  • There have been people on this forum that have berated me when I sincerely asked for help. Some said it was not enough, others said it was too much. Thanks for the clarification and the JSFiddle. I'm not good at using JSFiddle and have limited JavaScript knowledge. I will take the one you provided and attempt to modify it to better reflect the problem. – Pamela Cook - LightBe Corp May 04 '17 at 16:23
  • We've all been there, sorry you had to experience that, but please assume the best intentions :-) Almost everyone here is trying to help and they are all volunteers, so let's be nice. That's what I try to be, at least. Let me know when you have something! – Just a student May 04 '17 at 17:04
  • @Justastudent when I posted my original comment I had one down vote. I thought you did that. Hence my harsh responses. I now have two down votes and I don't know why. I tried to copy the code that you had and create my own fiddle in my account. The Font Awesome font don't work on mine like yours. I'll look at this later. I have other things I need to get done. Thanks for trying to help me. – Pamela Cook - LightBe Corp May 04 '17 at 18:06
  • You should be able to edit my fiddle and click save to save it under your account. What you probably did not copy are the external resources in the left pane. – Just a student May 04 '17 at 19:04
  • It took a while @Justastudent but I have a fiddle. I updated my question with it explaining the error in detail. Thanks for your help. I guess I will be a JSFiddle expert after this. – Pamela Cook - LightBe Corp May 04 '17 at 22:25

2 Answers2

0

After looking at this off and on I decided to add id toggleback to my statement as follows.

<li class="sidebar-close" id="toggleback"><%= link_to "#" do %><i class="fa fa-times"></i><% end %></li>

I then duplicated the javascript for #menu-toggle for #toggleback as follows to test this.

$("#toggleback").click(function(e) {
  e.preventDefault();
  $("#wrapper").toggleClass("toggled");
});

Now when I click the x the sidebar toggles closed.

Here's my final JavaScript code.

$("#menu-toggle, #toggleback").click(function(e) {
  e.preventDefault();
  $("#wrapper").toggleClass("toggled");
});

I guess what I thought was working was a fluke.

  • But this gets rid of the behavior of closing the sidebar when clicking outside of it, no? – Just a student May 06 '17 at 14:46
  • Yes my code allows the sidebar to close when clicking outside of the sidebar. I also wanted to add X at the top to close it if people may not know about clicking outside the box to close the sidebar. – Pamela Cook - LightBe Corp May 07 '17 at 23:51
  • Ah, I thought that you had replaced all of your JavaScript with the last snippet in your answer. In [my answer](//stackoverflow.com/a/43821775/962603) I tried to explain why the code was not working and am giving an alternative way to fix it. The solution in this answer obviously works as well :-) – Just a student May 08 '17 at 07:16
  • @Justastudent the snippet I posted was the bottom part of the JavaScript. The top part remains where you can click on the outside of the sidebar and close it. Thanks so much for your input which gave me the starting point for a solution. – Pamela Cook - LightBe Corp May 08 '17 at 13:52
  • Yes, I see now. No worries, glad it helped! Feel free to mark your own answer (or mine) as accepted :-) – Just a student May 08 '17 at 13:58
0

There are a couple of issues with your code, that prevent it from working the way you want.

  1. This line likely does not do what you think it does.

    $("body, html").not('#menu-toggle').click(function(e) { /* ... */
    

    It will attach a click handler to both the html and body elements, filtering those two to ones that do not have id="menu-toggle"'. Neither has, because there is only a div with that ID. Because html is the parent of body and click events bubble, this click handler is triggered twice for every click event.

    It is best to check for events that have not been handled anywhere else on the global window:

    $(window).click(function(e) { /* ... */
    
  2. Checking event target is flawed. You check if a click does not target the sidebar as follows:

    !$(e.target).is('#menu-toggle, #sidebar-wrapper, #sidebar-wrapper *')
    

    However, since the close button of the sidebar is in the sidebar, this check will not trigger for clicks on that button. Therefore, the button won't close the sidebar.

The following JavaScript appears to work the way you intend it to.

// toggle menu on clicking anywhere outside of it
$(window).click(function(e) {
  var $t = $(e.target);
  if ($('#wrapper').hasClass('toggled') && !$t.is('#menu-toggle') &&
      ($t.closest('#sidebar-wrapper').size() === 0 ||
       $t.closest('.sidebar-close').size() === 1)) {
    $('#menu-toggle').trigger('click');
  }
});
// toggle menu on button click
$('#menu-toggle').click(function(e) {
  e.preventDefault();
  $('#wrapper').toggleClass('toggled');
});

This rewords the check for was a click in the sidebar? using jQuery's closest function. It also adds a separate check for clicks on the close button, enabling that one.

Just a student
  • 10,560
  • 2
  • 41
  • 69