1

I would like to change the CSS files on the fly (dynamically). I am developing in MVC 4 using Razor views. At the moment they are pulled from the web.config...

My bundle registration

bundles.Add(New StyleBundle("~/Content/themes/" + Domain.GetTheme + "/css").Include( "~/Content/themes/" + Domain.GetTheme + "/Main.css", "~/Content/themes/" + Domain.GetTheme + "/Content.css")) 

Razor View

@Styles.Render("~/Content/themes/" + Domain.GetTheme + "/css") 

Code in GetTheme property

Public Shared ReadOnly Property GetTheme As String Get Return ConfigurationManager.AppSettings("Theme") End Get End Property 

I'm not sure if this is the best way, but it works.

Research so far...

But now I want to change the theme on the fly. My initial idea was to access a querystring parameter. So if it contained ?Theme=Green then the CSS files would pick up the green version. The querystring value would be stored in session state so that the CSS would continue to use green until changed again via the querystring.

I started off by creating an attibute that I could apply to my controller...

Attribute

Public Class LoadThemeAttribute Inherits ActionFilterAttribute Public Overrides Sub OnActionExecuted(filterContext As ActionExecutedContext) MyBase.OnActionExecuted(filterContext) If HttpContext.Current.Request.QueryString("Theme") IsNot Nothing Then HttpContext.Current.Session("Theme") = HttpContext.Current.Request.QueryString("Theme") End If End Sub End Class 

Controller

<LoadTheme> Public Class CompanyController Inherits System.Web.Mvc.Controller ... End Class 

Then in my _Layout.vbhtml razor view I override the CSS files as follows:-

@If Session("Theme") IsNot Nothing Then @<link href="/Content/themes/@Session("Theme")/Main.css" rel="stylesheet"/> @<link href="/Content/themes/@Session("Theme")/Content.css" rel="stylesheet"/> Else @Styles.Render("~/Content/themes/" + Domain.GetTheme + "/css") End If 

I couldn't use the Render statement, I am assuming this is because this is called once when the project loads and cannot be called again. I certainly could not get it to work.

So my question is this:- Everything seems to work, but I just want to know if this is a good approach - is it a good MVC way to change the CSS files?

1 Answer 1

1

So I've pretty much had the same issue you had. A quick cure I did was remove my theme/css from the bundle and put it separate on my layout.vbhtml /master page. I gave the tag and id property, referenced it an a javascript function and changed the href to the different css I wanted loaded. If this is not enough information let me know, ill detail more.

Updated example from my program. layout.vbhtml header

<head> <meta charset="utf-8" /> <title>Amtrust - Print Metrics @*@ViewData("Title")*@</title> <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" /> <meta name="viewport" content="width=device-width" /> <link id="theme" href="~/Content/themes/jquery-blue-theme/css/start/jquery-ui- 1.10.3.custom.css" rel="stylesheet" /> @Styles.Render("~/Content/_Layout") @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/jqueryui") @Scripts.Render("~/Scripts/_Layout") </head> site.master.js -> js file I use to keep the theme consistent on all pages. var domainName; $(document).ready(function () { //loading = document.getElementById('loading'); //pagediv = document.getElementById('page'); //alarum = document.getElementById('alarum'); //alarum = $('#alarum'); jQuery's .append() method $("#menu").menu(); hideLoading(); //Apply UI skins to controls $(function () { $('#printinvButton').button(); $('#docsearchButton').button(); $('#policysearchButton').button(); $('#metricsButton').button(); $('#themeButton').button(); }); //setInterval(function () { bannerAlert() }, 4000); if (sessionStorage.getItem('theme') != null) { $('#theme').attr('href', sessionStorage.getItem('theme')); } domainName = location.protocol + '//' + location.host; }); var counter = 0; function switchTheme() { var theme; var imageRoot = document.body.getAttribute('data-root'); if (counter == 0) { theme = domainName + '/PrintRoomMetrics/Content/themes/jquery-blackgrey- theme/css/blackGrey/jquery-ui-1.10.3.custom.min.css'; $('#theme').attr('href', theme); counter++; } else if (counter == 1) { theme = domainName + '/PrintRoomMetrics/Content/themes/jquery-chrome-theme /css/overcast/jquery-ui-1.10.3.custom.min.css'; $('#theme').attr('href', theme); counter++; } else if (counter == 2) { theme = domainName + '/PrintRoomMetrics/Content/themes/jquery-blue-theme/css/start/jquery-ui- 1.10.3.custom.min.css'; $('#theme').attr('href', theme); counter++; } if (counter == 3) { counter = 0; } sessionStorage.setItem('theme', theme);// store data for session } 

hope you can figure out what I did. Ignore my app code and only pay attention to what you need.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, think I get what you did. How did you ensure the correct CSS files were called on subsequent calls to pages throughout your website?
Let me know if this helps. Ignore what doesn't apply, as I took this out of my app code. Top part is from my vbhtml and other is a javascript file that is included into it. I use session variables to store what theme is current.
@cw_dev this method was something i did when i was a novice. There are way better ways to do this now. If you want to go this way, then that theme variable is what im using to tell which theme to run. See where it says sessionStorage.getItem and setItem, that is where im saving the data and retrieving it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.