0

In a dockerized rail 6.1.7.2 application, I'm not able to have my custom javascript file working.
Its name corresponds to the view file where I want it to be loaded.

I can see that the JS asset is successfully transmitted in the network panel of the web browser when I hit this page, and when I open it, I can also see that my custom JS snippet is actually present at the very bottom of that .js file, underline in green in this screenshot:

enter image description here

But whatever I do with the checkbox on the web page, the div is always displayed and never disappears.

And if I test those snippets on JSFiddle, it works as expected: box ticked: the div is displayed, unticked: the div is hidden.

# cat app/assets/javascripts/custom.js

// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.
let checkbox = document.getElementById('show');
let box = document.getElementById('target');
box.style.visibility = 'hidden';

checkbox.addEventListener('click', function handleClick() {
  if (checkbox.checked) {
    box.style.visibility = 'visible';
  } else {
    box.style.visibility = 'hidden';
  }
});
# cat app/views/custom/index.html.erb

<h2 class="title">Title</h2>

<table>
  <tr>
    <td>
      <input type="checkbox" id="show"/>
    </td>
    <td>
      <p>Tick me to display the target div!</p>
    </td>
  </tr>
</table>


<div id="target">
  <h4 class="title">Foo</h4>
</div>

What could be wrong and how could I fix this strange behavior?
I cannot get it to work both in development and production.
There is no particular error or warning in the app/log/{production|development}.log files.

Edit

Adding <%= javascript_include_tag "custom.js", defer: true %> to the HTML template doesn't work either. But the custom JS code is now loaded twice in the DOM:

enter image description here

With the corresponding behavior of the web page (without | with the checkbox ticked):

enter image description here

swiss_knight
  • 5,787
  • 8
  • 50
  • 92
  • Could it be the loading order? https://stackoverflow.com/questions/8996852/load-and-execute-order-of-scripts You can try placing your script before the ending body tag `

    ` or just add a `defer` prop in the script tag

    – Joshua Mar 01 '23 at 02:40

1 Answers1

1

Since you create the checkbox variable using getElementId, you have to make sure the html finished render before the browser load the javascript.

in rails you can do this by adding 'defer: true' properties to the javascript include tag like this

<%= javascript_include_tag "custom.js", defer: true %>

like what shown in this thread Add defer attribute to javascript_include_tag Rails

Hirota
  • 11
  • 2
  • Thank you for your answer! With this proposed solution, the code is now loaded twice: once just as before at the very end of a huge JS file in the head section of the DOM. And now (this is new); also in a div of the body part of the DOM, as the custom code itself in a separate asset file as follow: ``. But the checkbox still has no effect when (un)ticked. Unfortunately. – swiss_knight Mar 01 '23 at 20:40
  • A strange thing I noticed is that the `script` tag doesn't show a `type=text/javascript` property. – swiss_knight Mar 01 '23 at 20:42
  • The defer doesn't seems to work apparently. The solution i could propose is maybe you can put your javascript code inside a "DomContentLoaded" event like this `document.addEventListener("DOMContentLoaded", function(){` `"put your code here"` `});` to make sure it get executed after the DOM loaded – Hirota Mar 02 '23 at 08:21