How to update only part of the index page in MVC 5?

The Index page contains two partial views. One of them is that the user enters search criteria, and the other - to display the results. How do I refresh data only in the Results view?

I am using MVC 5 and Razor. I saw several examples of this, mostly using ajax and jquery. I ask what would be the best (preferred) solution for this

// INDEX VIEW:

<div id="div_Search"> @{Html.RenderPartial("~/Views/Shared/Search.cshtml", ViewBag.Model_Search );} </div> <div id="div_Results"> @{Html.RenderPartial("~/Views/Shared/Results.cshtml", ViewBag.Model_Results );} </div> // HOME CONTROLLER 

public class HomeController: controller {MainContextDB db = new MainContextDB ();

 public ActionResult Index() { // Code to initialize ViewBag.Model_Search, etc... .... // Code to initialize ViewBag.Model_Results, etc... (Values empty at startup) .... return View(); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult GetResults([Bind(Include = "DropOffLoc,DropOffDate,PickUpDate")] Search search) { // Retrieve results using the search parameters, etc... .... // THIS RETURNS THE VIEW WITH THE DATA, BUT IN A SEPARATE PAGE (AS EXPECTED) return View("~/Views/Shared/Results.cshtml", results); // THIS RETURNS THE VIEW IN THE MAIN PAGE BUT WITH EMPTY DATA (AS EXPECTED) return RedirectToAction("Index"); // HOW TO RETURN THE VIEW WITH THE DATA IN THE MAIN PAGE ? ??????? } 

}

// THIS SEARCH PARTIAL VIEW

 @model Models.Results @using (Html.BeginForm("GetResults", "Home", FormMethod.Post, new { @class = "my-form" })) { @Html.AntiForgeryToken() @Html.ValidationSummary(true) <div class="form-group input-group-sm"> @Html.LabelFor(model => model.DropOffLoc) @Html.DropDownListFor(model => model.DropOffLoc, ViewBag.LocationList as SelectList, new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.DropOffLoc) </div> <div class="form-group input-group-sm"> @Html.LabelFor(model => model.DropOffDate) @Html.TextBoxFor(model => model.DropOffDate, new { @class = "form-control datepicker", placeholder = "Enter Drop-off date here..." }) @Html.ValidationMessageFor(model => model.DropOffDate) </div> <div class="form-group input-group-sm"> @Html.LabelFor(model => model.PickUpDate) @Html.TextBoxFor(model => model.PickUpDate, new { @class = "form-control datepicker", placeholder = "Enter Pick-up date here..." }) @Html.ValidationMessageFor(model => model.PickUpDate) </div> <div style="text-align: center; margin-top: 10px; margin-bottom: 10px;"> <input type="submit" id="getResults" value="GET RESULTS" class="btn btn-default btn-success" /> </div> } 
+6
source share
3 answers

I would put the form in your search partially. Then add the action message, which through jQuery, to your GetResults action, which should return:

 return PartialView("~/Views/Shared/Results.cshtml", results); 

Then, in the success callback to your jQuery message, return the results to your $ ("# div_Results") like this:

 $.ajax({ url: '/Home/GetResults', type: "POST", dataType: "html", data: $("#FormId").serialize(), success: function (data) { //Fill div with results $("#div_Results").html(data); }, error: function () { alert('error'); } }); 

If I don't have a typo or anything else, this should work. You will need to replace the form selector with the form tag identifier.

+14
source

although this question already has an answer, I thought I would post an alternative approach that would also work. This approach uses the same action method and only checks if the request is an Ajax call, which then replaces only the body part. Here are just the relevant code.

// Search Form

  @using (Ajax.BeginForm("Index", "Home", new AjaxOptions() { HttpMethod = "GET", UpdateTargetId = "my-posts", InsertionMode = InsertionMode.Replace })) { <input type="text" name="term" placeholder="Search BI & G" /> <input type="submit" value="" /> } 

// Presentation portion

 <section> <div id="my-posts"> @Html.Partial("_Posts", Model.Posts) </div> 

Now here is the index action method, if Request is AjaxRequest, it returns a Partial View, which replaces the contents of the div id my-posts. If the request is not an Ajax request, it loads the entire View.

  public async Task<ActionResult> Index(string term) { var viewModel = new HomeFeedsViewModel(); viewModel.Posts = await Task.Run(() => db.Posts.Include("Comments") .Include("By").OrderByDescending(o => o.PostedOn) .ToList()); //Return a Partial View which replaces content on the View //only if the Request is an Ajax Request if (Request.IsAjaxRequest()) { viewModel.Posts = viewModel.Posts .Where(a => a.Title.IndexOf(term, StringComparison.OrdinalIgnoreCase) >= 0 || a.Message.IndexOf(term, StringComparison.OrdinalIgnoreCase) >= 0 ); return PartialView("_Posts", viewModel.Posts); } return View(viewModel); } 

Hope this helps someone.

+5
source

You will essentially need to use AJAX.

The best approach, as I see it, is to have a partial view and give it an AJAX Load (jQuery.load in jQuery).

+3
source

All Articles