InvisiblePanda InvisiblePanda - 1 year ago 337
jQuery Question

Rendering partial view on button click in ASP.NET MVC

The problem I will be describing is very similar to ones I already found (e.g. this post with nearly identical name) but I hope that I can make it into something that is not a duplicate.

I have created a new ASP.NET MVC 5 application in Visual Studio. Then, I defined two model classes:

public class SearchCriterionModel
public string Keyword { get; set; }

public class SearchResultModel
public int Id { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }

Then I created the
as follows:

public class SearchController : Controller
public ActionResult Index()
return View();

public ActionResult DisplaySearchResults()
var model = new List<SearchResultModel>
new SearchResultModel { Id=1, FirstName="Peter", Surname="Pan" },
new SearchResultModel { Id=2, FirstName="Jane", Surname="Doe" }
return PartialView("SearchResults", model);

as well as views
(strongly typed with
as model and template Edit) and
as a partial view with model of type
(template List).

This is the Index view:

@model WebApplication1.Models.SearchCriterionModel

ViewBag.Title = "Index";

@using (Html.BeginForm())

<div class="form-horizontal">
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Keyword, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Keyword, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Keyword, "", new { @class = "text-danger" })

<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="button" id="btnDisplaySearchResults" value="Search" onclick="location.href='@Url.Action("DisplaySearchResults", "SearchController")'" />

@Html.ActionLink("Back to List", "Index")
<div id="searchResults">


As you can see, I added a
below the standard template and edited the button. What I want is to display the partial view
in the
on the bottom, but only after the button is clicked. I have succeeded in showing a partial view there by using
@Html.Partial("SearchResults", ViewBag.MyData)
, but it is rendered when the parent view is loaded for the first time and I set
in the
method already, which is not what I want.

Summary: On clicking the button, I will obtain some
instances (via database access) and then the partial view should be rendered, using this newly obtained data as model. How can I accomplish this? I already seem fail at the first step, that is reacting to the button click with the above code. Right now, I navigate to the URL
, but of course there's nothing there and no code-behind method is called.
In traditional ASP.NET I'd just have added a server-side
handler, set the
for a grid and show the grid. But in MVC I already fail with this simple task...

Update: Changing the button to
I can finally enter the controller method. But naturally since it returns the partial view, it's displayed as the whole page content. So the question is: How do I tell the partial view to be rendered inside a specific
on the client side?

Answer Source

Change the button to

<button id="search">Search</button>

and add the following script

var url = '@Url.Action("DisplaySearchResults", "Search")';
$('#search').click(function() {
  var keyWord = $('#Keyword').val();
  $('#searchResults').load(url, { searchText: keyWord });

and modify the controller method to accept the search text

public ActionResult DisplaySearchResults(string searchText)
  var model = // build list based on parameter searchText
   return PartialView("SearchResults", model);

The jQuery .load method calls your controller method, passing the value of the search text and updates the contents of the <div> with the partial view.

Side note: The use of a <form> tag and @Html.ValidationSummary() and @Html.ValidationMessageFor() are probably not necessary here. Your never returning the Index view so ValidationSummary makes no sense and I assume you want a null search text to return all results, and in any case you do not have any validation attributes for property Keyword so there is nothing to validate.


Based on OP's comments that SearchCriterionModel will contain multiple properties with validation attributes, then the approach would be to include a submit button and handle the forms .submit() event

<input type="submit" value="Search" />

var url = '@Url.Action("DisplaySearchResults", "Search")';
$('form').submit(function() {
  if (!$(this).valid()) { 
    return false; // prevent the ajax call if validation errors
  var form = $(this).serialize();
  $('#searchResults').load(url, form);
  return false; // prevent the default submit action

and the controller method would be

public ActionResult DisplaySearchResults(SearchCriterionModel criteria)
  var model = // build list based on the properties of criteria
  return PartialView("SearchResults", model);
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download