Introduction
I'm not very artistic so tend to stick with bootswatch to get bootstrap templates to help make my sites look a little more user friendly but I'd also like to have a quick way to see what the various themes might look like when applied to my site.
Using the Code
We'll look at the code a little further on as it is very simple and straightforward, however, I would rather encourage you to download the VS2013 web application and play around with it. The main code is all in the Site.Master
and I'll leave it to you to break it out as required: this is a sample application purely built to show a particular function. I would further encourage you to download the various themes to your local drive so as to make the changeover process a little sharper.
Note that this is an ASP.NET application and I selected all of the defaults when creating it. It serves no useful purpose other than to act as a showcase for the functionality being described.
I have also added a "Samples.aspx" page which is the page you see at Bootswatch and which gives examples of the various elements - each time you select a new theme, these will change to give you a quick view of the themed elements.
However, since the code is what's really of interest, let's go!
What I'm trying to achieve here is a way to be able to select any one of the themes from the selection of bootswatch templates and apply it directly to my site. I also want to see the effect of applying the default and inverse headers. On top of that, I'd like to persist those settings so I can load multiple pages and review the bootswatch samples. So, how can we do that? Plainly, there is always more than one way but this appears to be reasonably simple to implement.
First and foremost, you have to add a menu section to the navbar so as to be able to select the required theme/header. Place it directly under the final menu option (or wherever you deem suitable). It will look like:
<li class="dropdown">
<a href="#" class="dropdown-toggle"
data-toggle="dropdown">Themes <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="#" data-theme="default"
class="theme-link">Default</a></li>
<li><a href="#" data-theme="cerulean"
class="theme-link">Cerulean</a></li>
etc.
Under that, place a similar construct for the headers. This is simpler as:
<li class="dropdown">
<a href="#" class="dropdown-toggle"
data-toggle="dropdown">Headers <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="#" data-header="default"
class="header-link">Default</a></li>
<li><a href="#" data-header="inverse"
class="header-link">Inverse</a></li>
</ul>
</li>
and below that, place a label to hold the name of the currently selected theme:
<li><label class="navbar-text" id="theme-selection" /></li>
You may note that I have also created some CSS to style that label in the header of the file. Use or discard as you please.
Now we come to the magic part; the javascript/jquery that makes it all happen and to that end we have to create a construct that holds the names of the themes together with the url or location. This will look like:
var themes = {
"default": "//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css",
"cerulean": "//bootswatch.com/cerulean/bootstrap.min.css",
and so on.
There are also functions to help get or set a cookie, functions that handle the click events of the drop downs and code that ensures that the theme and header is shown when the page first loads should they have been previously persisted. If not, then the default theme will apply.
This is how the theme is set when you first load the page:
var setTheme = getCookie('setTheme');
var themeSheet = $('<link href="' +
themes[getCookie('setTheme')] + '" rel="stylesheet" />');
themeSheet.appendTo('head');
$('#theme-selection').text(setTheme);
and when the click event is kicked off:
$('.theme-link').click(function () {
var themeUrl = themes[$(this).attr('data-theme')];
setCookie('setTheme', $(this).attr('data-theme'));
themeSheet.attr('href', themeUrl);
$('#theme-selection').text($(this).attr('data-theme'));
});
Nothing else to add here; it works pretty well.
I would have set this as an article only it wasn't entirely my idea: I came across http://stackoverflow.com/questions/19192747/how-to-dynamically-change-themes-after-clicking-a-drop-down-menu-of-themes whilst browsing for inspiration and it fit the bill. I have, unashamedly, made good use of it as well as made some changes and additions to reach my goal.
My thanks to Kevin Pei, the author of that SO solution.
Enjoy.