1

I have a set of stylesheets with different colour options. I have created a user control with a list of the stylesheet options which are setup as linkbuttons. On click I set a session variable with the path of the stylesheet I want to use, then on the master page I check this session and set the stylesheet accordingly.

The problem is that the stylesheet changes don't take effect until I refresh the page again. How can I force the stylesheet to reload instantly?

Here is my usercontrol:

<ul id="swatch">
  <li>
    <div class="green"></div>
    <asp:LinkButton ID="lbGreen" runat="server" Text="Green" ClientIDMode="Static" 
          onclick="lbGreen_Click"></asp:LinkButton>
  </li>    
  <li>
    <div class="maroon"></div>
    <asp:LinkButton ID="lbMaroon" runat="server" Text="Maroon" ClientIDMode="Static" 
          onclick="lbMaroon_Click"></asp:LinkButton>
  </li>
  <li>
    <div class="silver"></div>
    <asp:LinkButton ID="lbSilver" runat="server" Text="Silver" ClientIDMode="Static" 
          onclick="lbSilver_Click"></asp:LinkButton>
  </li>
  <li>
    <div class="black"></div>
    <asp:LinkButton ID="lbBlack" runat="server" Text="Black" ClientIDMode="Static" 
          onclick="lbBlack_Click"></asp:LinkButton>
  </li>
</ul>

Here is the code behind for this control:

public partial class StylesheetPicker : System.Web.UI.UserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void lbGreen_Click(object sender, EventArgs e)
    {
        SetStylesheet("green");
    }

    protected void lbMaroon_Click(object sender, EventArgs e)
    {
        SetStylesheet("maroon");
    }

    protected void lbSilver_Click(object sender, EventArgs e)
    {
        SetStylesheet("silver");
    }

    protected void lbBlack_Click(object sender, EventArgs e)
    {
        SetStylesheet("black");
    }

    private void SetStylesheet(string selectedStyle)
    {
        switch (selectedStyle)
        {
            case "green":
                Session["style"] = "/css/green.css";
                break;
            case "maroon":
                Session["style"] = "/css/maroon.css";
                break;
            case "silver":
                Session["style"] = "/css/silver.css";
                break;
            case "black":
                Session["style"] = "/css/black.css";
                break;
            default:
                Session["style"] = "/css/green.css";
                break;
        }                      
    }
}

and then here is the code snippet I have on my master page:

if(Session["style"] != null)
{
  var stylesheet = Session["style"];
  <link rel="stylesheet" type="text/css" href="@stylesheet" />
}
else
{
  <link rel="stylesheet" type="text/css" href="/css/green.css" />
}

It seems I have to click the linkbuttons twice to get the stylesheet to change. How can I do it so when the button is clicked it changes instantly?

Thanks

alimac83
  • 2,346
  • 6
  • 34
  • 50

3 Answers3

2

Give your stylesheet link element an id, then you should be able to change the href on it to something else. This code works in chrome, not sure about other browsers:

<link id="userStylesheet" rel="stylesheet" type="text/css" href="/css/green.css" />

Javascript to change it:

var linkTag = document.getElementById('userStylesheet');
linkTag.href = "css/maroon.css";

For the server side problem you could problem just redirect after they postback a change to it to get it to take effect on the next page load.

Ted Elliott
  • 3,415
  • 1
  • 27
  • 30
1

create a placeholder for your stylesheet in the master page, then you can set the stylesheet on the Page_Load/postback and not have to refresh the page?

in fact Adding StyleSheets Programmatically in Asp.Net seems to be what you are after.

Community
  • 1
  • 1
kolin
  • 2,326
  • 1
  • 28
  • 46
1

If I remember correctly what ends up happening is that the session variable is getting set after the masterpage has already evaluated the if. The second click is just serving to reload the page one more time after the session variable is set in the first click (but to late to evaluate from the master.

These days there are better ways of doing this, but if you really want to make this approach work you are going to have to do something like force a page reload after the variable is set, or evaluate the post data earlier than the master page's render manually.

Bill
  • 284
  • 2
  • 6
  • Thanks Bill. I'd be interested what a better way of doing it would be? I think due to the time constraint I'm under I'll have to just force a page refresh with JS (it'll work but not the prettiest solution I guess). But I'd like to know a better way of handling it for future reference :-) ty – alimac83 Jun 18 '12 at 16:03
  • 2
    Long term I would look into themes, skins, adding the css differently as in kolin's answer or just pointing the thing to an axd (which would let you do the session variable checks and merge in other css assuming a lot of the css is not different between the themes). For the rime being I think you could probably get away with just adding a response redirect in the button click code behinds to the current page unless you are doing something stateful that would be lost. – Bill Jun 18 '12 at 16:11