I am creating simple mvc application using c#.
when I use Partial view to get the input the validation is not triggered.I have done the validation using data annotation .And another thing I am not using any form element in the partial view
What is the solution for the Kindly give the suggestion to this
So, I assume you a building a form you would like to submit.
First of all, you will suggest to you use EditorTemplates and not partial views. But this is just a tip.
Here is an example of loading partial view and resetting validation
$("#btnNewOrderLine").click(e => {
e.preventDefault();
(<any>$('#modalEditOrderLine')).modal('show');
var orderId = $("#OrderID").val();
$('#modalOrderLineBody').load("/ExactSalesOrders/PartialOrderLineDetail/", { orderLineId: "new", orderId: orderId },
() => {
$('#formOLDetail').removeData('validator');
$('#formOLDetail').removeData('unobtrusiveValidation');
$("#formOLDetail").each(function () { $.data($(this)[0], 'validator', false); }); //enable to display the error messages
$.validator.unobtrusive.parse("#formOLDetail");
}
);
});
Edit: you don't need to add any scripts to the end of the partialview page
See your ViewModal should contain all the Properties including the properties you are showing in Partial View. And you should include Data Annotation attribute to the required properties.
For Example:
public class myViewModal
{
[Required]
public int Id{get;set;}
[Required]
public string Name{get;set;}
public string Desc{get;set;}
//These two properties are for partial view
[Required]
public string DOB{get;set;}
[Required]
public string AnyOtherField{get;set;}
}
You should reference this model in your main view
#model MyProject.Model.myViewModal
Then Inside BeginForm or Form Tag in main view, you need to render the partial view to work validation.
#HTML.Beginform()
{
// My main View HTML goes here
// Here call the partial view
}
Related
I need to create a view that displays Order Header information and I need to add a patial view that displays a grid of Line Items. The partial view will be strongly typed from a viewmodel. I understand that I should use the html helper #Html.Partial("Path/view"). I have only used controllers up til now to open a view, populating the viewmodel before sending it to the view. Since the partial view is being called form the html helper, I would like to know is what would be the best way to populate the parital view with the model data.
Option 1: Inherit from parent page
By default, any partial view rendered by calling #Html.Partial("PartialViewName") will get the view model passed to the parent view.
So if you have:
View Model
namespace MyNamesapce
{
public OrderInfoViewModel
{
public string OrderTitle { get; set; }
public IEnumerable<OrderItem> OrderItems { get; set; }
}
}
OrderInfo.cshtml
#model MyNamespace.OrderInfoViewModel
<h1>#Model.OrderTitle</h1>
#Html.Partial("OrderLineItems")
The OrderLineItems page should get a MyNamespace.OrderViewModel passed to it... so your partial view should look like this:
OrderLineItems.cshtml
#model MyNamespace.OrderInfoViewModel
foreach (var orderItem in Model.OrderItems)
{
//Do stuff
}
Option 2: Specify model
You can use the second parameter to specify the view model to be passed. I.e.
OrderInfo.cshtml
#model MyNamespace.OrderInfoViewModel
<h1>#Model.OrderTitle</h1>
#Html.Partial("OrderLineItems", Model.OrderItems)
OrderLineItems.cshtml
#model IEnumerable<OrderItem>
foreach (var orderItem in Model)
{
//Do stuff
}
Option 3: Use partial actions
If you need to reuse a partial view over multiple pages, it could be a good idea to use a partial view to eliminate having to populate different view models with the same info just because the page is going to be using the same partial.
E.g.
View Model
namespace MyNamesapce
{
public OrderInfoViewModel
{
public string OrderTitle { get; set; }
}
}
Controller
public class OrderController : Controller
{
public ActionResult OrderInfo(int orderId)
{
OrderInfoViewModel viewModel = GetViewModel(orderId);
return View(viewModel);
}
public PartialViewResult OrderLineItems(int orderId)
{
IEnumerable<OrderItem> orderItems = GetOrderItems(orderId);
return Partial(orderItems);
}
}
OrderInfo.cshtml
#model MyNamespace.OrderInfoViewModel
<h1>#Model.OrderTitle</h1>
#Html.Action("OrderLineItems")
OrderLineItems.cshtml
#model IEnumerable<OrderItem>
foreach (var orderItem in Model.OrderItems)
{
//Do stuff
}
With a partial view, you are just sending in a Model just like you would with a normal View. For example, if your Model has a property of LineItem objects named 'LineItems' you simply would do this:
#Html.Partial("_PartialName", Model.LineItems)
Now if your Model does not have that property, you can either add it, or pass it another way, like ViewBag (I prefer a strongly typed method, but that is my opnion:
#Html.Partial("_PartialName", (List<LineItem>)ViewBag.LineItems)
These are not the only ways, but they are my preferred methods.
I have a list of blog post categories(~20) in a look up table.
I want to display them on multiple pages as list of hyperlinks that user can click.
I also want to display them in a dropdown list in 2 or more places(different view pages)
The follow works & I see categories as a menu/list of hyperlinks.
But this will cause me modify multiple controller where I need to show the categories.
What is the best practice to handle this so that I have minimal code change?
//#1 I added new class in one of my model:
namespace MyApp.Models
{
...
public class ShowPostModel
{
public Post Post { get; set; }
public IEnumerable<Category> Categories { get; set; }
}
public class Category
{
public string _id { get; set; }
public string Name { get; set; }
}
}
//#2 Populating the controller
namespace MyApp.Controllers
{
public class BlogController : Controller
{
public ActionResult ShowPost()
{
ShowPostModel viewModel = new ShowPostModel();
viewModel.Post = ReadBlogPostFromDB();
viewModel.Categories = ReadCategoriesFromDB();
return View(viewModel);
}
}
}
//#3 This is from my main view for showing the Post:
#Html.Partial("_Categories", Model.Categories)
//#4 This is my _Categories partial view:
#model IEnumerable<MyApp.Models.Category>
<section>
<header><b>Categories</b></header>
<ul style="padding:0;margin:0;">
#foreach (var cat in Model)
{
<li>
#cat.Name
</li>
}
</ul>
</section>
Thanks for reading
Edit:
I made these changes and it seems working as well.
Any comments or improvements I can make here?
//#1 deleted this line from public class ShowPostModel (model is now DRY)
public IEnumerable<Category> Categories { get; set; }//deleted
//#2 created a base controller and inherit from it
public abstract class BlogBaseController : Controller
{
public BlogBaseController()
{
ViewBag.Categories = ReadCategoriesFromDB();
}
}
//#3 force all controller where I need categories to inherit from base controller
public class BlogController : BlogBaseController
//#4 change how I read in my views
#Html.Partial("_Categories", (IEnumerable<MyApp.Models.Category>)#ViewBag.Categories)
If you use the categories in enough places, you can encapsulate this into a base controller class, and override OnActionExecuted.
I would then put the Categories into a property on the ViewBag and pass it into your partial view from there, and leave your view's model alone.
i wonder why no one has suggested using RenderAction. you can write this Action method in you base controller. this will make it available in all derived controller. this way you can have your categories view strongly typed. Moreover, you should put your Categeories view in Views/Shared directory so every controller has access to this view. Doing so will keep you DRY and you still have the benefits of having strongly typed view.
EDIT By the way you don't have to have base controller to use renderaction. Although above approach is valid and i prefer doing like this but you can also have a nvaigation controller like
Public NavigationController:Controller()
{
public ActionResult Categories()
{
var Categories = FetchFromDB();
return View(Categoires);
}
}
Now you can call this action method using renderAction on anywhere in your application
You might want to try creating 2 display for templates, one to display in link and one to display in dropdown. Depending on the page you tell the view to use the specific template.
You can create a Filter that populates your categories and adds it to ViewData/ViewBag. You can then apply this filter to the controllers/actions that require the categories.
For displaying, you can use EditorTemplates or Partials to keep your UI code DRY...
HTH.
As we all know RenderAction() is either part of:
Asp.net MVC 1 Futures or
Asp.net MVC 2 Beta 2
and allows us to render action result inside another view or partial view.
Description
You have a view with multiple partial views displayed using RenderAction() helper.
At least two partial views render a <form> probably by using Html.BeginForm() that postback to original view.
Postback is not performed via Ajax call
Postback data is validated upon form POST.
Problem
When one of the forms gets posted back the other one renders as invalid.
Has anyone used this pattern and solved it? We should somehow know which form performed postback and only that one should validate its POST data. Others should either ignore validation or perform regular HttpVerb.Get action processing.
Have a hidden field in the form to indicate which one. Or, have a prefix passed to the partial and appended to each element in the form.
About prefixes. First way is to have two properties, calling Html.RenderPartial("partial", Model.Data1/2.WithPrefix("data1")).
public class FormModel
{
public string Prefix { get; set; }
}
public class FormData
{
public FormModel Data1 { get; set; }
public FormModel Data2 { get; set; }
}
public ActionResult HandlePost(FormData data)
{
if (data.Data1 != null) {} else {}
}
Second way is the same but use two action parameters.
public ActionResult HandlePost(FormModel data1, FormModel data2)
{
if (data1 != null) {} else {}
}
In the partial view you do
<%= Html.TextBox(Model.Prefix + ".FormModelField", Model.FormModelField) %>
that is, you set field name with the prefix passed in the model.
Of course you may vary this in details.
Consider the following scenario:
Action Edit() is forwarded to Edit.aspx view to render the view.
Edit.aspx consists of textbox1 and two partial views (aka view user controls):
part1.ascx (which has textbox2, textbox3)
and part2.ascx (which has checkbox1 and checkbox2)
You want to have a strongly typed view for Edit.aspx, say, you use EditViewData class.
You also need Edit.aspx, part1.ascx and part2.ascx have access to some global information such as currentUserID, currentUserLanguage, currentUserTimezone.
Questions:
How do you go about structuring the EditViewData class?
How do you pass the view data to the view and partial views so that the object gets populated automatically when you submit the form and return to the Edit() http.post action?
What do you pass to the Edit() http.post action?
Your viewdata should look like this:
public class EditViewData
{
public int currentUserID { get; set; }
public string currentUserLanguage { get; set; }
public string currentUserTimezone { get; set; }
// ... other stuff
}
After you strongly type your aspx, you also need to strongly type your ascxs. Then in your aspx, when you call RenderPartial, just call like usual:
<% using (Html.BeginForm()) %>
<% Html.RenderPartial("part1.ascx" ); %>
<% Html.RenderPartial("part2.ascx" ); %>
<%}%>
It should automatically inherit the Model in the control. Just remember that your BeginForm should be surrounding both of your controls (ascxs).
I want to pass some parameters to my MVC UserControl like ShowTitle(bool) and the ViewData.Model.Row . How I define my usercontrol and pass them to it?
Tanx
You can use the RenderAction HtmlHelper, found in the MVC futures dll available at codeplex. In your main page
...
You need an action method on the controller with the parameters. The action then creates a ViewData for the usercontrol. The usercontrol is returned as a view with
return View("usercontrolname", model);
The .ascx file then uses the model for just the user control. The resulting HTML is rendered into the calling page.
You can define your control as
public partial class MyUserControl : System.Web.Mvc.ViewUserControl<MyUserControlViewData> {
}
public class MyUserControlViewData {
public IList<MyData> MyData { get; set; }
public string SomethingElse { get; set; }
}
After that you can create an instance of MyUserControlViewData classin your controller, populate with data and pass it to the view. Is that what you're looking for?