0

Trying various answers on "toggle theme with button", I have code, but it is not working

  • from bootstrap 4, bootswatch themes 'flatly' and 'darkly' have been selected, since I want to offer user of my web page option to select his/her favorite theme
  • I have put complete 'flatly.min.css' and 'darkly.min.css' into my static files folder (django project), and renamed them to 'light.css' and 'dark.css'
  • I tried various answers from stack exchange, and currently I use this one: create switch for changing theme intead of browser page style html

My base.html:

    <head>
      <!-- Required meta tags -->
      <meta charset="utf-8">
      <meta name="viewport"
            content="width=device-width, initial-scale=1, shrink-to-fit=no">
    ...

      {% include 'base/css.html' %}

      {% block base_head %}
      {% endblock %}
    </head>

    <body>
    ...
      {% include 'base/js.html' %}

      {% block javascript %}
      {% endblock %}
    </body>

My css.html:

    <!-- custom styling -->
    <link rel="stylesheet"
          href="{% static 'css/base.css' %}">
    <!-- light styling  -->
    <link rel="stylesheet alternate"
          id="theme"
          href="{% static 'css/light.css' %}">
    <!-- dark styling  -->
    <link rel="stylesheet alternate"
          id="theme"
          href="{% static 'css/dark.css' %}">

When I use only 'css/dark.css' (no 'css/light.css' link is declared), I get my page to render dark; if I change to 'css/light.css' (no 'css/dark.css' is declared), page renders light theme.

My js.html:

   ...

    <script src="{% static 'js/ecommerce.sales.js' %}"></script>
    <!-- toggle theme js -->
    <script src="{% static 'js/toggle_theme.js' %}"></script>

toggle_theme.js says:

    console.log('now what') // works at django runserver first run
    document.getElementById('toggle-theme').onClick = function() {
      console.log('js works'); // not working, js is not run on click
      if (document.getElementById('theme').href == "{% static 'css/dark.css' %}") {
        document.getElementById('theme').href = "{% static 'css/light.css' %}";
      } else {
        document.getElementById('theme').href = "{% static 'css/dark.css' %}";
      }
    }

The button I want to use in the navbar:

          <!-- todo: toggle theme -->
          <div class="nav-item mx-auto my-auto">
            <!-- href="#" -->
            <!-- <a class="nav-link dark-theme" -->
            <a class="nav-link"
               id="toggle-theme"
               title="toggle theme">
              <!-- id="toggle-theme" -->
              <i class="fas fa-lg fa-square"
                 aria-hidden="true">
                <!-- <script src="{% static 'js/toggle_theme.js' %}"></script> -->
              </i> </a>
          </div>

I did usual django stuff, 'python manage.py collectstatic' and Ctrl-F5 to refresh the development browser. What am I missing here?

Thank you for your help

EDIT: Although above link to "Toggle between two stylesheets" did solved my issue, it is not complete, because on refresh the theme is set back to default theme. My complete solution is (dark is my default theme):

if (document.getElementById('theme')) {
  if (localStorage) {
    // console.log('storidge');
    if (!localStorage.getItem('theme')) {
      localStorage.setItem('theme', 'dark');
    } else {
      if (localStorage.getItem('theme') == 'dark') {
        $("link[id='theme']").attr('href', '/static/css/dark.css');
      } else if (localStorage.getItem('theme') == 'light') {
        $("link[id='theme']").attr('href', '/static/css/light.css');
      }
    }
  }
}

$('#toggle-theme').click(function() {
  if ($("link[id='theme']").attr('href') == '/static/css/dark.css') {
    $("link[id='theme']").attr('href', '/static/css/light.css');
    localStorage.setItem('theme', 'light');
    console.log('changed to light.css');
  } else {
    $("link[id='theme']").attr('href', '/static/css/dark.css');
    localStorage.setItem('theme', 'dark');
    console.log('changed to dark.css');
  }
});

I do experience some page twinkling at refresh (F5), if light theme is set, but I will have to live with this for now. Dark theme works without twinkling.

Best regards,

Simon S love nia

chistabo
  • 13
  • 7

2 Answers2

0

Have you tried changing document.getElementById('toggle-theme').onClick = function() { to document.getElementById('toggle-theme').onclick = function() {?

No guarantee that's the only issue, but onclick should be all lower case, and if the initial click isn't being recognized that might be your problem.

pseudoku
  • 716
  • 4
  • 11
  • Yes, I have, lol, half an hour before I saw this answer. Thank you anyway. Now that button works, I am following the console.log output. Inspecting my web page, I get an error: GET http://localhost:8000/%7B%%20static%20'dark.css'%20%%7D net::ERR_ABORTED 404 (Not Found). It seems I toggle_theme.js is not finding my dark.css. Originally I had "{% static 'css/dark.css' %}", changed to "... 'dark.css'...", not working. I am checking now on SO how to call my (django) static files from javascript. – chistabo Apr 04 '19 at 17:56
  • Ah, sorry I didn't notice that earlier. Django templating has that issue in JS files, but if you move the click event to the HTML file in a – pseudoku Apr 04 '19 at 21:30
  • I did tried – chistabo Apr 04 '19 at 21:46
0

Ok, when I refresh my page, and view page source, I get:

<!-- light styling  -->
<link rel="stylesheet"
      id="theme"
      href="/static/css/light.css">
<!-- dark styling  -->
<link rel="stylesheet"
      id="theme"
      href="/static/css/dark.css">

If I inspect elements, I get the same code. Then I click my toggle-button, and view page source, the code stays the same, but when I inspect elements, I get:

<!-- light styling  -->
<link rel="stylesheet"
      id="theme"
      href="/static/css/dark.css">
<!-- dark styling  -->
<link rel="stylesheet"
      id="theme"
      href="/static/css/dark.css">

Both href are "/static/css/dark.css". So, the code works, but not as expected. This tells me this is not a code to use. Will continue my search.

chistabo
  • 13
  • 7
  • Hi! I am also trying to do such a feature of changing the theme. If I press f5 the site shows itself without CSS at all for 1 to 3 seconds and then gets the styles. However, I do not have the links for all my themes in the HTML. Only a link, and then the logic to toggle it. Did you solve your problem? btw, why do you have 2 stylesheet links with the same id? – Joel Carneiro Mar 24 '21 at 09:52