Graceful Degradation AJAX

AJAX can improve site's appeal and give you chance to stretch your dollar a little further by serving more requests in same bandwidth. AJAX needs JavaScript and there are times when either user of your website has disabled JavaScript or have a device that doesn't support JavaScript. Although number of users with no JavaScript support are less but that doesn't mean we don't need their business.

Today, we will look at an example of Graceful Degradation of our web application which supports both AJAX and Non-AJAX usages.

Note: I am using ASP.NET MVC 3 but you can use any server side technology but it can be utilized with any server side technology with some minor changes.

To get started, let's create:

  1. A class with name "Employee" in Models folder
    1. Create three properties: First Name, Last Name, Hire Date (As shown below)

public class Employee

{

public string FirstName { get; set; }

public string LastName { get; set; }

public DateTime HireDate { get; set; }

}

 

  1. In our home controller we will create two action methods
    1. Employee (for Get requests)
    2. Employee, with Http Post attribute (for posting values back)

     

public ActionResult Employee()

{

return View();

}

 

[HttpPost]

public ActionResult Employee(Employee e)

{

ViewBag.Employee = e;

return View();

}

 

    To keep things simple, I am just receiving input from user and returning it back in ViewBag.

  1. Our view is strongly typed to Employee Model and will include:
    1. Form with input text for First Name, Last Name, Hire Date
    2. If condition to check if ViewBag has Employee data and if it does then print it in tabular form

@model MVC3.Models.Employee

@{

ViewBag.Title = "Employee Data";

}

 

<div id="empForm">

@using (Html.BeginForm())

{

<fieldset>

<legend>New Employee</legend>

<div>

<p>

@Html.LabelFor(m => m.FirstName)

</p>

<p>

@Html.TextBoxFor(m => m.FirstName)

</p>

</div>

<div>

<p>

@Html.LabelFor(m => m.LastName)

</p>

<p>

@Html.TextBoxFor(m => m.LastName)

</p>

</div>

<div>

<p>

@Html.LabelFor(m => m.HireDate)

</p>

<p>

@Html.TextBoxFor(m => m.HireDate)

</p>

</div>

<div>

<input type="submit" value="Save Employee" />

</div>

</fieldset>

}

</div>

 

@if (ViewBag.Employee!=null)

{

MVC3Test.Models.Employee e = ViewBag.Employee;

<table>

<thead>

<tr>

<th>

Name

</th>

<th>

Hire Date

</th>

</tr>

</thead>

<tbody>

<tr>

<td>

@e.LastName, @e.FirstName

</td>

<td>

@e.HireDate.ToShortDateString()

</td>

</tr>

</tbody>

</table>

}

 

  1. It's time to test your page without AJAX so run your application and browse employee page, fill all the fields and submit the page. You should see:

     

  2. Now it's time to add some JavaScript to AJAXify out page, but before we do you will need following libraries (can be downloaded using NuGet Package manager):
    1. Reference to latest jQuery Library
    2. Reference to JSON2.js file
  3. Once downloaded and added to project we will add its reference to _Layout.cshtml page present in Shared under Views folder
  4. Next we will create a file with name "empsubmit.js"
  5. At the bottom of the page, add "empsubmit.js" reference in our "Employee.cshtml" view

<script src="../../Scripts/empsubmit.js" type="text/javascript"></script>

 

  1. Now we will catch submit event fired when the page is submitted and instead of submitting it we will inject our script and call AJAX submit version. So add code below to the JS file:

/// <reference path="../jquery-1.9.1-vsdoc.js" />

$(function () {

$('#empForm form').submit(function (e) {

e.preventDefault();

var employee = {

FirstName: $('#FirstName').val(),

LastName: $('#LastName').val(),

HireDate: $('#HireDate').val()

};

var form = $('#empForm form');

$.ajax({

url: form.attr('action'),

type: form.attr('method'),

data: JSON.stringify(employee),

processData: false,

contentType: 'application/json; charset=utf-8',

success: function (data) {

$('#result').append("<table><thead><tr><th>Name</th><th>Hire Date</th></tr></thead><tbody><tr><td>" + data.LastName + ", " + data.FirstName + "</td><td>" + data.HireDate + "</td></tr></tbody></table>");

}

});

 

});

});

 

  1. Update HomeController's employee action method (post version) with code below (bold code shows changes):

[HttpPost]

public ActionResult Employee(Employee e)

{

bool ajaxCheck=Request.Headers.AllKeys.Contains("X-Requested-With");

if (ajaxCheck)//(Request.IsAjaxRequest())

{

return Json(new {

FirstName=e.FirstName,

LastName=e.LastName,

HireDate=e.HireDate.ToShortDateString()

});

}

ViewBag.Employee = e;

return View();

}

 

  1. ASP.NET MVC has Request.IsAjaxRequest() method built in but we used a more generic approach to show that this can also be done by checking headers we are receiving in our request.
  2. Once all these changes are done build solution and revisit employee page

Tags: , , , ,

AJAX | jQuery | MVC