Nov 12, 2011

Stylish ASP.NET Wizard Control with Horizontal Sidebar on Top

Our objective is to customize asp.net wizard control sidebar as stylish horizontal step navigation on top without any image. First, we will disable existing side bar and use header template to create own sidebar. See following screen-shot which we are going to implement:


wizard steps asp.net sidebar

Wizard Structure:

To disable existing sidebar, set DisplaySideBar=”false”. See following wizard structure, there are 5 steps for sample and Repeater is used in header template.

 <asp:Wizard ID="Wizard1" runat="server" DisplaySideBar="false">
            <WizardSteps>
                <asp:WizardStep ID="WizardStep1" runat="server" Title="Step 1">
                 <div class="content">This is Step 1</div>
                </asp:WizardStep>
                <asp:WizardStep ID="WizardStep2" runat="server" Title="Step 2">
                    <div class="content">This is Step 2</div>
                </asp:WizardStep>
                <asp:WizardStep ID="WizardStep3" runat="server" Title="Step 3">
                   <div class="content">This is Step 3</div>
                </asp:WizardStep>
                <asp:WizardStep ID="WizardStep4" runat="server" Title="Step 4">
                    <div class="content">This is Step 4</div>
                </asp:WizardStep>
            <asp:WizardStep ID="WizardStep5" runat="server" Title="Step 5">
                    <div class="content">This is Step 5</div>
                </asp:WizardStep>
           </WizardSteps>
            <HeaderTemplate>
                <ul id="wizHeader">
                    <asp:Repeater ID="SideBarList" runat="server">
                        <ItemTemplate>
                            <li><a class="<%# GetClassForWizardStep(Container.DataItem) %>" title="<%#Eval("Name")%>">
                                <%# Eval("Name")%></a> </li>
                        </ItemTemplate>
                    </asp:Repeater>
                </ul>
            </HeaderTemplate>
        </asp:Wizard>

See following server side code to bind repeater and assign class name:

	protected void Page_Load(object sender, EventArgs e)
    {
        Wizard1.PreRender += new EventHandler(Wizard1_PreRender);        
    }
    protected void Wizard1_PreRender(object sender, EventArgs e)
    {
        Repeater SideBarList = Wizard1.FindControl("HeaderContainer").FindControl("SideBarList") as Repeater;
        SideBarList.DataSource = Wizard1.WizardSteps;
        SideBarList.DataBind();

    }

    protected string GetClassForWizardStep(object wizardStep)
    {
        WizardStep step = wizardStep as WizardStep;

        if (step == null)
        {
            return "";
        }
        int stepIndex = Wizard1.WizardSteps.IndexOf(step);

        if (stepIndex < Wizard1.ActiveStepIndex)
        {
            return "prevStep";
        }
        else if (stepIndex > Wizard1.ActiveStepIndex)
        {
            return "nextStep";
        }
        else
        {
            return "currentStep";
        }
    }

CSS:

There are 3 classes used for previous steps(prevStep), current step(currentStep) and next steps(nextStep).

		#wizHeader li .prevStep
        {
            background-color: #669966;
        }
        #wizHeader li .prevStep:after
        {
            border-left-color:#669966 !important;
        }
        #wizHeader li .currentStep
        {
            background-color: #C36615;
        }
        #wizHeader li .currentStep:after
        {
            border-left-color: #C36615 !important;
        }
        #wizHeader li .nextStep
        {
            background-color:#C2C2C2;
        }
        #wizHeader li .nextStep:after
        {
            border-left-color:#C2C2C2 !important;
        }
        #wizHeader
        {
            list-style: none;
            overflow: hidden;
            font: 18px Helvetica, Arial, Sans-Serif;
            margin: 0px;
            padding: 0px;
        }
        #wizHeader li
        {
            float: left;
        }
        #wizHeader li a
        {
            color: white;
            text-decoration: none;
            padding: 10px 0 10px 55px;
            background: brown; /* fallback color */
            background: hsla(34,85%,35%,1);
            position: relative;
            display: block;
            float: left;
        }
        #wizHeader li a:after
        {
            content: " ";
            display: block;
            width: 0;
            height: 0;
            border-top: 50px solid transparent; /* Go big on the size, and let overflow hide */
            border-bottom: 50px solid transparent;
            border-left: 30px solid hsla(34,85%,35%,1);
            position: absolute;
            top: 50%;
            margin-top: -50px;
            left: 100%;
            z-index: 2;
        }
        #wizHeader li a:before
        {
            content: " ";
            display: block;
            width: 0;
            height: 0;
            border-top: 50px solid transparent;
            border-bottom: 50px solid transparent;
            border-left: 30px solid white;
            position: absolute;
            top: 50%;
            margin-top: -50px;
            margin-left: 1px;
            left: 100%;
            z-index: 1;
        }        
        #wizHeader li:first-child a
        {
            padding-left: 10px;
        }
        #wizHeader li:last-child 
        {
            padding-right: 50px;
        }
        #wizHeader li a:hover
        {
            background: #FE9400;
        }
        #wizHeader li a:hover:after
        {
            border-left-color: #FE9400 !important;
        }        
        .content
        {
            height:150px;           
            padding-top:75px;
            text-align:center;
            background-color:#F9F9F9;
            font-size:48px;
        }

Note:
For browsers that don’t support :after/:before/ nth-child, the code will not work.

Fun with CSS:

1. Increase margin-left in “#wizHeader li a:before” to increase width of arrow.

