2

I want to make a collapisible side menu with JS and CSS for my app. Here is my code:

In views/pages/home.html.erb I have:

<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>

<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application','data-turbolinks-track': 'reload' %>

<div class = "head">
    
    <div class = "navbar">
        <div id="mySidepanel" class="sidepanel">
            <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a>
            <a href="#">About</a>
            <a href="#">Services</a>
            <a href="#">Clients</a>
            <a href="#">Contact</a>
        </div>
        <button class="openbtn" onclick="openNav()">&#9776; Toggle Sidepanel</button>

        <h1 class = "titles">
            <%if current_user%>
                ¡Bienvenido <%=current_user.first_name%>!
            <%else%>
                Home
            <%end%>
        </h1>

        <h3 class = "secondary-contact">25 de mayo 1160 Puiggari, Entre Rios, Argentina</h3>
        <h3 class = "secondary-contact">TEL. 0343 15-467-5058</h3>
    </div>

My stylesheets/application.css

.sidepanel {
    height: 250px; /* Specify a height */
    width: 0; /* 0 width - change this with JavaScript */
    position: fixed; /* Stay in place */
    z-index: 1; /* Stay on top */
    top: 0;
    left: 0;
    background-color: #111; /* Black*/
    overflow-x: hidden; /* Disable horizontal scroll */
    padding-top: 60px; /* Place content 60px from the top */
    transition: 0.5s; /* 0.5 second transition effect to slide in the sidepanel */
  }
  
  /* The sidepanel links */
  .sidepanel a {
    padding: 8px 8px 8px 32px;
    text-decoration: none;
    font-size: 25px;
    color: #818181;
    display: block;
    transition: 0.3s;
  }
  
  /* When you mouse over the navigation links, change their color */
  .sidepanel a:hover {
    color: #f1f1f1;
  }
  
  /* Position and style the close button (top right corner) */
  .sidepanel .closebtn {
    position: absolute;
    top: 0;
    right: 25px;
    font-size: 36px;
    margin-left: 50px;
  }
  
  /* Style the button that is used to open the sidepanel */
  .openbtn {
    font-size: 20px;
    cursor: pointer;
    background-color: #111;
    color: white;
    padding: 10px 15px;
    border: none;
  }
  
  .openbtn:hover {
    background-color: #444;
  }

In javascript/packs/application.js I added:

function openNav() {
    document.getElementById("x").style.width = "15%";
  }
  
function closeNav() {
    document.getElementById("mySidepanel").style.width = "0";
  }

The problem is that when I click the button nothing happens. I'm very new with JavaScript and I can´t find my error.

3
  • I'd try to console.log in those functions to see if they are called. Do u know how to check the console in your browser? Commented Apr 22, 2021 at 20:51
  • I could make it work but only if i put the JS code in my html file between <script> </script>. Obviously I prefer to have my JS code in my application.js, because of organization. No, I don´t know how to check the console, I´d appreciate if you tell me how, thanks! Commented Apr 22, 2021 at 21:06
  • 1
    Depends on your browser, but usually right click -> inspect and then there's a console tab developer.chrome.com/docs/devtools/console . See if you see any javascript errors in the console when you click on your links. Btw where is the element with id = "x"? document.getElementById("x") Commented Apr 22, 2021 at 21:13

2 Answers 2

3

You can not access directly application.js or other js file functions from dom. Because rails use webpack for your codes. You can use events like this;

let openButton = document.querySelectorAll('button.openbtn')
openButton.addEventListener("click", function(event) {
  document.getElementById("x").style.width = "15%";
})

let closeButton = document.querySelectorAll('button.closebtn')
closeButton.addEventListener("click", function(event) {
  document.getElementById("mySidepanel").style.width = "0";
})
Sign up to request clarification or add additional context in comments.

Comments

2

Muhammet's answer is right:

  • When using Webpacker, all the functions are private and not visible to the DOM
  • Either use Muhammet's solution of binding events in Webpack (preferred), or:
  • export the functions to the global scope:
window.openNav = function() {
 document.getElementById("x").style.width = "15%";
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.