Click here to Skip to main content
15,868,016 members
Articles / MVC / MVC4

ASP.NET MVC 4 SPA Navigation with Sammy.js

Rate me:
Please Sign up or sign in to vote.
4.80/5 (4 votes)
28 Jan 2013CPOL4 min read 29.5K   9   5
I am learning from John Papa's Single Page Apps with HTML5, Web API, Knockout and jQuery

I am learning from John Papa’s "Single Page Apps with HTML5, Web API, Knockout and jQuery" on Pluralsight. The course outlines building an application called "Code Camper". The "Code Camper" sample is very effective at showing an end to end SPA design. It leverages a bunch of open source libraries and can be a lot to take in all at once. One of the libraries used is called Sammy.js. I decided it would be beneficial to focus on just Sammy.js library which is the focus of this blog post.

If you are like me, then you are also new to Single-Page Applications. I find it helpful to start with a simple definition. Wikipedia defines SPA as a "web application… that fits on a single web page with the goal of providing a more fluid user experience akin to a desktop application. In an SPA, either all necessary code – HTML, JavaScript, and CSS – is retrieved with a single page load, or partial changes are performed loading new code on demand from the web server, usually driven by user actions."

ASP.NET MVC versus Single Page Application

Suppose you have an HTML, JavaScript and CSS application loaded in a browser. If you look at the home page source, you might notice a series of anchor elements containing hypertext links to other areas within your application such as an "About" page. If you build an SPA version of this application versus a traditional ASP.NET MVC version, it would be difficult to tell them apart by inspecting the HTML only. The anchor tags would look very very similar if not identical.

In a standard MVC application, when the User clicks on the "About" hyperlink, MVC’s routing would find the server-side controller which would create an HTML page on the server and navigate the browser to this new page.

In an SPA, when the User clicks on the "About" hyperlink, the client side HTML is dynamically manipulated all within the client’s browser using standard HTML, JavaScript and CSS. Since a costly server trip is avoided, the result is typically "a more fluid user experience". To pull this off, typically an SPA loads more data in memory upfront to enable the application to stay on the client.

Sammy.js is an open source library that Code Camper leverages to help pull off the SPA behavior but at the same time keep all the good things the browsers do for us such as history management, etc. It's pretty slick.

For me, the following question captures one of the cool features of Sammy.js: "How can I create a standard HTML anchor tag that when the user clicks, instead of requesting a resource on the server, I can intercept the request on the client and call a JavaScript function?" Let me show you an example that answers this question. This example is a modified version of the example provided in the following blog post.

http://mikehadlow.blogspot.com/2010/11/sammyjs.html#/ My version mimics how Code Camper works as well. Thanks Mike Hadlow for this very simple example.

Step by Step

Create a new ASP.NET MVC4 Internet Application Project called "MVC4Sammy or download the finished code here.

Right click on References and click on "Manage NuGet Packages…". Search for Sammy.js and click "Install".

In the root of the project, add an "MVC 4 View Page (Razor) called "Index.cshtml".

image

HTML
 1: <!DOCTYPE html>
 2: <html>
 3: <head>
 4:     <meta name="viewport" content="width=device-width" />
 5:     <title>Sammy Test</title>
 6:     <script src="Scripts/jquery-1.8.2.js"></script>
 7:     <script src="Scripts/sammy-0.7.2.js"></script>
 8:     <script src="Scripts/sammy_test.js"></script>
 9: </head>
10: <body>
11:     <div id="header">
12:             <h1>Sammy Test</h1>
13:             <a href="#/one">one</a>
14:             <a href="#/two">two</a>
15:             <a href="/#three">three</a>
16:             <a href="HtmlPage1.html">HtmlPage1</a>
17:             <a href="http://www.promodel.com">ProModel</a>
18:         </div>
19:         <div id="main">
20:             <section class="main">
21:                 @RenderPage("Views/Partial1.cshtml")
22:                 @RenderPage("Views/Partial2.cshtml")
23:                 @RenderPage("Views/Partial3.cshtml")
24:             </section>
25:         </div>
26: </body>
27: </html>
28:

Delete all the files from "Views" folder. Right click on the empty "Views" folder and Add a partial "View" called Partial1.

image

Put the following code in Partial1.cshtml.

HTML
<section id="partial1-view" class="view">
    <div>Hello from Partial 1</div>
</section>

Repeat for Partial2 and Partial3 but change the section ids.

image

Add a new "JavaScript file" in the "Scripts" folder called "sammy_test.js". Put the following code:

JavaScript
 1: (function ($) {
 2:
 3:     var app = $.sammy('#main', function () {
 4:
 5:         this.get("#/one", function (context) {
 6:             $(".view").hide();
 7:             $("#partial1-view").show();
 8:         });
 9:
10:         this.get("#/two", function (context) {
11:             $(".view").hide();
12:             $("#partial2-view").show();
13:         });
14:
15:         this.get("/#three", function (context) {
16:             $(".view").hide();
17:             $("#partial3-view").show();
18:         });
19:     });
20:
21:     $(function () {
22:         app.run('#/');
23:     });
24:
25: })(jQuery);

Modified root Web.Config webpages:Enabled to true.

image

Add a new "Html Page" to the root called "HtmlPage1". Put any text in the body.

Set Index.cshtml as Start Page and Run.

Highlights

Similar to Code Camper, this example MVC4 SPA creates a root view called "index.cshtml" containing a series of @RenderPage calls against some partial views. The partial views represent the various modules within an application. Each partial view is declared within a "Section" element with a unique id and a shared class called "view".

image

In the "sammy_test.js" file, you will see code registering "get" routes with JavaScript functions such as:

image

When the user clicks on a link that goes to "#/one", that function will be called instead of requesting a resource from the server. The JavaScript code hides any element with a class called "view", then immediately shows any element with an id value of "partial1-view".

There are probably a million ways to do this, but this example shows how the client is dynamically manipulated without going to the server.

Image 7 Image 8

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Chief Technology Officer PROMODEL Corporation
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionSammy's technique using in ASP.NET MVC with integration of SSRS Report Pin
5G15-Dec-16 5:17
5G15-Dec-16 5:17 
QuestionSo familiar Pin
Krystan Honour23-Mar-15 11:10
professionalKrystan Honour23-Mar-15 11:10 
QuestionNice Article Pin
Suraj Sahoo | Coding Passion20-Apr-14 1:05
professionalSuraj Sahoo | Coding Passion20-Apr-14 1:05 
QuestionIs '#/' compulsary in the url Pin
Aaditya parcha19-Mar-14 20:58
Aaditya parcha19-Mar-14 20:58 
GeneralMy vote of 5 Pin
Mohammad Sepahvand26-Apr-13 5:34
Mohammad Sepahvand26-Apr-13 5:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.