That's because you are mixing Http POSTs and GETs.
You are POSTing data to a form, creating a model from it, chucking it into TempData and returning the view.
Then, you have links (GET) to go to a page with a query string for your page number.... at no point in time does your DisplayPost(DisplayFilterViewModel filter) execute again
Normally this sort of thing is all done with GETs especially because your form data is just filters and it can easily be put into a query string. The other problem with this implementation is that you are putting everything into TempData and then using that in your child action to render data. This is not a very good way to work with MVC. It's also worth nothing that TempData should only ever be used when you are redirecting ... this is the sole reason it exists. Since you are not redirecting, if you want to continue down this path, you should use ViewData.
Here's what you should do:
Your form should be a GET not a POST
You should have a single ChildAction to display your paged data, it could accept a DisplayFilterViewModel as a parameter if your query string parameters can bind to that model, or you can bind each query string valu as individual parameters (this is standard ASP.Net MVC)
You'd then have your normal filtering logic and return a partial view with your model
public ActionResult DisplayGet(DisplayFilterViewModel filter)
{
var category = filter.Category + "";
var keyword = filter.Keyword + "";
var from = new DateTime(1753, 1, 1);
var to = DateTime.MaxValue;
if (filter.FromDate.HasValue)
from = (DateTime)filter.FromDate;
if (filter.ToDate.HasValue)
from = (DateTime)filter.ToDate;
var model = _foiQuestionService.GetFoiQuestions(category, keyword, from, to)
.Select(s => new DisplayViewModel()
{
Id = s.Id,
FileRef = s.Foi.FileRef,
Question = s.Question,
DateRequestReceived = s.Foi.DateRequestReceived
}).ToList();
return PartialView("~/Views/Partials/Foi/DisplayFoi.cshtml", model);
}
It returns the partialview back to a blank page. This is where I stumbled when I first looked at this, and is why I ended up coming across the tempdata, solution?
I'm assuming you are sending your form to the DisplayGet action?
Let me try to explain what is happening as there's clearly a bit of confusion as to what is happening.
Umbraco renders your page
Inside of this page you have a form which gets sent to a SurfaceController action (either by a GET or a POST)
This MVC Action is executed, just like any normal ASP.Net MVC action
In this action you are currently returning return PartialView("~/Views/Partials/Foi/DisplayFoi.cshtml", model). ... which is doing exactly what it says: it's returning a partial view ... and this is outside of the Umbraco pipeline, this is the exact same thing that would happen if you created a normal ASP.Net MVC app, sent your data to an Action and just returned a partial view
When you return anything from a SurfaceController action that you are sending form data to, you need to either return CurrentUmbracoPage() or RedirectToCurrentUmbracoPage().
This is simply going to reload your page with the form values as query strings.
Then all you need to do is have the logic in your ChildAction that looks up your content and displays it. For what you are doing, there's not need for a Controller Action to handle your form request, all you want is for the form to populate the query strings.
Cool, just keep in mind that the links sent are about POSTing data to forms whereas your implementation doesn't require that since it's just a filter based on query strings
MVC partial view filter problems???
I'm still trying to get my head around mvc implementation in Umbraco but currently stuck on a problem.
I have a template with two Html.Action partial views.
The first will shows the results from a filter http://www.merthyr.gov.uk/council/data-protection-and-freedom-of-information/disclosure-log
The second is a side filter.
If i select a filter value from years ago which generates enough results for the pagination to kick it all works.
Once I select to move to the next page, it doesn't work.
That's because you are mixing Http POSTs and GETs.
DisplayPost(DisplayFilterViewModel filter)
execute againNormally this sort of thing is all done with GETs especially because your form data is just filters and it can easily be put into a query string. The other problem with this implementation is that you are putting everything into TempData and then using that in your child action to render data. This is not a very good way to work with MVC. It's also worth nothing that TempData should only ever be used when you are redirecting ... this is the sole reason it exists. Since you are not redirecting, if you want to continue down this path, you should use ViewData.
Here's what you should do:
Hi Shannon,
Thanks for getting back to me on this. I don't think my example shows but I use the same page for showing the item detail e.g
Based on this, will your solution still work?
That would work fine, all you are doing is out-putting a different partial view/model based on what is in your query strings.
Thanks Shannon,
Will give this a try in the morning.
Hi Shannon,
When I do this
It returns the partialview back to a blank page. This is where I stumbled when I first looked at this, and is why I ended up coming across the tempdata, solution?
My current view that displays, the filter, summary and detail
I'm assuming you are sending your form to the
DisplayGet
action?Let me try to explain what is happening as there's clearly a bit of confusion as to what is happening.
return PartialView("~/Views/Partials/Foi/DisplayFoi.cshtml", model)
. ... which is doing exactly what it says: it's returning a partial view ... and this is outside of the Umbraco pipeline, this is the exact same thing that would happen if you created a normal ASP.Net MVC app, sent your data to an Action and just returned a partial viewWhen you return anything from a SurfaceController action that you are sending form data to, you need to either
return CurrentUmbracoPage()
orRedirectToCurrentUmbracoPage()
.TempData is used only for redirecting.
Have you read this? It explains in detail the routing process: https://our.umbraco.org/documentation/reference/Templating/Mvc/forms
yes, I'm sending the form to DisplayGet.
It feels like I should be looking for return CurrentUmbracoPage(model)
I need to return the view but with the current page.
Just looking at the link you sent :)
The link and examples should help you understand the process a little more.
In the meantime, here's where your implementation is incorrect:
You don't need to send data anywhere, your html form doesn't even need to be an Umbraco form. It could literally just be:
<form action="@Request.Url.AbsolutePath" method="GET">
This is simply going to reload your page with the form values as query strings.
Then all you need to do is have the logic in your ChildAction that looks up your content and displays it. For what you are doing, there's not need for a Controller Action to handle your form request, all you want is for the form to populate the query strings.
Thanks Shannon,
This seems to be the solution. I'm going to read over the links you've sent so that I completely understand the process tomorrow.
Really appreciate the help.
Cool, just keep in mind that the links sent are about POSTing data to forms whereas your implementation doesn't require that since it's just a filter based on query strings
is working on a reply...