I was doing some R&D for an application which would have a wizard or survey style interface where the user navigates forwards and backwards through a number of steps. I was looking at using a jQuery slider to display a progress marker which doubled as navigation. Although I did not use this method in the final application here I will describe how to set this up.
To get started we need project. I have created a new MVC project (not Empty) and chose No Authentication. You can choose any authentication option you require.

By selecting this project we are off to a running start because jQuery is included. We will need to add jQueryUI library which can be done via NuGet.
Install-Package jQuery.UI.Combined
To use the jQueryUI elements (javascript and css) we can add references in the BundleConfig class (App_Start folder).
bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
"~/Scripts/jquery-ui-{version}.js"));
bundles.Add(new StyleBundle("~/Content/jqueryui").Include(
"~/Content/themes/base/all.css"));
Now is a good time to create a file to hold our custom javascript, create a file in the Scripts folder called site.js then add a reference to the file in the BundleConfig class like before.
bundles.Add(new ScriptBundle("~/bundles/sitejs").Include(
"~/Scripts/site.js"));
Any custom styles will be added to site.css which exists in the Content folder and is already included in the Content/css bundle.
These bundles can now be referenced in either the layout page or the individual view. I have added references in the layout page, the styling references I added to the head section.
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
@Styles.Render("~/Content/jqueryui")
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
The javascript references are added with other javascript at the bottom of the page. Notice the references to both the jqueryui and sitejs bungles.
@Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/jqueryui") @Scripts.Render("~/bundles/bootstrap") @Scripts.Render("~/bundles/sitejs") @RenderSection("scripts", required: false)
Now we have performed the required setup actions we can now look at the code that makes things happen. For starters we can add action methods in HomeController, one for each step.
public ActionResult Step1()
{
return View();
}
public ActionResult Step2()
{
return View();
}
Create a view for each action (right-click method and select Add View from context menu) and add some basic text like below for step 1
@{
Layout = null;
}
<h1>Step 1</h1>
and step 2
@{
Layout = null;
}
<h1>Step 1</h1>
Because we are loading a view inside a div of another view, if we did not set the layout to null the rendering engine would apply the layout to the parent view and the child view (loaded in the div).
Setting the layout to null prevents the layout being applied to the child view.
Add some basic styling to the content\site.css file to space out the labels on the slider.
/* slider style start */
#navSlider label {
position: absolute;
width: 20px;
margin-left: -10px;
text-align: center;
margin-top: 20px;
}
/* below is not necessary, just for style */
#navSlider {
width: 80%;
margin: 2em auto;
}
/* slider style end */
The final piece of code is the javascript to set up the slider and the action(s) to take each time the value of the slider changes, or in our case each time a label is clicked.
Add this code to the scripts\site.js file created earlier.
$(function () {
// A slider with a step of 1
$("#navSlider").slider({
value: 1,
min: 1,
max: 2,
step: 1,
change: function (event, ui) {
$('#contentDIV').load("/home/step" + ui.value);
}
})
.each(function () {
// Add labels to slider whose values
// are specified by min, max
// Get the options for this slider (specified above)
var opt = $(this).data().uiSlider.options;
// Calcualte the number of possible values
var vals = opt.max - opt.min;
// Position the labels
for (var i = 0; i <= vals; i++) {
// Create a new element and position it with percentages
var el = $('<label >' + (i + opt.min) + '</label>').css('left', (i / vals * 100) + '%');
// Add the element inside #navSlider
$("#navSlider").append(el);
}
});
$('#contentDIV').load("/home/step1");
});
Because I have given the views incremental names (step1, step2…) in the Change event it is convenient to use the use the index of the step to build the name of the view to load in the DIV element.
To get the same effect for views where their names are less similar some logic will be needed in the change event of the slider to decide which view to load, for example
change: function (event, ui) {
var viewName;
switch(ui.value)
{
case 1:
viewName="overview";
break;
case 2:
viewName="employment";
break;
case 3:
viewName = "training";
break;
default:
viewName = "overview";
}
$('#contentDIV').load("/home/" + viewName);
}
After configuring the slider the step1 view is loaded as the default view.
It is easy to change this code to accomodate having more steps by setting the max value on the slider configuration. I have added a link on the download page to a demo application with 5 steps.

You must be logged in to post a comment.