Partial Rendering with ASP.NET MVC and jQuery

An entry about asp.net mvc | ajax | javascript Publication date 1. June 2008 13:57

Yesterday, I wrote a post detailing how easy we can invoke an ASP.NET MVC controller action from JavaScript using jQuery. Lets up the ante a bit, and see if we can't use the same approach to get some partial rendering going. To accomplish this, we'll use a fact about the RenderViewResult class that hasn't got a lot of attention so far - the fact that its View propetry can be set to point at a UserControl, not just a WebForm. When doing so, only the user control will be rendered - which sounds like exactly what we need for doing partial rendering..

Rendering User Controls

Lets say we're building a simple task list. We might have the following UserControl representing a single task:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Task.ascx.cs" Inherits="MvcApplication2.Views.Tasks.Task" %>
<div class="task">
    <div class="task_name"><%= ViewData.Name %></div>
    <div class="task_due"><%= ViewData.Due %></div>
    <div class="task_desc"><%= ViewData.Description %></div>
</div>

 

Our TaskList view may then use this to render a list of tasks:

<h1>Tasks</h1>
 
<div id="task_list">
    <% foreach(Task task in ViewData) {%>
        <%= Html.RenderUserControl("~/Views/Tasks/Task.ascx", task) %>
    <%} %>
</div>
 
<h1>Add task</h1>
 
Name: <input type="text" id="newtask_name" /><br />
Due: <input type="text" id="newtask_due" /><br />
Description: <input type="text" id="newtask_desc" /><br />
<input type="button" onclick="AddTask()" value="Add" />

 

The TaskList view is rendered by the Index action on our TaskController, which looks like this:

public ActionResult Index()
{
    Task[] tasks = // get tasks from repository
 
    return RenderView("TaskList", tasks);
}

 

Next, we need an action for creating a new task. However, we want to invoke it from JavaScript, and have it only return the markup for the new task item so that we can append it to the task list dynamically, instead of refreshing the entire page. To accomplish this, we implement it using the previously mentioned trick of the RenderViewResult class:

public ActionResult New(string name, string desc, DateTime due)
{
    Task task = new Task { Name = name, Description = desc, Due = due };
    // ...save task to repository
    return RenderView("Task", task);
}

 

Notice here that "Task" points to the Task.ascx user control, not a Web Form. When invoked, this action will render the markup for that control only.

Manipulating the DOM

Like I mentioned in yesterdays post, we can tell jQuery to handle the response from an Ajax call as html. More than that, we can use jQuery to create a DOM element for us from the returned html, and drop it anywhere in our document. The following JavaScript function accomplishes both:

function AddTask()
{
    var name = $("#newtask_name").attr("value");
    var due = $("#newtask_due").attr("value");
    var desc = $("#newtask_desc").attr("value");
 
    $.ajax(
    {
       type: "POST",
       url: "/Tasks/New",
       data: "name=" + name + "&due=" + due + "&desc= "+ desc,
       dataType: "html",
       success: function(result)
       {
            var domElement = $(result); // create element from html
            $("#task_list").append(domElement); // append to end of list        
       }
    });        
}

 

Here, we're making an Ajax call to the New action on the Tasks controller. We then create a new DOM element from the resulting html that it renders, and append it to the task list. And that's it! When the user adds a task, the following POST is sent:

Post

The following response is received from the server, which we append to the task list:

Response

If you want to take a look at a working example, you can download the project I used to demo this here.

Note: For some reason, the Ajax calls are quite slow (~1 sec) when running the demo using Visual Studio's built-in development server. Publish the site to IIS however, and things are blazingly fast (as you can see from the screenshots above) :)

Currently rated 5.0 by 7 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Comments

Powered by BlogEngine.NET 1.4.5.0

Welcome!

My name is Fredrik Kalseth, and this is my blog - thanks for visiting! I am fortunate enough to work with what I love for a living, and this blog is essentially the biproduct of that.

I work as a senior consultant for Capgemini, and am also an active participant in the Norwegian .NET community, as an avid attendee but also as a speaker (most recently at NNUG and MSDN Live).

As a developer, I have a wide circle of interest. My primary passion is for agile, test-driven development, with focus on best practices and clean code. That said, I also love to work on the frontend, especially with web development.

On Twitter? My handle is fkalseth. On LinkedIn? I`m there too.

Disclaimer

This is a personal blog; any opinions expressed here are my own and do not necessarily reflect those of my employer. All content herein is my own original creation, and as such is protected by copyright law. Unless otherwise stated, all source code posted on this blog is freely usable under the Microsoft Permissive License.

What Readers Talk About

Comment RSS