- How to make partial update
- How to make a Get request with additional parameters in query string
- How to make a Post request with additional paremeters inside request body
- What happens if javascript is disabled or the user using an older browser
Menu Interface
The menu items in the master page will be as below ;<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" runat="server"> <title> <asp:ContentPlaceHolder ID="TitleContent" runat="server" /> </title> <link href="../../Content/Site.css" rel="stylesheet" type="text/css" /> </head> <body> <div class="page"> <div id="header"> <div id="title"> <h1> Asp.Net Mvc & jQuery Demo</h1> </div> <div id="logindisplay"> <% Html.RenderPartial("LogOnUserControl"); %> </div> <div id="menucontainer"> <ul id="menu"> <li> <%= Html.ActionLink("Home", "Index", "Home")%></li> <li> <%= Html.ActionLink("Html", "TestMethod", "Home")%></li> <li> <%= Html.ActionLink("Partial Update", "TestMethod", "Home", new {name = "cem", surname = "karaca"}, new { @class = "html" })%> </li> <li> <%= Html.ActionLink("Json (GET)", "TestMethod", "Home", new { name = "yasin", surname= "tarim"}, new { @class = "jsonGET" }) %> </li> <li> <%= Html.ActionLink("Json (POST)", "TestMethod", "Home", new { name = "yasin", surname= "tarim"}, new { @class = "jsonPOST" }) %> </li> <li> <%= Html.ActionLink("About", "About", "Home")%></li> </ul> </div> </div> <div id="main"> <asp:ContentPlaceHolder ID="MainContent" runat="server" /> <div id="footer"> </div> </div> </div> <script type="text/javascript" src="../../Scripts/jquery-1.4.1.min.js"></script> <script type="text/javascript" src="../../Scripts/Helper.js"></script> </body> </html>As seen in the highlighted sections instead of using Ajax.ActionLink I will use Html.ActionLink with custom class attributes specifying what kind of request will be invoked by the jQuery ajax method. All the menu invokes TestMethod action method in the HomeController class. We need to add the jquery library and a custom javascript file containing helper methods. Here is the Helper.js
/// <reference path="jquery-1.4.1.min-vsdoc.js" /> //Helper object for making request and updating view var HELPER = (function () { var methods = {}; methods.updateView = function (data) { //locate the object that will be updated //which is inside div with id 'main' var $placeHolder = $("#main > :not(#footer)"), html, i, l, item; //if data is a string object simply update //view with data if (typeof data === "string") { $placeHolder.replaceWith(data); return; } //if data is a javascript object with additional //properties loop over the properties for each item //and create an html ul element html = ['<ul>']; for (i = 0, l = data.length; i < l; i++) { html.push("<li>"); for (item in data[i]) { if (data[i].hasOwnProperty(item)) { html.push("<span><b>" + item + "</b> : " + data[i][item] + "</span></br>"); } } html.push("</li>"); } html.push("</ul>"); $placeHolder.replaceWith(html.join('')); }; methods.makeRequest = function (obj) { $.ajax({ type: obj.type || "POST", url: obj.url, data: obj.data || " ", contentType: "application/{contentType}; charset=utf-8". replace("{contentType}", obj.contentType || "json"), dataType: obj.contentType || "json", beforeSend: obj.beforeSend || function (xhr) {}, success: obj.success || function (msg) {}, error: obj.error || function (msg) {} }); }; return { makeRequest: methods.makeRequest, updateView: methods.updateView }; }()); $(function () { //bind the click event to menu div //catch all the click event from anchor element $("#menu").click(function (e) { if (e.target.nodeName === "A") { var trg = e.target, url = trg.href, $trg = $(trg); //if the anchor element has html class //make a http post request for a partial update if ($trg.hasClass("html")) { HELPER.makeRequest({ type: "POST", contentType: "html", url: url, success: function (arg) { HELPER.updateView(arg); } }); } // if the anchor element has jsonPost class //make a http post request and send additional //parameters within request body else if ($trg.hasClass("jsonPOST")) { HELPER.makeRequest({ type: "POST", contentType: 'json', data: { age: '28', songs: ['Namus Belasi', 'Tamirci Ciragi', 'Parka'], group: 'Dervisan' }, url: url, success: function (arg) { HELPER.updateView(arg); } }); } // if the anchor element has jsonPost class //make a http GET request and send additional //parameters within request url else if ($trg.hasClass("jsonGET")) { HELPER.makeRequest({ type: "GET", contentType: 'json', data: { age: '30', song: 'Unutamadigim' }, url: url, success: function (arg) { HELPER.updateView(arg); } }); } return false; } }); });
Updating View and Making Ajax Calls with jQuery
The Helper javascript object has two helper methods which are MakeRequest and UpdateView. The MakeRequest method accepts an object which has additional properties and functions like url, data,contentType. The second method UpdateView simply updates the area within the element with id main. But because the main div also contains the footer div we simply filter the footer div and then update the rest of the main with a simple jquery selector.The jQuery selector is :
$("#main > :not(#footer)");as higlighted in line 8.
The MakeRequestmethod of the helper class when the document loaded. After the document loaded we bind a click event to the menu div (id = menu). So :
-
<>liWhenever a click event occurs inside the menu div we check the target if it is an anchor element.
- If it is an anchor tag we check it is class properties
- if the anchor element has html class we invoke an Http Post request. if it has jsonGet class we invoke an Http Get and send extra data within the querystring, if it has jsonPost class we incoke an Http Post and send extra data within the request body.
public ActionResult TestMethod(string name, string surname) { if (Request.IsAjaxRequest()) // Check if it is an ajax request { //check if the response is requested in json format if (Request.ContentType.Contains("application/json")) { //check if the request is made using HTTP GET or HTTP POST string httpMethod = Request.HttpMethod; if (httpMethod == "GET") { //Get additional parameters added with jQuery from QueryString var collection = Request.QueryString; return Json(collection.Cast<string>(). Select(p => new { Key = p, Value = collection[p]}), JsonRequestBehavior.AllowGet); } else if (httpMethod == "POST") { //Get additional parameters from Request body using (var sr = new StreamReader(Request.InputStream)) { //fetch the request body into a string variable var requestBody = sr.ReadToEnd(); //create a name-value pair object from request body var collection = HttpUtility.ParseQueryString(requestBody); //return Json Message return Json(collection.Cast<string>(). Select(p => new { Key = p, Value = collection[p] })); } } } //response format is not json so return partial view in html format //pass a string as the model data return PartialView("SimplePartialView", "This message is generated from partial view in html format".Split(' ')); } else { //request is not made by XmlHttpRequest object //return normal view return View("The request is made without ajax".Split(' ')); } }Now when we receive the request
- First we check if it is an ajax request if it is not we simply pass the model object to the TestMethod View
- If the request is an ajax request we check the response type that the user requested if the contentType is html we render a partialview names SimplePartialView.
- If it an ajax request with contentType of json we check the HttpMethod of the request. If the httpmethod is GET we read posted values (which also contains the ones that are added via jQuery besides the ones in the request url as in the masterpage) and send it back to the client in json format. If the http method is POST we read the additional data from the request body and send them to the client on json format.
[HttpPost] public ActionResult TestMethod()
What happens if the user has disabled javascript or using an older browser
Our application will still be running. Because we used Html.ActionLink instead of Ajax.ActionLink if the javascript is disabled our jQuery code will not be called. So for example if the user click Json(Post) link it will receive an html response instead of json because we check if the request is an ajax request in TestMethod with the isAjaxRequest extension method and if it is not we simply render the TestMethod view. Here is the TestMethod view TestMethod.aspx<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %> <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> TestMethod </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <% Html.RenderPartial("SimplePartialView"); %> </asp:Content>and here is the SimpleViewPartialView.ascx view:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<string>>" %> <% foreach (var item in Model){ %> <li> <%= item %> </li> <% } %>
Hope it helps.
No comments:
Post a Comment