Need to simulate an @Html.action() on a button click

629 Views Asked by At

I'm having some issues with updating a partial view in my index view. Basically, based on a click, I would like to have updated information.

    //controller
    public ActionResult Index()
    {
        var filteredObservations = getFilteredObservationSessions().ToList();
        var observationManagementVm = new ObservationManagementVM(filteredObservations);

        return View(observationManagementVm);
    }

    public ActionResult indexPagedSummaries(int? page, List<ObservationSessionModel> data)
    {
        var alreadyFilteredObservations = data;
        int PageSize = 10;
        int PageNumber = (page ?? 1);

        return PartialView(alreadyFilteredObservations.ToPagedList(PageNumber, PageSize));
    }

My main view

//index.cshtml
@model AF.Web.ViewModels.ObservationManagementVM
....
<div id="testsim">
  @Html.Action("indexPagedSummaries", new { data = Model.ObservationSessions })
</div>
<input id="new-view" value="Sessions" type="button" />

<script>
$("#new-view").click(function() {
   $.ajax({
     type: "GET",
     data: { data: "@Model.FeedBackSessions" },
     url: '@Url.Action("indexPagedSummaries")',
     cache: false,
     async: true,
     success: function (result) {
     console.log(result);
       $('#testsim').html(result);
       $('#testsim').show();
      }
  });
});
</script>
....

And my partial view

//indexPagedSummaries.cshtml
@model PagedList.IPagedList<AF.Services.Observations.ObservationSessionModel>
@using (Html.BeginForm("indexPagedSummaries"))
{

    <ol class="vList vList_md js-filterItems">
        @foreach (var item in Model)
        {
            @Html.DisplayFor(modelItem => item)
        }
    </ol>
    <div>
        Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount

        @Html.PagedListPager(Model, page => Url.Action("Index",
                                new { page }))
    </div>
}

Html.Action() returns what I want perfectly, but it doesn't seem to be able to be triggered by a button click.

So, I'm not getting any errors, but the url doesn't give any data back. When I try to run the Observation/indexPagedSummary url without passing in data, I get a System.ArgumentNullException error, so I'm assuming that something is being transferred to the view model. Any help would be so appreciated.

2

There are 2 best solutions below

3
On

Have not run your code but I believe it is because you are not sending the data along with the @Url.Action

Main View:

//index.cshtml
@model AF.Web.ViewModels.ObservationManagementVM
....
<div id="testsim">
  @Html.Action("indexPagedSummaries", new { data = Model.ObservationSessions })
</div>
<input id="new-view" value="Sessions" type="button" />

<script>
$("#new-view").click(function() {
   $.ajax({
     type: "GET",
     data: { data: "@Model.FeedBackSessions" },
     url: '@Url.Action("indexPagedSummaries", "[Controller Name]", new { data = Model.ObservationSessions})',
     cache: false,
     async: true,
     success: function (result) {
     console.log(result);
       $('#testsim').html(result);
       $('#testsim').show();
      }
  });
});
</script>

If that doesn't help I have had issues when I have had a content-type mismatch or a datatype mismatch. You may need to add those to you ajax request.

0
On

Change your ajax data line to this:

data: { data: JSON.stringify(@Model.FeedBackSessions) },

You may also need to add these lines to the ajax:

dataType: 'json',
contentType: 'application/json; charset=utf-8',

You can see in one of your comments above that the current URL is being formed with a description of the List Object, rather than the contents of it:

http://localhost:60985/Observation/indexPagedSummaries?data=System.Collections.Generic.List%601%5BAF.Services.Observations.ObservationSessionModel%5D&data=System.Collections.Generic.List%601%5BAF.Services.Observations.ObservationSessionModel%5D&_=1482453264080

I'm not sure if there's a better way, but you may even have to manually get the model data into Javascript before posting it.

eg:

<script> 
    var temp = [];

    @foreach (var item in Model.FeedBackSessions){
        @:temp.push(@item);
    }
</script>

and then data: { data: JSON.stringify(temp) },