0

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>
Chris V.
  • 1,123
  • 5
  • 22
  • 50
  • 1
    this is wrong ``$("#SamplingEventDetails").html(data)`` this element will come with partial and currently it is not on page – Ehsan Sajjad May 30 '14 at 19:02
  • make a container div and load html in that – Ehsan Sajjad May 30 '14 at 19:02
  • You want to convert the partial to a string then return it (I usually return JSON and have the string under a property called "html").This post should help you [convert-partialview-to-html](http://stackoverflow.com/questions/18343378/convert-partialview-to-html) – Ballbin May 30 '14 at 19:08
  • It seems the partial views in these examples depend upon a model, which I don't have. I'm just sending a string through the ViewBag. – Chris V. May 30 '14 at 19:37
  • Also, let's assume I just want the script to pass the value to the action method and then let that action method take over from there. Is *that* possible? – Chris V. May 30 '14 at 19:44

2 Answers2

1

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" />
  }
Priyanka Jain
  • 317
  • 1
  • 7
magos
  • 3,371
  • 4
  • 29
  • 54
1

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>
xDaevax
  • 2,012
  • 2
  • 25
  • 36
  • Isn't this what I'm already doing, minus trying to use the HTML helper method RenderPartial in the main view div? – Chris V. May 30 '14 at 19:51
  • Your first div would be what "SampleListDiv" is in my original post. Your second div I already have in my partial view. The third part I have as the last part of my script. I think the part I'm not getting is how to return the data from the action method via the script call. – Chris V. May 30 '14 at 19:52
  • Do you have data in your partial by default and need to render it on page load? Also, because the SamplingEventDetailsDiv is your target, you will likely wind up nesting your partial within itself at each call. Since the value of "data" in your ajax call is HTML markup, not the actual string value. – xDaevax May 30 '14 at 19:57
  • No there is no data in it by default. Right now it's just as in your response - "@ViewBag.Selected" is the only content. – Chris V. May 30 '14 at 20:00
  • Maybe it would help if I stated what I'm ultimately trying to do. Eventually I'll use the value posted by the script to perform another query, then pass those results through to the partial view, and the partial view in the main page should be updated. Right now I'm just passing the selected value through to be sure I can get data to and from the action method and update the partial view accordingly. – Chris V. May 30 '14 at 20:06
  • Remember, your action method as you currently have it is not returning just the data, it is returning all of the HTML of the partial, so nothing will be "passed" to the partial view that you rendered on the first page load. Your action method and ajax call literally return a full set of HTML markup that replace the HTML contents of whichever target you have in your JQuery. We could continue this in chat if you like. – xDaevax May 30 '14 at 20:08
  • That worked man, thanks! Appreciate your patience! :) Now to make it work with something more complex than a string. I don't think I need the partial view this way though -- I only had it before because I thought I could pass the data to it through the ViewBag. If it's just a div I can just put that in place of the @Html.Partial() portion. – Chris V. May 30 '14 at 21:05