I'm having a problem passing parameters from my view to my popup.
In my view, I have the following razor code to render an Action Link wherein when I click it, a pop-up will appear:
#Html.ActionLink("[Edit Product]", "Edit", "Products", new { ProductCode = #Model.ProductCode}, new { #class = "editLink" })
I'm not quite sure if this is correct or if the part new { ProductCode = #Model.ProductCode} makes any sense (please explain to me what that part does, anybody hihi).
Anyway, my pop-up code accepts a parameter like this:
#model MySuperStore.Models.ViewModel.ProductsModel
Whenever I try to display the ProductCode via #Mode.ProductCode, I always receive an error saying the reference not set to an instance of an object.
I have tried placing the ProductCode in a ViewData through the MainView and accessing it on the pop-up but that doesn't seem to work either.
Can somebody please help me? Thanks. Cheers!
Your code looks fine:
#Html.ActionLink(
"[Edit Product]",
"Edit",
"Products",
new { ProductCode = Model.ProductCode },
new { #class = "editLink" }
)
Just ensure that the view you are putting this code in is strongly typed and that the controller action that rendered it passed an actual model to it.
As far as the Edit action is concerned you should also ensure you are invoking you are passing a non-null model to the view:
public ActionResult Edit(int productCode)
{
ProductsModel model = ... fetch your model using the productCode
return View(model);
}
Now inside your Edit.cshtml view (or partial view if you are opening this using jQuery UI dialog or something in a pop-up) you could use the properties of the model:
#model ProductsModel
#Html.DisplayFor(x => x.ProductCode)
Related
So I have a Edit view with a partial view. In this partial view I have a selectlist (or dropdownlist) which values come from a ViewBag. In the control I include the selected value but it just does'nt work.
public ActionResult Edit(int id = 0)
{
Customer c = db.Customer.Find(id);
ViewBag.CustomerGlobalQuality = new SelectList(db.GlobalQuality, "Id", "Quality", c.Skill.GlobalQuality);
return View(c);
}
and in the PARTIAL VIEW I have:
#Html.DropDownList("CustomerGlobalQuality")
#Html.ValidationMessageFor(model => model.Skill.GlobalQuality)
what did I miss? It usually works with normal views, so why not with a partial?
if your logic doesn't need partial view, do not include it in this case. Use those lines of code inside your edit chtml view. In your case debug it and see what are you realy sending to drop down list. I see that you included dropdown list dana in edit view. If you use partial view you must pass object to that view in controler.
public ActionResult PartialDDLData()
{
ViewBag.CustomerGlobalQuality = new SelectList(db.GlobalQuality, "Id", "Quality", c.Skill.GlobalQuality);
return Partial("_nameOfView",ViewBag.CustomerGlobalQuality);
}
and make sure your partial view is accessible in shared or controller view folder.
I'm currently trying to post a form composed of two strongly typed views. This question is similar but it doesn't have an answer:
MVC 3 Razor Form Post w/ Multiple Strongly Typed Partial Views Not Binding
When I submit form the model submitted to the controller is always null. I've spent a couple of hours trying to get this to work. This seems like it should be simple. Am I missing something here? I don't need to do ajax just need to be able to post to the controller and render a new page.
Thanks
Here's my view code:
<div>
#using (Html.BeginForm("TransactionReport", "Reports", FormMethod.Post, new {id="report_request"}))
{
ViewContext.FormContext.ValidationSummaryId = "valSumId";
#Html.ValidationSummary(false, "Please fix these error(s) and try again.", new Dictionary<string, object> { { "id", "valSumId" } });
#Html.Partial("_ReportOptions", Model.ReportOptions);
#Html.Partial("_TransactionSearchFields", new ViewDataDictionary(viewData) { Model = Model.SearchCriteria });
}
Here's the code in the controller:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult TransactionReport(TransactionReportRequest reportRequest)
{
var reportInfo = new List<TransactionReportItem>();
if (ModelState.IsValid)
{
var reportData = _reportDataService.GetReportData(Search.MapToDomainSearchCriteria(reportRequest.SearchCriteria));
if (reportData!=null)
{
reportInfo = reportData.ToList();
}
return View(reportInfo);
}
return View(reportInfo);
}
The partial views themselves are pretty irrelevant since all they are doing is biding and displaying their models.
Partials are not the way to go here. You are looking for EditorTemplates, these are made for what you want. This case, your properties will be nicely bound to your model (that you will submit).
Your main View will have this form (note that you only have to use EditorFor instead of Partial; in this case, you probably will need to put that viewData parameter in the ViewBag or so):
#using (Html.BeginForm("TransactionReport", "Reports", FormMethod.Post, new {id="report_request"}))
{
ViewContext.FormContext.ValidationSummaryId = "valSumId";
#Html.ValidationSummary(false, "Please fix these error(s) and try again.", new Dictionary<string, object> { { "id", "valSumId" } });
#Html.EditorFor(model => model.ReportOptions);
#Html.EditorFor(model = Model.SearchCriteria });
}
Now you only have to drag your partials to the folder ~/Shared/EditorTemplates/ and rename them to match the model name they are the editor templates for.
In the ~/Shared/EditorTemplates/ folder, make a new "view", example "SearchCriteria.cshtml". Inside, put as "model" the type of class you which to create an editor template for. Example (example class has properties Name and OtherCriteria):
#model MyNamespace.SearchCriteria
<ul>
<!-- Note that I also use EditorFor for the properties; this way you can "nest" editor templates or create custom editor templates for system types (like DateTime or String or ...). -->
<li>#Html.LabelFor(m => m.Name): #Html.EditorFor(m => m.Name)</li>
<li>#Html.LabelFor(m => OtherCriteria): #Html.EditorFor(m => m.OtherCriteria</li>
</ul>
Some good reading about them:
https://www.exceptionnotfound.net/asp-net-mvc-demystified-display-and-editor-templates/
https://www.hanselman.com/blog/ASPNETMVCDisplayTemplateAndEditorTemplatesForEntityFrameworkDbGeographySpatialTypes.aspx
You should add prefix to the PartialView's fields. That will let binding data correctly.
So instead:
#Html.Partial("_ReportOptions", Model.ReportOptions);
Use:
#Html.Partial("_ReportOptions", Model.ReportOptions, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "ReportOptions" }})
I agree with #Styxxy and #Tony, Editor Templates are the better solution. However, your problem is that that you are feeding a sub-model to the partial views. Thus, when the partial view renders it doesn't know that it's part of a larger model and does not generate the correct name attributes.
If you insist on using Partials rather than Editor Templates, then I suggest only passing the Model to the partials, then having each partial do Model.Whatever.Foo and it will generate the correct name attributes for binding.
Try using EditorTemplates instead of Partials http://coding-in.net/asp-net-mvc-3-how-to-use-editortemplates/.
#Html.Partial("_ReportOptions", Model.Contact, new ViewDataDictionary()
{
TemplateInfo = new TemplateInfo()
{
HtmlFieldPrefix = "Contact"
}
})
)
#Html.Partial("_TransactionSearchFields", Model.SearchCriteria, new
ViewDataDictionary()
{
TemplateInfo = new TemplateInfo()
{
HtmlFieldPrefix = "SearchCriteria"
}
})
Im developing an MVC project and im using Ajax for displaying a list of shifts.
Here's my parent page, shifts.chtml:
#model UI.ViewModels.ViewModelShiftList
<h2>Shifts</h2>
#Ajax.ActionLink("View All Shifts", "AllShifts", "Shifts",
new AjaxOptions
{
UpdateTargetId="searchResults",
HttpMethod="GET", //default
InsertionMode= InsertionMode.Replace, //replace
LoadingElementId="progress"
})
<div id="searchResults">
#Html.RenderPartial("_ShiftList",model)
</div>
heres the controller action for the above page:
public ActionResult Shifts()
{
ViewModelShiftList viewModel = new ViewModelShiftList
{
Shifts = _shiftService.GetShifts().ToList()
};
return View(viewModel);
}
Should I not be able to send the viewmodel produced here into the partial view? Or do I have to create another action for the partial view? If so, what is the correct way to send an action to the controller of a partialview?
The error im gettin is at this point:
#Html.RenderPartial("_ShiftList",model)
// cannot impilicty convert type void to object
This was a simple fix...I needed to add curly brackets like so..
#{Html.RenderPartial("_shiftlist", Model);}
I created my first MVC application in ASP.NET today. I have a datetime column "CreatedAt" which should be filled by current date without being visible in the input form. But the generated code has this code:
<div class="editor-field">
#Html.EditorFor(model => model.CreatedAt)
#Html.ValidationMessageFor(model => model.CreatedAt)
</div>
It displays a textbox in input form. I don't want to display it, instead it should be set in code behind. How can I do that?
ASP.NET MVC doesn't have a concept of a 'code-behind'. Quite simply, you send data from your View, and it's processed in your Controller.
So if this is an action that POSTs, then we can send data back to the controller, and even better, we can keep that data 'hidden' from the textbox view.
In your view, you should replace that with the following line:
#Html.HiddenFor(m => m.CreatedAt, DateTime.Now);
Then when the model is POSTed to the controller, the CreatedAt property will have the DateTime.Now filled in.
When you POST something, it has to go to an Action Method:
public class MyController : Controller
{
//other stuff
[HttpPost]
public ActionResult Edit(Product product)
{
product.CreatedAt // should equal the DateTime.Now set when you created the View
}
}
or you could set it in the controller after it POSTs:
public class MyController : Controller
{
//other stuff
[HttpPost]
public ActionResult Edit(Product product)
{
product.CreatedAt = DateTime.Now;
}
}
You may run into issues with Html.Hidden in this context, if you do, make sure to use the work around in place.
I have the following issue.
My url structure is like this:
/people/edit/usercode
In my controller i have the following:
[AcceptVerbs(HttpVerbs.Post)]
public PartialViewResult LoanRefresh(string id)
{
PeopleModel p = new PeopleModel();
return PartialView("_LoanHistory", p.getPersonLoanHistory(id));
}
In my view i have:
#Ajax.ActionLink("Refresh", "LoanRefresh", new { id = Model.IdentityCode }, new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "loanHistory", LoadingElementId = "Loading" }, new { #class = "button" })
and
<div id="loanHistory">
#Html.Partial("_LoanHistory", Model.Loans)
</div>
When run the Ajax.ActionLink it gets the data back ok and it updates the div, but the url of the sort links on the webgrid then change their address to:
/People/LoanRefresh/AFU0006?sort=CreatedOn&sortdir=ASC
i need to stay as:
/People/Edit/AFU0006?sort=CreatedOn&sortdir=ASC
Any help would be greatly appreciated.
Well #Nick, that's because your action name is LoanRefresh and not Refresh. To do that you will probably have to do some routing or even redirect your LoanRefresh results to an action named Refresh.
Try setting ajaxUpdateContainerId to an object that is specified in the partial view, rather than an object in the view from which the partial view is originally called. The sort URLs should work correctly then.