How to load another view as PartialView when the current View loads? - asp.net-mvc

I am relatively new to this. I am working on this ASP.NET Core MVC project where I want to load a PartialView, HistoryTable.cshtml in a <div> in the current Main View when the Main View, Locate.cshtml loads. In other words, I want the PartialView to be there whenever the MainView loads/reloads.
I am implementing it in the following way:
Locate.cshtml
#model Project.Models.CustomModels.LocationsHistoryViewModel
<div class="container">
...
<div id="divLocationsHistoryTable"></div>
...
</div>
#section Scripts {
<script type="text/javascript">
$(document).ready(function () {
$(".disabledropdowncntrl").prop('disabled', false).trigger("chosen:updated");
$("#divLocationsHistoryTable").load("/Project/HistoryTable");
});
HistoryTable.cshtml
#model IEnumerable<Project.Models.CustomModels.LocationsHistoryViewModel>
<div class="card">
...
#if(Model.Count() != 0)
{
<thead>
<tr>
<th data-column-id="UserId" data-type="string" data-identifier="true" hidden>User ID</th>
<th data-column-id="Name">Name</th>
...
</tr>
</thead>
}
else
{
...
}
<tbody>
#foreach(var item in Model)
{
<tr>
<td>
#item.User.FirstName #item.User.LastName
</td>
...
</tr>
}
</tbody>
</div>
Controller: Locate ActionMethod
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Locate(int Id, InventoryLocationsHistoryViewModel locationsHistoryVM)
{
...
var HistoryObject = _context.History
.Include(...
.Where(...
.Select(...
{
...
}).ToList();
return PartialView("/Project/HistoryTable", HistoryObject);
}
What to do?
EDIT
The issue that I am facing is similar to this question, however, the difference is that I HAVE to use Submit button here as I am submitting form here. The Submit button has to do two things when clicked:
Save the form details into the database.
Update the HistoryTable that has to be displayed below the Submit button always. This HistoryTable has to be shown at all times (even before clicking Submit). Thus, I cannot use Button.

There's a number of issues here, making it a little difficult to figure out what it is you're actually trying to achieve.
First and foremost, your Locate action should return your Locate.cshtml view, on both GET and POST. The fact that that view includes your HistoryTable.cshtml partial view is an implementation detail. If you only return the partial on POST, you'll only have the partial HTML in the browser, not the full Locate view.
Then, it appears that you're attempting to use jQuery's load method to load your actual partial, not an action that returns that partial. You can't get the view directly; you need to submit an AJAX request (what load is doing) to a route tied to an action that returns that partial.
Next, it looks like your partial needs a payload, i.e. some object needs to be "posted" for it to work with. If that's the case, you need to pass a JavaScript object representation of what you need to post to the load method as its second parameter. As it is, it's simply going to issue a GET request directly, passing no data.
However, since you're only doing this on page load, it calls into question why you're using AJAX at all. AJAX only makes sense if you need to change something later, after page load. If you're doing an AJAX request on load, it should simply be built into the page from the start, negating the need for a separate request.
Lastly, while you can pass a model to a partial view when you include it in a page, more likely than not what you're actually looking for here is a view component, i.e. something capable of actually doing logic like querying from a database, separate from the main request in play.

Related

Partial Views on mvc create view that use a dropdown list to populate the partial view's view bag is this possible in mvc?

can a Partial Views on mvc create view that is using a dropdown list that sends value from the dropdown list to a function that creates a list based on the dropdown list value selection, That is then stored in a view bag for the partial view.. Can this be done in mvc and can it be done on create view of a mvc form?
I can see how something this would work in the edit view because the dropdown list value has already been selected when the page loads.
But on a new Create view record nothing is selected so the list function has a null value
Are partial views only for forms that have data pre-populated in them?
Update:
I have a create view that was created by the visual studio wizard. It has both a post and get under the create. When the user in the create view. I have a dropdown list on the page form with other fields but on load of that new create page it is empty. Unfortunately for me I wanted my partial view to to get populated with a list of data that gets sent to a view bag after the user make a selection from the drop down list.
I think what I am asking to do can only be done with webforms as mvc can handle dynamic data all that well it seems. And since when the page loads the dropdown has no value.. the list can't built so there is a null value error as well as and empty list if I hard code a value in the drop down list.
Here is my Code in these different attempt threads with different veration of my code documenting my many attempts. As I have comcluded it is not possible sadly.
Can a Drop Down List Trigger A Partial View To Update on A Create View Form In mvc?
Null view bag and partial view
Populating Partial Views using mvc
Updating a Partial View in MVC 5
So with help from Matt Bodily You can Populate a Partial View in the create view triggered by a changed value in a drop down list using a view bag and something called Ajax. Here is how I made my code work.
First the partial view code sample you need to check for null data
_WidgetListPartial
#if (#ViewBag.AList != null)
{
<table cellpadding="1" border="1">
<tr>
<th>
Widget Name
</th>
</tr>
#foreach (MvcProgramX.Models.LIST_FULL item in #ViewBag.AList)
{
<tr>
<td>
#item.WidgetName
</td>
</tr>
}
</table>
}
Populating your View Bag in your controller with a function
private List<DB_LIST_FULL> Get_List(int? VID)
{
return db.DB_LIST_FULL.Where(i => i.A_ID == VID).ToList();
}
In your Create controller add a structure like this using the [HttpGet] element
this will send you data and your partial view to the screen placeholder you have on your create screen The VID will be the ID from your Drop down list this function also sends back the Partial View back to the create form screen
[HttpGet]
public ActionResult UpdatePartialViewList(int? VID)
{
ViewBag.AList = Get_List(VID);
return PartialView("_WidgetListPartial",ViewBag.AList);
}
I am not 100% if this is needed but I added to the the following to the ActionResult Create the form Id and the FormCollection so that I could read the value from the drop down. Again the Ajax stuff may be taking care if it but just in case and the application seems to be working with it.
This is in the [HttpPost]
public ActionResult Create(int RES_VID, FormCollection Collection, [Bind(Include = "... other form fields
This is in the [HttpGet] again this too may not be needed. This is reading a value from the form
UpdatePartialViewList(int.Parse(Collection["RES_VID"]));
On Your Create View Screen where you want your partial view to display
<div class="col-sm-6">
<div class="form-horizontal" style="display:none" id="PV_WidgetList">
#{ Html.RenderAction("UpdatePartialViewList");}
</div>
</div>
And finally the Ajax code behind that reads the click from the dropdown list. get the value of the selected item and passed the values back to all of the controller code behind to build the list and send it to update the partial view and if there is data there it pass the partial view with the update list to the create form.
$(document).ready(function () {
$('#RES_VID').change(function ()
{
debugger;
$.ajax(
{
url: '#Url.Action("UpdatePartialViewList")',
type: 'GET',
data: { VID: $('#RES_VID').val() },
success: function (partialView)
{
$('#PV_WidgetList').html(partialView);
$('#PV_WidgetList').show();
}
});
This many not be the best way to do it but this a a complete an tested answer as it work and it is every step of the process in hopes that no one else has to go through the multi-day horror show I had to go through to get something that worked as initially based on the errors I thought this could not be done in mvc and I would have to continue the app in webforms instead. Thanks again to everyone that helped me formulate this solution!
No, partial views do not necessarily have to be strongly typed, if that's your question. You can have a partial view with just html markup.

Keeping model while navigation using angularjs

I just started to learn angularjs and I have a question:
I am trying to create a view with a table of entities with an update button. When the Upadte button is pressed I want to navigate to another view to edit the entity.
In my main page I used this to load my different view into:
<div ng-view></div>
I used ASP.NET MVC to create partial views for the list of entites and the update form.
These two partial views use the same angular controller.
To display the list:
<div ng-controller="CompaniesController">
<table id="tblCompaniesCollection">
<thead>
<tr>
<th>Name</th>
...
</tr>
</thead>
<tbody ng-repeat="Company in Companies">
<tr>
<td><span>{{Company.Name}}</span></td>
...
<td>
<button type="button" ng-click="ChangeView(Company)">Go to edit</button>
</td>
</tr>
</tbody>
</table>
</div>
To update:
<div ng-controller="CompaniesController">
<table id="tblCompanyToEdit">
<tbody >
<tr >
<td>Name</td>
<td><span>{{CompanyToEdit.Name}}</span></td>
</tr>
...
</tbody>
</table>
</div>
In the ChangeView(Company) function I do the following:
$scope.ChangeView = function (Company) {
$scope.CompanyToEdit = Company
$location.path('/EditCompany');
};
What I tried to achieve:
Have a simple partial view for the view of list of entites and the
update view.
After the view of list of entites is loaded into it's place, it
gets the data from the same web application via WEB API
controller.
It is working till this point.
What is not working:
When I click the button store the selected entity in the
$scope.CompanyToEdit and load it into the view.
This way I would not have to create another request to the server to
get the company to edit, but the angular controller recreated on
navigating and I lost my data.
How do you solve this wiht angular? Please tell me if my aproach is not good.
You cannot achieve that with the same controller.
The reason is that when changing views, and I assume you're changing states, the controller is loaded again and is going through an initialization process.
Meaning that $scope.CompanyToEdit won't have a value and will be undefined, unless you initialize that in the controller.
What you need to do, is use a service to keep the data and use the controller to access that service. The service will keep the value since while you're navigating in the same SPA, services exist as singletons.
Inject the service to the controller and access the data there.

Unable to use multiple Model in MVC based on any conditions

I am creating a voting mechanism for my MVC application. user will be able to vote only after loged in. I have totally 3 tables tblQuestions(to populate the questions), tblAnswers(to populate the answers), tblQuestionAnswerUserResponses (to populate the user response.)tblAnswers have relation with tblQuestions. I have used the following code in the container in the HttpGet. This is my controller code.
[HttpGet]
[ActionName("VotingResult")]
public ActionResult VotingResult(int personid)
{
List<Voting_Questions> QuesList = EpDObj.PopulateQuestions(); //Populate the list of questions
CountofQuestionsDisplayed = QuesList.Count;
ViewBag.Questions = QuesList; // Storing the list of questions in the viewbag
List<Voting_Answers> Answers = EmcObj.Voting_Answers.ToList(); //Populate the list of answers
return View(Answers);
}
I am using the Voting_Answers as model in my view My view is
#model IEnumerable<EmployeeManagementDAL.Voting_Answers>
<h2>VotingResult</h2>
#using (Html.BeginForm())
{
<div>
#foreach (var a in ViewBag.Questions)
{
<h4>#a.Questions</h4>
<div>
#foreach (var b in Model)
{
if (b.QuestionsID == a.id)
{
#Html.RadioButton(b.AnswersOptions, new {Answerid= b.id, Questionid=a.id }) #b.AnswersOptions
}
}
</div>
}
</div>
<br/>
<div >
<input type="submit" value="Vote Now!!" onclick="return confirm('Are you sure you want to submit your choices?');"/>
</div>
}
When the user go to this page for the very first time there will be no options selected. after selecting the options the values an clicking Save button will save the details to the third table and then he comes out of that page. Now if for the second time he reaches that page for editing, I want my page to render with those values in my tblQuestionAnswerResponses i.e I guess my model class of tblQuestionAnswerResponses to be used. In that case can i use the same page for both cases i.e when the user vists the page for first time and also when second time the page is visited. Can I use multiple Model in MVC based on conditions in my View.
Your ActionName attribute is unnecessary, as you have specified the same name that your action already has.
It would be cleaner to use a ViewModel instead of using the ViewBag. For starters, you'll get strong typing in your view, and it will also lend itself to easier testing.
If you make a ViewModel that represents what you want your view to display, then you can map back and forth between it and your domain models in your controller actions, and let them do the heavy lifing.

ASP.NET MVC 2: ViewData.Model.ExecuteResult not existing

ViewData.Model.ExecuteResult does not exist in ASP.NET MVC2, but in MVC1.
What is the alternative in ASP.NET MVC2?
What I want to do, is to update a table after an ajax request. So I put the table in an extra View. How can I update this partial view without loading the whole page again?
ExecuteResult is a method on the System.Web.Mvc.ActionResult class. Are you sure you don't mean to be looking there?
http://aspnet.codeplex.com/SourceControl/changeset/view/23011#266522
The Model property is just an object type, and always has been, AFAIK.
As for updating the table, what I've done in the past, to update a portion of a page after a partial view is to use Ajax.BeginForm like so:
<% using (Ajax.BeginForm("Customers", new AjaxOptions { UpdateTargetId = "customerList"})) { %>
<!-- FORM HERE -->
<% } %>
<div id="customerList">
<% Html.RenderPartial("CustomerList"); %>
</div>
'UpdateTargetId' is the key here, and tells MVC to use the result of the "Customers" action to replace (by default, you can append by setting the InsertionMode AjaxOption to InsertBefore or InsertAfter) everything inside the element withthe Id you specify.
If you want to use the same action to service the full page request and the Ajax request, you can use the IsAjaxRequest extension method to determine what to return:
if (Request.IsAjaxRequest())
return PartialView("CustomerList");
// Not an Ajax request, return the full view
return View();
Hope that helps!

Parsing Form Post Values From a Table in ASP.NET MVC?

Ok, I'm an MVC newbie coming from a webforms background, so please excuse any ignorance here. Here is my scenario. I've got a table consisting of a list of applications and associated permissions. Each table row consists of 3 pieces of information: a checkbox, some text describing the row, and a dropdown list allowing the user to select the appropriate permission for the application. I want to post this data and only work with the rows in the table which were checked (the id of the row is embedded as the checkbox name). From there, I want to grab the selected value from the DropDownList, and call the necessary code to update the DB. Here is my View page's code:
<%foreach (var app in newApps)
{ %>
<tr>
<td><input type="checkbox" name="AddApps" value="<%=app.ApplicationId %>" /></td>
<td><%=Html.Encode(app.ApplicationName)%></td>
<td><%=Html.DropDownList("AppRole", new SelectList(app.Roles, "RoleId", "RoleDescription"))%></td>
</tr>
<%} %>
How would I retrieve the appropriate values from the FormCollection when I get to the controller on form post? I have done this in the past when I only had checkbox values to retrieve by just calling Request.Form["CheckBoxName"] and parsing the string.
Or am I going about this entirely wrong?
You are halfway right in order to post your data that the controller can read the info it must be inside a form as so :
<% using(Html.BeginForm("Retrieve", "Home")) %>//Retrieve is the name of the action while Home is the name of the controller
<% { %>
<%foreach (var app in newApps) { %>
<tr>
<td><%=Html.CheckBox(""+app.ApplicationId )%></td>
<td><%=Html.Encode(app.ApplicationName)%></td>
<td><%=Html.DropDownList("AppRole", new SelectList(app.Roles, "RoleId", "RoleDescription"))%></td>
</tr>
<%} %>
<input type"submit"/>
<% } %>
and on your controller :
public ActionResult Retrieve()
{
//since all variables are dynamically bound you must load your DB into strings in a for loop as so:
List<app>=newApps;
for(int i=0; i<app.Count;i++)
{
var checkobx=Request.Form[""+app[i].ApplicationId];
// the reason you check for false because the Html checkbox helper does some kind of freaky thing for value true: it makes the string read "true, false"
if(checkbox!="false")
{
//etc...almost same for other parameters you want that are in thr form
}
}
//of course return your view
return View("Index");//this vaires by the name of your view ex: if Index.aspx
}
This site gives more details on how to handle the dropdownlist helper:
http://quickstarts.asp.net/previews/mvc/mvc_HowToRenderFormUsingHtmlHelpers.htm
Request.Form will still work, except that your checkboxes all have the same name.
So one way would be to give the checkboxes distinct names, e.g. "AddApps-app.id", and use Request.Form.
However, a more elegant and testable way is to use list binding.
In this model, you give your form elements a certain structured name, and the default model binder will wrap each set of form elements into a list of typed records in the controller. This is fully explained in this blog post.
The advantage here is that your controller deals only with instances of the application type, and hence has no implicit dependency on the way the view is structured. Therefore, it is very easy to unit test.

Resources