Reputation: 1143
I'm working on a single page web app. The page has a dropdown list. When an item is selected, I use jQuery to post the selected value to an action method, which [for now, for testing purposes] adds that value to the ViewBag, and returns a PartialView. I want to put this partial view in the same page, obviously. So when I select a value from the dropdown, the selected option should show up below it. Is this possible or am I approaching this the wrong way?
Relevant code for context:
Index (Main page)
<html>
@using SampleTracking.Models.ViewModels;
@model SamplingEventsVM
<head>
<title>@ViewBag.Title</title>
<script src="~/Scripts/jquery-2.1.1.js"></script>
<script type="text/javascript" src="~/Scripts/CustomScripts.js"></script>
</head>
<body>
<span id="SamplingEventDiv">
@Html.DropDownListFor(model => model.SelectedSamplingEvent, Model.SamplingEvents, new { @id = "SamplingEventSelection" })
</span>
<div id="SampleListDiv">
@{Html.RenderPartial("~/Views/Home/RetrieveSamples.cshtml");}
</div>
</body>
</html>
Script
$(function (ready) {
$("#SamplingEventSelection").change(
function () {
$.post(
"/Home/RetrieveSamples",
{ selectedSamplingEvent: $("#SamplingEventSelection").val() },
function (data) {
$("#SamplingEventDetails").html(data)
}
)
}
)
});
Action method script is posting to
public ActionResult RetrieveSamples(string samplingEvent)
{
ViewBag.Selected = samplingEvent;
return PartialView();
}
Partial view
<div id="SamplingEventDetails" style="margin-top:100px;">@ViewBag.Selected</div>
Upvotes: 0
Views: 4710
Reputation: 3511
Yes, it is. You have to use Ajax for that purpose.
There is Ajax.BeginForm
helper. Your view should look like below:
@using (Ajax.BeginForm(new AjaxOptions() { LoadingElementId="loadingPanel", UpdateTargetId = "info", InsertionMode = InsertionMode.InsertBefore, Url = Url.Action("AjaxTest")}))
{
@Html.DropDownList("dropDown1", new SelectList(new[] { "One", "Two", "Three"}));
<br /><br />
<input type="submit" value="Send" />
}
Upvotes: 1
Reputation: 2022
Consider loading only the data instead of the html for a partial view.
Using Ajax requests with MVC is really useful, and you're not limited to partial views either. You can return JSON data as well if you didn't want to return a view.
public ActionResult RetrieveSamples(string samplingEvent) {
JsonResult result = new JsonResult();
result.Data = samplingEvent;
return result;
} // end function RetrieveSamples
Then in your JS:
function (data) {
console.log("Json Data returned: " + data);
$("#SamplingEventDetails").html(data);
}
Edit: Here is a working solution I have:
Controller:
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
List<SelectListItem> items = new List<SelectListItem>();
items.Add(new SelectListItem() { Text = "Option 1", Value = "1" });
items.Add(new SelectListItem() { Text = "Option 2", Value = "2" });
ViewBag.Options = items;
return View("Index");
}
public ActionResult getDetail(string selectedSamplingEvent) {
JsonResult result = new JsonResult();
result.Data = selectedSamplingEvent;
return result;
}
}
}
Full view (Index.cshtml)
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@Html.DropDownList("Options")
<div class="dynamic-wrapper">
@Html.Partial("Details")
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#Options").change(function (e) {
$.post(
"home/getDetail",
{ selectedSamplingEvent: $("#Options").val() },
function (data) {
$("#SamplingEventDetails").html(data);
}
);
});
});
</script>
Partial view:
<div id="SamplingEventDetails"><!-- Data will go here --></div>
Upvotes: 1