0

I am trying to switch between a dark & light theme I have created on my MVC application.

My _Layout.cshtml page loads the default theme I have created below

<link id="theme" rel="stylesheet" href="~/lib/bootstrap/dist/css/Original.css">

I have created the below buttons to switch between the themes below

<button id="light">Light</button><br />
<button id="dark">Dark</button>

My two other bootstrap themes are located in lib > bootstrap> dist > css >

I have the below js in my botstrap.js file

$('#dark').click(function () {
    $('link[href="~/lib/bootstrap/dist/css/Dark.css"]').attr('href', '~/lib/bootstrap/dist/css/Dark.css');
});
$('#light').click(function () {
    $('link[href="~/lib/bootstrap/dist/css/Dark.css"]').attr('href', '~/lib/bootstrap/dist/css/Light.css');
});

Not sure if I am making some obvious error but any help on this is appreciated.

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
joshh
  • 15
  • 2
  • 7
  • What is the issue you are having currently? – palaѕн Apr 06 '20 at 17:30
  • Note that buttons, by default, submit any forms they are within. – Heretic Monkey Apr 06 '20 at 17:32
  • Currently there are no changes to the page when the buttons are pressed. I was wondering if there is an issue with the href i have queried or withing the js itself – joshh Apr 06 '20 at 17:38
  • Isn't it possible that your dom query for the link-element doesn't return any elements? It looks like you're looking for hrefs literallly starting with `~/`. In your razor page it's being transformed to the path of your content root, but when querying it won't – Pieterjan Apr 06 '20 at 17:43
  • Did you try this one? [Replacing css file](https://stackoverflow.com/a/19844696/7894673) – Fateme Mirjalili Apr 06 '20 at 18:34

3 Answers3

1

Here it is in VanillaJS, check also if the href on the link tag resolves to CSS File correctly.

const darkBtn = document.querySelector('#dark');
const lightBtn = document.querySelector('#light');
const linkTag = document.querySelector('#theme');

darkBtn.addEventListener('click', () => {
  linkTag.setAttribute('href', '~/lib/bootstrap/dist/css/Dark.css')
});

lightBtn.addEventListener('click', () => {
  linkTag.setAttribute('href', '~/lib/bootstrap/dist/css/Light.css')
});

Lucjan Grzesik
  • 739
  • 5
  • 17
  • Hi, Thanks for your answer. Unfortunately this did not work for me. Within my _Layout page i have and the js i have placed in the bootstrap.js file. Not sure exactly why it is not working. If you can see any other issues it would be appreciated. – joshh Apr 06 '20 at 18:17
  • Try to add this code in the footer in a script tag. When you are clicking when you inspect the script changes anything? – Lucjan Grzesik Apr 06 '20 at 18:18
  • Hi Lucjan, when running this with the snippet you have provided in the footer section. This seems to remove any sort of bootstrap associated with the application, however something has changed at least now when clicking the button. – joshh Apr 06 '20 at 18:26
  • 1
    You must have attached at all times the bootstrap CSS file, if you want themes, just write the CSS files with the selectors to overwrite the original CSS values. You can also have attached the files with a dark and light theme at all times and just add a class to the body depending on your selectors. – Lucjan Grzesik Apr 06 '20 at 18:34
0

You probably need following code:

$('#dark').click(function () {
    $('#theme').attr('href', '~/lib/bootstrap/dist/css/Dark.css');
});
$('#light').click(function () {
    $('#theme').attr('href', '~/lib/bootstrap/dist/css/Light.css');
});

Your code is looking for a link-element where the href literally starts with ~/. In your razor page the href starts with this string. But ASP.NET replaces this with the path for the content-root, so for the browser, the href does not start with this string.

enter image description here

joshh
  • 15
  • 2
  • 7
Pieterjan
  • 2,738
  • 4
  • 28
  • 55
  • Hi, Thnaks for your answer. I tried your snippet and it was the same, nothing happened when i pressed the buttons I am not using razor pages on my MVC application. I am using cshtml pages. For my _Layout page i am not using any server side code so razor is not needed. From my code can you see any issues with the js which i have placed on my bootstrap.js file. Or can you see any other issues which may be causing this? – joshh Apr 06 '20 at 18:03
  • I've created a basic example https://github.com/PieterjanDeClippel/DynamicTheme. Just open cmd -> git clone https://github.com/PieterjanDeClippel/DynamicTheme and open the project – Pieterjan Apr 06 '20 at 20:12
  • Note that I'm not modifying the original bootstrap.css file. I've created a new css-file where I overload the colors – Pieterjan Apr 06 '20 at 20:15
  • Hi, thanks for the response. Have you ran the mvc app you have created? It seems the Application wont change the theme within that. Same issue i have been having – joshh Apr 06 '20 at 20:33
  • On my PC it works fine. If you open developer tools (F12) do you get an exception (in pink) in the console? – Pieterjan Apr 06 '20 at 20:43
  • Yes i get a few. It wont seem to dynamically switch the css. Is the file in Github the latest version compared to the one you are currently using? I appreciate this help. – joshh Apr 06 '20 at 21:13
  • That's right, everything is commited to the repository. I retried the cloning and running the application and I get it working. Can you share an image/text of the errors you're getting in the webbrowser console (modify your question with an EDIT statement). Do you get these errors when loading the page or when clicking the button? – Pieterjan Apr 06 '20 at 22:44
  • Can you post a screenshot of the error messages you're getting in de webbrowser console (F12) – Pieterjan Apr 07 '20 at 06:20
  • Hi, i have updated your answer with the console error message – joshh Apr 07 '20 at 08:10
  • Are you sure that the UseStaticFiles() middleware is still present in the middleware pipeline (Startup.Configure)? – Pieterjan Apr 08 '20 at 13:54
0

I downloaded Pieterjan solution and it began to work after I added event.preventDefault() like that:

$(document).ready(function () {
            $('#dark').click(function () {
                event.preventDefault();
                $('#dynamicCss').attr('href', '/css/site-dark.css');
            });
            $('#light').click(function () {
                event.preventDefault();
                $('#dynamicCss').attr('href', '/css/site-light.css');
            });
        });

But website displays light theme again after refreshing the page.