First of all, it's ridiculous how you have to sign in to your live account before logging into yet another account in order to simply log in to the forums. Anyway, that's irrelevant to the real issue at hand.
I have a view that has input fields for searching for customer orders. A have a button to execute this search which invokes an actionresult method in the controller for this view.
What i want is the results to be displayed below these input fields on the same page. My idea of solving this (with little practical experience of asp.net mvc) was to have the actionresult method return a partial view and also have the "main" view take use
of this partial view by the html.renderpartial method. well, the result is i get a partial view only rendered and the main view with the input fields etc disappears.
I get that my way of thinking may have not been very logical, but really how do you solve this very simple task of updating a partial view only of a main page?
(1) If you are performing a simple query operation which does not alter any data (like a search), you'd want to use a HTTP GET on your action rather than a HTTP POST.
(2) You will need to call the action asynchronously using ajax if you only want to display/update the search results section of your view. Your action can check whether it is an async request (Request.IsAjaxRequest()) and then return the partial view. If
it is not an ajax request, you can return the entire view as a normal HTTP GET request. You will need to have your view make an async request when the submit/search button is clicked.
i understand that i would need to use ajax for updating only a part of the page. perhaps i wasn't very clear on what i'm after.
i'm perfectly fine with updating the entire page. i'm planning on adding ajax functionality later on and would first like to make it work with javascript disabled.
i'm simply wondering what the cleanest and most appropriate way is to return the order information to the original page.
for instance, i could use the main page and have some sort of <% if (ViewData["orders"] != null) { %> bunch of order data <% } %>
however, i don't feel like that solution is very clean at all. i would much rather be able to split the content into different partial views. perhaps one partial view for the input fields and one for the search results and have them both displayed on the
same page, and just simply be able to send the search result data to that specific partial view.
You would need to put everything you need in the model (input field values + search results) and then use them in the view. You could pass the input field values portion of the model to one partial view and the search results to another partial view as you
have said.
The renderpartial method takes a second argument which could contain whatever model data you want to pass to it.
so that "solution" is what i mentioned being not a very clean one earlier with the whole if statement and everything.
so basically the controller method PartialView which returns a PartialViewResult is totally pointless in its existance unless you are using some asynchronous method such as ajax to call it?
that makes little sense to me. at least the naming of the method cause it kind of implies it's usage is more broad than that.
this all seems very suspicious to me still. what if you have a bunch of random unrelated widgets on your page. you click on a link that shows you some info, still with the widgets and everything there. what you're saying then is i would still have to pack
all the unrelated data for all the widgets and the new content i want to show in the model and then run a bunch of checks for each widget to see if the data for the widget is there and if so, pass it down to it with the renderpartial and if not, skip it.
i'm hoping i just don't have the right overall idea of how it all works because this feels messy.
Partial views are just reusable blocks of markup. You don't have to use them in combination with ajax (although this is useful). You can just use them when you need to reuse the same portion of a view template more than once.
A view can only deal with a single model so the controller has to give it all the information it needs to display whatever it needs to. The decision making in the view should be simple. So for example, the view model the controller gives to the view can
contain flags to indicate to the view whether it should show something. The view would still have to use this information to decide what to show.
Note also that you can store information in ViewData, so the strongly typed view model doesn't necessarily have to contain EVERYTHING that is needed for all "widgets", just information that is specific to the current view.
You're right - what you're describing IS messy. Now, if you're using good OOP, then there is nothing messy about how you pass things around. I've seen people trick out there classes to support things like dropdowns, and other controls, but they're generally
missing the point.
A good place where controllers come in handy is when you have built partial controlls based on your objects - Let's say you have a couple of biz object that share a relationship Customer/order
You build a controller for Customer and Order. Each of these controllers has an Index & Edit page. Inside each of these pages, there is a reference to a Edit & List control. You can now take your OrderListControl and add it to the Customer/Edit page.
Your Client/Edit page takes in your Client object, which you pass to your Client Edit control.
You then pass your orders to the orders list control via your Parent/Child relationship to the Client/Orders. On your page it would be renderPartial("../Orders/List", Model.Orders)
If you're doing something rather exotic, you can always create a helper class which brings together many unrelated objects that you can pass around. I started down this road, but was able to step away from that once I started using the method I described
above.
So my Edit page content panel looks like this (note the call to the child objects)...
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Ltrs.Data.xFuture>" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>
<% using (Html.BeginForm(ViewData["Action"].ToString(), ViewData["Controller"].ToString(), FormMethod.Post, new { id = "formSubmit" }))
{
Html.RenderPartial(ViewData["Controller"].ToString(), Model);
} %>
<div>
<%=Html.ActionLink("Back to List", "Index") %>
</div>
</asp:Content>
thank you both very much for taking the time helping me out!
Pikesville, thanks. your mention of viewmodel user controls made me change approach. i'm going through your example and hopefully will be able to get something good going for my project.
i also took the time to read through ASP.NET MVC In Action (Manning) and it has given me some new insight. for anyone struggling with views and partial views i can especially recommend reading chapter 4 and 7.2 (haven't gotten further than chapter 7 which
is about halfway through the book so i'm sure it'll have even more helpful things to offer as well).
You're quite welcome, please remember to mark as answer as my profile could use the boost!
Also, I've a small project out on code plex that tackles a few of these such issues. It's my first end-to-end mvc project and I've improved my approach somewhat in the weeks that have followed, but you should find plenty of helpful nuggets in there.
http://mvctaskmanagement.codeplex.com/
Good luck!
Remember to mark as a answer if it helps, and to help someone else in kind...
You haven't had a beer until you've learned how to make your own...
You're quite welcome, please remember to mark as answer as my profile could use the boost!
Also, I've a small project out on code plex that tackles a few of these such issues. It's my first end-to-end mvc project and I've improved my approach somewhat in the weeks that have followed, but you should find plenty of helpful nuggets in there.
http://mvctaskmanagement.codeplex.com/
Good luck!
Remember to mark as a answer if it helps, and to help someone else in kind...
You haven't had a beer until you've learned how to make your own...
cherrynoise
Member
1 Points
4 Posts
How do I return/update a partial view inside another view?
Sep 22, 2009 08:42 AM|LINK
First of all, it's ridiculous how you have to sign in to your live account before logging into yet another account in order to simply log in to the forums. Anyway, that's irrelevant to the real issue at hand.
I have a view that has input fields for searching for customer orders. A have a button to execute this search which invokes an actionresult method in the controller for this view.
What i want is the results to be displayed below these input fields on the same page. My idea of solving this (with little practical experience of asp.net mvc) was to have the actionresult method return a partial view and also have the "main" view take use of this partial view by the html.renderpartial method. well, the result is i get a partial view only rendered and the main view with the input fields etc disappears.
I get that my way of thinking may have not been very logical, but really how do you solve this very simple task of updating a partial view only of a main page?
Any input much appreciated!
From Invoice/Generate.aspx <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<OrderDto>" %> <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> Generera fakturaunderlag </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2>Generate orders</h2> <form action="Generate" method="post"> <fieldset> <label for="customerNumber">Customer number:</label> <input type="text" name="customerNumber" id="customerNumber" /> <label for="startDate">Start date:</label> <input type="text" name="startDate" id="startDate" /> <label for="endDate">End Date:</label> <input type="text" name="endDate" id="endDate" /> <input type="submit" name="searchButton" id="searchButton" value="Search" /> </fieldset> </form> <% Html.RenderPartial("Orders"); %> </asp:Content> From InvoiceController.cs [AcceptVerbs(HttpVerbs.Post)] public ActionResult Generate(string customerNumber, string startDate, string endDate) { return PartialView("Orders"); }hasselhoss
Participant
1201 Points
174 Posts
Re: How do I return/update a partial view inside another view?
Sep 22, 2009 10:09 AM|LINK
A few things to be aware of.
(1) If you are performing a simple query operation which does not alter any data (like a search), you'd want to use a HTTP GET on your action rather than a HTTP POST.
(2) You will need to call the action asynchronously using ajax if you only want to display/update the search results section of your view. Your action can check whether it is an async request (Request.IsAjaxRequest()) and then return the partial view. If it is not an ajax request, you can return the entire view as a normal HTTP GET request. You will need to have your view make an async request when the submit/search button is clicked.
Here's a tutorial that discusses this but you can find many others: http://www.asp.net/learn/mvc/tutorial-32-cs.aspx
cherrynoise
Member
1 Points
4 Posts
Re: How do I return/update a partial view inside another view?
Sep 22, 2009 10:33 AM|LINK
thanks for the reply.
i understand that i would need to use ajax for updating only a part of the page. perhaps i wasn't very clear on what i'm after.
i'm perfectly fine with updating the entire page. i'm planning on adding ajax functionality later on and would first like to make it work with javascript disabled.
i'm simply wondering what the cleanest and most appropriate way is to return the order information to the original page.
for instance, i could use the main page and have some sort of <% if (ViewData["orders"] != null) { %> bunch of order data <% } %>
however, i don't feel like that solution is very clean at all. i would much rather be able to split the content into different partial views. perhaps one partial view for the input fields and one for the search results and have them both displayed on the same page, and just simply be able to send the search result data to that specific partial view.
what am i missing?
hasselhoss
Participant
1201 Points
174 Posts
Re: How do I return/update a partial view inside another view?
Sep 22, 2009 10:51 AM|LINK
Sorry if I misunderstood.
You would need to put everything you need in the model (input field values + search results) and then use them in the view. You could pass the input field values portion of the model to one partial view and the search results to another partial view as you have said.
The renderpartial method takes a second argument which could contain whatever model data you want to pass to it.
RenderPartial("PartialViewName1", Model.SearchResults)
RenderPartial("PartialViewName2", Model.InputFieldValues)
So your action would just need to construct the Model and return the view as normal:
Return View("ViewName", New YourViewModel(inputFieldValues, searchResults))
cherrynoise
Member
1 Points
4 Posts
Re: How do I return/update a partial view inside another view?
Sep 22, 2009 11:11 AM|LINK
thanks once again.
so that "solution" is what i mentioned being not a very clean one earlier with the whole if statement and everything.
so basically the controller method PartialView which returns a PartialViewResult is totally pointless in its existance unless you are using some asynchronous method such as ajax to call it?
that makes little sense to me. at least the naming of the method cause it kind of implies it's usage is more broad than that.
this all seems very suspicious to me still. what if you have a bunch of random unrelated widgets on your page. you click on a link that shows you some info, still with the widgets and everything there. what you're saying then is i would still have to pack all the unrelated data for all the widgets and the new content i want to show in the model and then run a bunch of checks for each widget to see if the data for the widget is there and if so, pass it down to it with the renderpartial and if not, skip it.
i'm hoping i just don't have the right overall idea of how it all works because this feels messy.
hasselhoss
Participant
1201 Points
174 Posts
Re: How do I return/update a partial view inside another view?
Sep 23, 2009 12:12 AM|LINK
Partial views are just reusable blocks of markup. You don't have to use them in combination with ajax (although this is useful). You can just use them when you need to reuse the same portion of a view template more than once.
A view can only deal with a single model so the controller has to give it all the information it needs to display whatever it needs to. The decision making in the view should be simple. So for example, the view model the controller gives to the view can contain flags to indicate to the view whether it should show something. The view would still have to use this information to decide what to show.
Note also that you can store information in ViewData, so the strongly typed view model doesn't necessarily have to contain EVERYTHING that is needed for all "widgets", just information that is specific to the current view.
Pikesville P...
Participant
1036 Points
197 Posts
Re: How do I return/update a partial view inside another view?
Sep 23, 2009 02:42 AM|LINK
You're right - what you're describing IS messy. Now, if you're using good OOP, then there is nothing messy about how you pass things around. I've seen people trick out there classes to support things like dropdowns, and other controls, but they're generally missing the point.
A good place where controllers come in handy is when you have built partial controlls based on your objects - Let's say you have a couple of biz object that share a relationship Customer/order
You build a controller for Customer and Order. Each of these controllers has an Index & Edit page. Inside each of these pages, there is a reference to a Edit & List control. You can now take your OrderListControl and add it to the Customer/Edit page.
Your Client/Edit page takes in your Client object, which you pass to your Client Edit control.
You then pass your orders to the orders list control via your Parent/Child relationship to the Client/Orders. On your page it would be renderPartial("../Orders/List", Model.Orders)
If you're doing something rather exotic, you can always create a helper class which brings together many unrelated objects that you can pass around. I started down this road, but was able to step away from that once I started using the method I described above.
So my Edit page content panel looks like this (note the call to the child objects)...
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Ltrs.Data.xFuture>" %> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %> <% using (Html.BeginForm(ViewData["Action"].ToString(), ViewData["Controller"].ToString(), FormMethod.Post, new { id = "formSubmit" })) { Html.RenderPartial(ViewData["Controller"].ToString(), Model); } %> <div> <%=Html.ActionLink("Back to List", "Index") %> </div> </asp:Content>My user control looks like this...
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Ltrs.Data.xFuture>" %> <%@ Import Namespace="Ltrs.Data.Models" %> <div id="errorMsg" class="errorMessage"> <ul></ul> </div> <% Html.RenderPartial("Request", Model.GetRequest(Model.RequestType)); %> <table width="725px"> <tr> <td><%= Html.LabelFor(x => x.ViprsCaseNumber)%><%= Html.ValidationMessage("ViprsCaseNumber", "*")%></td> <td><%= Html.EditorFor(x => x.ViprsCaseNumber, "Textbox")%></td> <td><%= Html.LabelFor(x => x.AccountTypeCode)%><%= Html.ValidationMessage("AccountTypeCode", "*")%></td> <td><%=Html.DropDownList("AccountTypeId", (SelectList)ViewData["AccountType"])%></td> </tr> <tr> <td><%= Html.LabelFor(x => x.ReceiptNumber)%> <%= Html.ValidationMessage("ReceiptNumber", "*")%></td> <td><%= Html.EditorFor(x => x.ReceiptNumber)%></td> <td><%= Html.LabelFor(x => x.ReceiptDate)%> <%= Html.ValidationMessage("ReceiptDate", "*")%></td> <td><%= Html.EditorFor(x => x.ReceiptDate)%></td> <td><%= Html.LabelFor(x => x.ReceiptAmount)%><%= Html.ValidationMessage("ReceiptAmount", "*")%></td> <td><%= Html.EditorFor(x => x.ReceiptAmount)%></td> </tr> </table> <% if (Roles.IsUserInRole("Local User")) { Html.RenderPartial("../Comment/Comment", new Ltrs.Data.Comment { RequestId= Model.Id, CommentTypeCode=Ltrs.Data.CommentType.Type.Local.ToString(), CommentTypeId=Ltrs.Data.CommentType.Type.Local.GetHashCode(), CommentDate=DateTime.Now}); %><input type="submit" value="Save" /><% } if (Model.LocalComments != null && Model.LocalComments.Count > 0) { Html.RenderPartial("../Comment/CommentList", Model.LocalComments.OrderByDescending(x => x.Id)); } else { %> <h3 style="margin-left:300px;">No Local Comments</h3> <%} if (Roles.IsUserInRole("TAD Supervisor")) { Html.RenderPartial("TransactionStatus", Model.Statuses.LastOrDefault()); Html.RenderPartial("../Comment/Comment", new Ltrs.Data.Comment { RequestId = Model.Id, CommentTypeCode = Ltrs.Data.CommentType.Type.Tad.ToString(), CommentTypeId = Ltrs.Data.CommentType.Type.Tad.GetHashCode(), CommentDate = DateTime.Now }); } if (Model.TadComments != null && Model.TadComments.Count > 0) { Html.RenderPartial("../Comment/CommentList", Model.TadComments.OrderByDescending(x => x.Id)); } else { %> <h3 style="margin-left:300px;">No TAD Comments</h3> <%}%>and the comments controller is as follows...
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Ltrs.Data.Comment>>" %> <%@ Import Namespace="MvcContrib.UI.Grid" %> <h3> <%=ViewData["Count"]%> </h3> <div id="GridPage" title="GridPage" class="GridPage" > <% Html.Grid(Model).Columns(column => { column.For(x => x.CommentBy).Named("Author"); column.For(x => x.CommentDate == DateTime.MinValue ? "" : x.CommentDate.ToShortDateString()).Named("Comment Date"); column.For(x => x.CommentText).Named("Comment"); column.For(x => x.CommentTypeCode).Named("Comment Type"); }).Attributes(style => "width: 100%;", ID => "tblSearchResults") .Empty("There are no records") .Render(); %> </div> <style type="text/css" title="currentStyle"> @import "<%=Url.Content("~/Content/Themes/datatable.css")%>"; </style> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <script type="text/javascript" src="<%=Url.Content("~/Content/Scripts/jquery/jquery-1.2.6.min.js")%>"></script> <script type="text/javascript" language="javascript" src="<%=Url.Content("~/Content/Scripts/jquery/jquery.dataTables.min.js")%>" ></script> <script type="text/javascript" charset="utf-8"> // put all your jQuery goodness in here. $(document).ready(function() { $('#tblSearchResults').dataTable({ "sPaginationType": "full_numbers" }); }); </script>You haven't had a beer until you've learned how to make your own...
cherrynoise
Member
1 Points
4 Posts
Re: How do I return/update a partial view inside another view?
Sep 24, 2009 10:05 AM|LINK
thank you both very much for taking the time helping me out!
Pikesville, thanks. your mention of viewmodel user controls made me change approach. i'm going through your example and hopefully will be able to get something good going for my project.
i also took the time to read through ASP.NET MVC In Action (Manning) and it has given me some new insight. for anyone struggling with views and partial views i can especially recommend reading chapter 4 and 7.2 (haven't gotten further than chapter 7 which is about halfway through the book so i'm sure it'll have even more helpful things to offer as well).
thanks once again!
Pikesville P...
Participant
1036 Points
197 Posts
Re: How do I return/update a partial view inside another view?
Sep 24, 2009 01:21 PM|LINK
You're quite welcome, please remember to mark as answer as my profile could use the boost!
Also, I've a small project out on code plex that tackles a few of these such issues. It's my first end-to-end mvc project and I've improved my approach somewhat in the weeks that have followed, but you should find plenty of helpful nuggets in there.
http://mvctaskmanagement.codeplex.com/
Good luck!
You haven't had a beer until you've learned how to make your own...
Pikesville P...
Participant
1036 Points
197 Posts
Re: How do I return/update a partial view inside another view?
Sep 24, 2009 01:21 PM|LINK
You're quite welcome, please remember to mark as answer as my profile could use the boost!
Also, I've a small project out on code plex that tackles a few of these such issues. It's my first end-to-end mvc project and I've improved my approach somewhat in the weeks that have followed, but you should find plenty of helpful nuggets in there.
http://mvctaskmanagement.codeplex.com/
Good luck!
You haven't had a beer until you've learned how to make your own...