I have a view that dynamically updates depending on user input - here's how it works:
View is rendered with initial data from controller populated with a partial view
When something is clicked, I use retrieve a partial view from an ActionResult from the controller and replace existing data with jQuery
I need a string from the controller for the main view, so I make another call to the controller and retrieve a string.
I want to know if there's a way to get the string I need with the partial view instead of making a separate controller call.
Initial Data:
<!-- This needs to change when the partial is replaced, but it's heavier html
and I don't want to include it in the partial to minimize server calls/data -->
<div class="Location"> </div>
<div class="myContainingDiv">
<!-- This content gets updated -->
#Html.Partial("_MyPartial");
</div>
Partial View:
<div class="something">Model.something</div>
Controller Method (Partial View):
[HttpGet]
public ActionResult _MyPartial(string param1)
{
MyModel model = new MyModel();
// This is dynamic and what I need to get in my main view from the partial view
model.something = "Hi";
return PartialView(model);
}
Controller Method (Return desired string):
public string GetHiString(string param1)
{
return "Hi";
}
JavaScript (Update partial view):
$.post('/Home/_MyPartial', { 'param1': 'Hi' }, function (result) {
$('.something').replaceWith(result);
getOtherThing('Hi');
});
JavaScript (getOtherThing):
$.post('/Home/_GetHiString', { 'param1': 'Hi' }, function (result) {
$('.Location').replaceWith(result);
});
OK, i think that's everything.
Basically I only want to hit the controller once per call. Including the div in the partial view is not an ideal option.
I hit the controller the second time from my main view to get data that can easily be created from an object within the first method and sent down to the partial view.
So, besides including <div class="Location"> in my partial view, is there a way to send the extra information I need to the partial view and retrieve it dynamically from my main view (via JavaScript). Or is there a way to return additional data when I call _MyPartial from my JavaScript?
This is really the last simplification I want to make and i'd really appreciate the help!
You could modify your partial view _MyPartial and it's model to include something hidden within it that you could extract using jQuery:
Partial View
<div class="something">Model.something
<input class="somethingElse" type="hidden" value="#(Model.somethingElse)" />
</div>
Controller Method (Partial View):
[HttpGet]
public ActionResult _MyPartial(string param1)
{
MyModel model = new MyModel();
// This is dynamic and what I need to get in my main view from the partial view
model.something = "Hi";
model.somethingElse = GetHiString(param1);
return PartialView(model);
}
JavaScript (Update partial view)
$.post('/Home/_MyPartial', { 'param1': 'Hi' }, function (result) {
$('.something').replaceWith(result);
$('.Location').html($('.somethingElse').val());
});
Related
Can someone help me understand partial views, forms and posting in ASP.NET Core Razor.
I have a Search.cshtml partial view located in "~/Client/Search" :
#model Web.Pages.Client.SearchModel
#using (Html.BeginForm())
{
<div>
#Html.RadioButtonFor(x => x.searchType, (int)ApplicationCore.Interfaces.SearchType.mobile, new { Name = "SearchType" }) Mobile
#Html.RadioButtonFor(x => x.searchType, (int)ApplicationCore.Interfaces.SearchType.phone, new { Name = "SearchType" }) Phone
#Html.RadioButtonFor(x => x.searchType, (int)ApplicationCore.Interfaces.SearchType.email, new { Name = "SearchType" }) Email
</div>
#Html.TextBoxFor(x => x.searchFilter)
<input type="submit" value="Search"/>
}
With code page Search.cshtml.cs :
public class SearchModel : PageModel
{
public SearchType searchType { get; set; }
public string searchFilter { get; set; }
private readonly IClientService _clientService;
private readonly Infrastructure.Data.DBContext _context;
public SearchModel(Infrastructure.Data.DBContext context, IClientService clientService)
{
_context = context;
_clientService = clientService;
searchFilter = string.Empty;
searchType = SearchType.mobile;
}
public async Task<IActionResult> OnPostAsync()
{
return RedirectToPage("./Index");
}
}
If I load the "~/Client/Search" Partial View directly it loads and on post it correctly fires the OnPosAsync() action.
However if the "~/Client/Search" Partial View is rendered from the "~/Session/CheckIn" parent View :
#await Html.PartialAsync("~/Client/Search", Model._searchModel)
The OnPostAsync() within the "~/Client/Search" Partial View no longer fires.
I have tried all sorts of combinations to define "action", "controller" within the Html.BeginForm in the Partial View, however I can never get the OnPostAsync() within the Partial View to fire.
Any pointers? Read a lot of articles and forum posts however there are no clear descriptions or walkthroughs to help me understand this and get the Partial View action method firing on postback from parent View.
This is why Razor Pages are a blight: they obfuscate logic, allowing people to build stuff without ever actually understanding how any of it works. </rant>
There's nothing special about a partial view. It's just a view like any other view. What makes it "partial" is the context in which it's used, i.e. injecting it into the rendering of a view. As such, Razor Pages lets you add a code-behind, because it's just a view, and any view can have a Razor Pages code-behind. However, when used like a partial, that code-behind is not actually utilized, and there's your problem.
Also, you need to bear in mind that the whole concept of partial views only exists server-side. Once the response has been returned, all you have is just an HTML document. The browser couldn't care less whether you used one partial view, 100 partial views or no partial views to create the response server-side. As such, using a partial doesn't somehow magically buy you the ability to just work with a single section of your page, such that when you post, only that section is changed. For that, you need AJAX. Otherwise, doing a post, whether from a "partial view" or not, will cause the entire view to be changed in the browser window.
In other words, you need something server-side that will respond to that post request by returning a new full view, not just your partial, or you need to make the request client-side via AJAX, and return just your partial view. However, then, you're responsible for replacing whatever HTML should be replaced with that response, yourself.
I am currently trying to display one of my views (partial view) inside of another one. Inside of my view, I have been using the following code: #{ Html.RenderPartial("_Pending"); }.
My partial view is inside of my Shared folder. My goal is to pull in two different views using logic from two different controllers. Given my two views (Transaction Index and Pending Transactions (partial)), I essentially want both of these to appear on the same page. The issue is that currently, I am essentially getting the same view twice.
In short, how do I display a partial view inside of another view, with the partial view returning results from a different controller?
If I understand correctly, what you want is getting result of same partial view but executed by two different controller.
Have you tried #Html.Action?
essentialy it is the same concept as calling Partial but with controller action involved.
to use it, just create two Action then call #Html.Action in your view, such as:
in your controller:
public ActionResult Action1() {
return PartialView("__Pending");
}
public ActionResult Action2() {
return PartialView("__Pending");
}
in your view - you can also call it within your partial view
#Html.Action("Action1")
#Html.Action("Action2")
More info abount Partial and Action difference check out
MVC Html.Partial or Html.Action
more info about hwo to use Html.Action
How can I use Html.Action?
The partial is always included in the main view. The only time you would return the partial on its own would be if you were updating via AJAX. Presumably you would use a partial to display a list of clients. You would, perhaps, use a foreach loop in your view to iterate over the lists (contained in the view model), passing each one to the partial as its model.
Find an example to use many partial views inside one view.
In aspx page:-
<asp:content id="content" contentplaceholderid="CenterContentPlaceHolder" runat="server">
<form id="frmCheckout" name="frmCheckout" method="post">
<div class="rzccartcont">
<%this.Html.RenderPartial("CheckoutProduct", Model);%>
<div class="rzcchkpmnt rzcchkpmnt-bg" id="divChkbottomArea">
<% this.Html.RenderPartial("CheckoutCartProfileInformation", Model); %>
<%this.Html.RenderPartial("CheckoutCartPaymentDetails", Model); %>
</div>
</div>
</form>
</asp:content>
Reloading part of a page via AJAX (note partial is rendered inline in initial page load)
<script type="text/javascript">
$(function() {
$('#someButton').click( function() {
$.ajax({
url: '/controller/action',
data: ...some data for action...,
dataType: 'html',
success: function(data) {
$('#partial').html(data);
},
...
});
});
});
</script>
Controller for AJAX:-
public ActionResult Action(...)
{
var model = ...
...
if (Request.IsAjaxRequest())
{
return PartialView( "Partial", model.PartialModel );
}
else
{
return View( model );
}
}
Hope it helps you.
I have a case like the following:
The Parent page looks like:
#using (Html.BeginForm("Create", "HTML", FormMethod.Post))
{
#Html.DropDownListFor(model => model.SelectedObjectId, Model.MajorObjects)
#Html.Partial("_SelectCase");
...
}
And in the _SelectCase i want to load some data based on the DropDownList selected element.
For this i have the _SelectCase like
#using (Html.BeginForm("SelectCase", "HTML", FormMethod.Post))
{
...
}
And the controller like
public ActionResult SelectCase(CustomIdentity currentUser)
{
...
}
And the question: how may i get the value from the DropDownlist in the SelectCase method from the Controller?
Thanks.
As far as I know, you can't have a dynamic partial inside a parent.
Parent and Partial views are generated after a server side call.
The best you can do is make that partial form in the parent and have whatever values you want to change dynamically fetched through an AJAX call.
Is there any way i can know that partial view is called from which main view?
I have one partial view being called from two main views with different data.
MainIndex1.cshtml
#Html.Partial("~/Views/Shared/_partialView.cshtml", Model)
MainIdex2.cshtml
#Html.Partial("~/Views/Shared/_partialView.cshtml", Model)
so, in _partialView how i can know that it is called from which main view?
If you want to see which controller and action is participating to call this partial view. So if you want to get the parent context inside this child action you could do this:
public ActionResult Menu()
{
var rd = ControllerContext.ParentActionViewContext.RouteData;
var currentAction = rd.GetRequiredString("action");
var currentController = rd.GetRequiredString("controller");
...
return View();
}
or you can also use this code to find out the controller and action name for current request.
Controller: #ViewContext.Controller.ValueProvider.GetValue("controller").RawValue
<br />
View: #ViewContext.Controller.ValueProvider.GetValue("action").RawValue
refer following thread on stackoverflow..
Get the parent controller name from partialview action
hope this will help you.
thanks
I'm new to MVC and I wanna render a partial view in a popup within a view, but I wondering how to provide the partial view's model.
<div id="enumsDialog" class="dialog">
#Html.Partial("~/Views/Enumeration/List.cshtml", [it needs a modal here])
</div>
In another words, I want the partial view to deal with its own controller.
How to implement that?
If you are wanting to render a partial view whose action/data comes from a different controller, then you will probably want to use the RenderAction method:
#Html.Action("MyAction", "MyController")
If you are wanting to render a partial view with data from your current viewmodel (without having to make another request of your application), then use the RenderPartial method:
#Html.Partial("NameOfView", Model.WhateverYouArePassing)
The easiest way is this one:
public class EnumerationController : Controller {
// other actions...
public ActionResult List(){
// TODO: var model = retrieve-your-model-here
return PartialView(model);
// using "PartialView" instead of "View" method ensures this action isn't
// responsible from direct requests
// Also you can use "PartialViewResult" class as a return-type instead
// of "ActionResult" in method, like "List2()" method below:
}
public PartialViewResult List2(){
// TODO: var model = retrieve-your-model-here
return PartialView(model);
}
}
and in .cshtml file:
#{Html.RenderAction("List", "Enumeration");}
// or:
#Html.Action("List", "Enumeration")