2. Add Padding:20px in “#wizHeader li” css you will get following layout

wizard steps css

3. Set margin-left: 35px; in “#wizHeader li a” to get above layout.

Thanks this post, fiddle and CSS Triangle Breadcrumbs. Share your opinion or queries in comment box.

Enjoy Programming!!!

21 comments

  1. code has only one bug which is not displaying the horizontal steps because of
    OnPreRender=”Wizard1_PreRender”
    is not written in design page so please correct it by below line

    BTW its a great post…Thanks

  2. Very good, I made it work with included links.
    Thanks Sohail.
    1) In aspx

    This is Step 1

    This is Step 2

    This is Step 3

    This is Step 4

    This is Step 5

    <asp:LinkButton
    ID="SideBarButton"
    CssClass="”
    onclick=”Step_Click”
    Text=””
    Tabindex=””
    runat=”server”
    >

    2) In .cs
    protected string GetClassForWizardStep(object wizardStep)
    {
    WizardStep step = wizardStep as WizardStep;

    if (step == null)
    {
    return “”;
    }
    int stepIndex = Wizard1.WizardSteps.IndexOf(step);

    if (stepIndex Wizard1.ActiveStepIndex)
    {
    return “nextStep”;
    }
    else
    {
    return “currentStep”;
    }
    }
    protected int GetIndexForWizardStep(object wizardStep)
    {
    WizardStep step = wizardStep as WizardStep;

    int stepIndex = Wizard1.WizardSteps.IndexOf(step);

    return (stepIndex);
    }

    protected void Step_Click(object sender, EventArgs e)
    {
    LinkButton btnStep = (LinkButton)sender;
    string id = btnStep.TabIndex.ToString();
    sapo.Text = “Text= ” + id + ” —- CssClass=” + btnStep.CssClass.ToString();
    // if (btnStep.CssClass == “prevStep” || btnStep.CssClass == “currentStep”)
    // {
    // sapo.Text = “Text= ” + id + ” —- CssClass=” + btnStep.CssClass.ToString();
    switch (id)
    {
    case “0”: Wizard1.MoveTo(WizardStep1); break;
    case “1”: Wizard1.MoveTo(WizardStep2); break;
    case “2”: Wizard1.MoveTo(WizardStep3); break;
    case “3”: Wizard1.MoveTo(WizardStep4); break;
    case “4”: Wizard1.MoveTo(WizardStep5); break;
    default: Wizard1.MoveTo(WizardStep1); break;
    }
    // }
    }

  3. Is there a way to styling the buttons Next, Previous and Finish? I can’t find any option for doing that. Nice post BTW! Thanks.

  4. Thank you very much for wonder article. Is there a way to render the HTML in DIV layout instead of TABLE layout for the example you demonstrated.

  5. HI Brij, I know the post has been a while but its there a way to make the Wiz Header responsive. the arrows seems to show when the screen size decreases.
    Thank you

  6. Thanks for nice article. am new for CSS, this article is working fine in chrome and mozilla but not in ie7 and ie 8 (Arrow shape). How can i do this and where i can change in css???. Please help me out, thanks in advance.

  7. HI,

    NIce article.. need your help

    At the last step,this tyle is going off.

    Can you please,tell me how to make that style stay even at the last step.

    User can go back and change the details.

  8. This was a great article for getting the arrows in the wizard control.
    I have modified it to allow you to click the arrow links in the header template:

    /* replace the html a tag with asp:Linkbutton */

    <asp:LinkButton runat="server" ID="SideBarButton" Font-Bold="true" onclick="Step_Click"
    CssClass='’ Text=” ToolTip=”/>

    /* at the following onclick event*/

    protected void Step_Click(object sender, EventArgs e)
    {
    LinkButton btnStep = (LinkButton)sender;
    string id = btnStep.Text;

    if (btnStep.CssClass == “prevStep” || btnStep.CssClass == “currentStep”)
    {
    switch (id)
    {
    case “Step 1”: Wizard1.MoveTo(Step1); break;
    case “Step 2”: Wizard1.MoveTo(Step2); break;
    case “Step 3”: Wizard1.MoveTo(Step3); break;
    default: Wizard1.MoveTo(Step1); break;
    }
    }
    }

    1. i tried it but giving me error :

      Parser Error Message: The server tag is not well formed.
      Line 725:
      Line 726:
      Line 727: <asp:LinkButton runat="server" ID="SideBarButton" Font-Bold="true" OnClick="Step_Click"
      Line 728: CssClass="” Text=””
      Line 729: ToolTip=”” />

      1. The Textarea rendered for inserting a comment rendered in th ewrog way Sohail Deen’s great improvements.

        Thanks Sohail Deen :-)

    1. To fix this simply add this line in the CSS:
      border-left: 30px solid brown;
      right above
      border-left: 30px solid hsla(34,85%,35%,1);

  9. hello … very helpful article …. i need your help
    how can i set current postion of wizard step is coming from database …i want to show all completed steps in green ….but also user can see previous steps

  10. I want to use this amazing and nice wizard, but unfortunately the arrows at the top of the wizard are not shown in Internet Explorer.
    Is there any way to display them?

    1. To fix this simply add this line in the CSS:
      border-left: 30px solid brown;
      right above
      border-left: 30px solid hsla(34,85%,35%,1);

      Also ensure you got compatibility mode disabled.

Leave a Reply

Your email address will not be published. Required fields are marked *