How do I switch external CSS files?


Tags: javascript,jquery,css,ajax

Problem :

I've got a couple books that I'm reading on AJAX, but still quite new. All the tutorials and these books have the ubiquitous examples of: an auto-populating search bar and an asynchronous form validator. Those are both great, but not what I'm looking for. Specifically, I want to click a button and switch the external CSS file in my header include. Is this possible? Well... I know it's possible, but how do you do it?

PS: I have jQuery in this project, so if there is something built in from there, even better!

PPS: I'm realizing I have not included important information (don't shoot me!):

  1. The final goal of this will be to have a user settings section where the user can click a radio button and decide the color scheme they want to use for our app. So we will eventually have something like 8 different CSS styles to choose from. Not sure if this will alter the best method to achieve this.

  2. The user is logging into their account and changing their setting there. I want their changes to 'stick' until they decide to change the stylesheet again. I can do this manually in MySQL as we have a table called stylesheets with the various user stylesheets numbered... so in actuality, what I'm needing to do is change that MySQL value asynchronously so the CSS is immediately loaded.



Solution :

Stylesheet Switcher in jQuery.

In response to the 'newbie followup' comment, I will try to make it a little more instructional.

The page I was playing with to test on while writing can be found here.

Page Display

You're going to want to have your current stylesheet displayed in a <link> tag in the <head> of each of your pages. The <link> tag will need an id for reference later in JavaScript. Something like:

<?php 
  // Somewhere in the server side code, $current_stylesheet is read from the user's 
  // "preferences" - most likely from a database / session object
  $current_stylesheet = $user->stylesheet;
?>
<link href='<?php echo $current_stylesheet ?>' rel='stylesheet' type='text/css' id='stylelink' />

Changing the preference

Once you are displaying the users stylesheet, you need a way to change it. Create a <form> that will send a request to the server when the user changes their stylesheet:

<form method="GET" id="style_form" >
  <select name="stylesheet" id="styleswitch">
    <option value="css1.css">Black &amp; White</option>
    <option value="css2.css" selected="selected">Shades of Grey</option>
   </select>
   <input value='save' type='submit' />
</form>

Server Side

Now, without jQuery, submitting this form should GET (you could change it to POST if you like) stylesheet={new stylesheet} on the current page. So somewhere in your bootstrap / sitewide include file, you do a check for it, a php sample:

$styles = array(
  'css1.css' => 'Black &amp; White',
  'css2.css' => 'Shades of Grey',
);

if (!empty($_GET["sytlesheet"]) {
  // VALIDATE IT IS A VALID STYLESHEET - VERY IMPORTANT
  // $styles is the array of styles:
  if (array_key_exists($_GET["stylesheet"], $styles)) {
    $user->stylesheet = $_GET["stylesheet"];
    $user->save();
  }
}

Live Preview

At this point, you have a functioning styleswitcher for the lame people without javascript. Now you can add some jQuery to make this all happen a little more elegantly. You'll want to use the jQuery Form Plugin to make a nice ajaxForm() function, that will handle submitting the form. Add the jQuery and jQuery Form library to the page:

<script type='text/javascript' src='/js/jquery.js'></script>
<script type='text/javascript' src='/js/jquery.form.js'></script>

Now that we have the libraries included -

$(function() {
  // When everything has loaded - this function will execute:


  $("#style_form").ajaxForm(function() {
    // the style form will be submitted using ajax, when it succeeds:
    // this function is called:
    $("#thediv").text('Now Using: '+$('#styleswitch').val());
  });

  $("#styleswitch").change(function() {
    // When the styleswitch option changes, switch the style's href to preview
    $("#stylelink").attr('href', $(this).val());
    // We also want to submit the form to the server (will use our ajax)
    $(this).closest('form').submit();
  });

  // now that you have made changing the select option submit the form,
  // lets get rid of the submit button
  $("#style_form input[type=submit]").remove();
});

    CSS Howto..

    How to set the path to compile my CSS with Compass SASS

    If a child has a certain specific value, how to check and make “true” so that hover of the parent yields a result?

    How to move a CSS class below another? [closed]

    How to re-render a page from a Google Chrome extension?

    How to remove Width and Height values of an Image with css?

    How do you position div's in html5? [closed]

    how to override unselectable=“on” with css in IE10?

    How to defferent row heights for different rows in a single table?

    How to share common css and other resources among grails projects?

    how to number questions using class in CSS

    how to reduce the size of all component in sencha application

    Every third post excerpt shows up on its own line

    How to play a video inside a logo

    How to set the overall Grid thumbnail height to be equal?

    How to get menu text vertically aligned with inherited height

    How do you load the css for a Mediawiki tag extension?

    CSS: How to make this kind layout?

    how to create proportional image height/width

    jQuery, given a Variable with DIV with items, how to scroll an Item to the Left

    How to prevent Float contents overlap other contents below

    How to create this layout using CSS

    css: How to float div according to 2nd div in hierarchy

    DevTools: How to visualize scss changes automatically without the need to save

    How can I resize these divs while keeping the same layout?

    How do I make my div with six different pictures expand outwards when clicking it?

    How to Auto-Resize a DIV with CSS while keeping Aspect Ratio?

    how to get background image present in other folder using css?

    How to fill the width under an image with a caption without defining the width of the caption?

    How to make simple_form input field wider with CSS?

    How to avoid wrapping in CSS float