Saturday, 21 June 2014

Tutorial: How to make Ajax call in Sitecore MVC

20 comments
Today I’ve stumbled upon a post in Sitecore SDN forum regarding how to make an AJAX call in SITECORE MVC. In this blog post I am going to explain how to implement AJAX call in SITECORE MVC solution by adding routes in RouteConfig. Also check how to make Ajax call in Sitecore without registering routes in RouteConfig. We can divide complete functionality in below steps:
  1. Create a MVC controller action: Create an action in MVC controller which will return JSON result set by using Json() method. This action method may accept input parameters to implement business logic and return JsonResult accordingly.
  2. Register route for controller: In RouteConfig.cs file you need to add a route that triggers the controller and action.
  3. Implement AJAX call and Update HTML: Implement AJAX Call to controller action using jQuery and pass the input parameters, if any.
Example:  I’ve created a data template in Sitecore which is having three fields as shown in figure.
I’ve created few items based on newly created data template. See below figure:

I’ve created a basic controller rendering which is displaying books in a dropdown list. Below is the code of controller rendering for your reference:

Controller Code
public class BookDetailsController : SitecoreController
    {       
        public override ActionResult Index()
        {           
            List<SelectListItem> bookItems = new List<SelectListItem>();
            bookItems.Add(new SelectListItem { Text = "--Select Book--", Value = ""});
            bookItems.Add(new SelectListItem { Text = "Learn ASP", Value = "{EC2B22FE-8A6E-431F-8114-6B2944AE81B8}" });
            bookItems.Add(new SelectListItem { Text = "Learn MVC", Value = "{EBB9F7D5-22DB-4B7A-A275-42D9B5C88715}" });
            bookItems.Add(new SelectListItem { Text = "Learn SITECORE", Value = "{C89AE332-9845-4379-8C45-E8D58AAA5685}" });
            ViewBag.Books = bookItems;          
            return View();
        }    
}  
View Code
Select Any Book :
@Html.DropDownList("Books")

<div id="BookDetail" style="white-space: pre;">

</div>
On change event of dropdown list; I’ll display book details (book title, book author and book language) of selected book. I’ll use AJAX to achieve this functionality.
  1. Create a MVC controller action: I’ve written GetBookDetails action with [HttpPost] attribute in BookDetails Controller where I am passing Sitecore item id of selected book as input parameter. I’ll get book details by using item id of book item and return book details as JsonResult.
    [HttpPost]
            public JsonResult GetBookDetails (string itemId)
            {
                Book book = new Book();
                if (Sitecore.Data.ID.IsID(itemId))
                {
                    Item item = Sitecore.Context.Database.GetItem(Sitecore.Data.ID.Parse(itemId));
                    if (item != null)
                    {                   
                        book.BookTitle= item.Fields["Book Title"].Value;
                        book.BookAuthor = item.Fields["Author"].Value;
                        book.BookLanguage = item.Fields["Language"].Value;
                    }
                }
                return Json(book);
            }
        }
    public class Book
        {
            public string BookTitle { get; set; }
            public string BookAuthor { get; set; }
            public string BookLanguage { get; set; }
        }
    
  2. Register route for controller: In RouteConfig.cs file you need to add a route that triggers GetBookDetails action. The routes for the MVC Web Application are defined in the RouteConfig.cs under the App_Start folder of the MVC Project.
    You can modify RouteConfig.cs and use the RegisterRoutes function to register the custom route to perform Ajax calls. The route maps the first segment of a URL to a controller name, the second segment of a URL to a controller action, and the third segment to a parameter named id. The RouteConfig.cs contains the following code: 
    public static class RouteConfig
        {
            public static void RegisterRoutes(RouteCollection routes)
            {
                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
                RouteTable.Routes.MapRoute("BookDetails", "BookDetails/GetBookDetails", new { controller = "BookDetails", action = "GetBookDetails" });
            }
        }
    
    The RouteConfig.cs contains a static RegisterRoutes function which is called from the Global.asax file.
            protected void Application_Start(object sender, EventArgs e)
            {
               RouteConfig.RegisterRoutes(RouteTable.Routes);        
            }
  3. Implement AJAX call: I’ll use jQuery to make Ajax call. In the below code, I am reading the value of selected book from dropdown list and passing book item id as an input parameter while making Ajax call to get book details. Use the returned JsonResult set to update the HTML div BookDetail.
    <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1.js"> </script>
    <script type="text/javascript">
        $(function () {
            $("#Books").bind("keyup change", function () {
                var itemId = $(this).val();
                if (itemId != "") {
                    $.ajax({
                        url: "BookDetails/GetBookDetails",
                        type: "POST",
                        data: { itemId: itemId },
                        context: this,
                        success: function (data) {
                            var BookString = "Book Title: " + data.BookTitle + "\n" + "Book Author: " + data.BookAuthor + "\n" + "Book Language:" + data.BookLanguage;
                            $("#BookDetail").text(BookString);
                            console.log("success", data);
                        },
                        error: function (data) {
                            console.log("error", data);
                        }
                    });
                }
                else {
                    $("#BookDetail").text("");
                }
            });
        });
    </script>
Comments and suggestions are most welcome. Happy coding! 

20 comments :