MVC Editor Templates - mvc-editor-templates

I was trying nested Editor Templates but couldnt get it working. The structure of my model is
public class CompanyModel
{
public EmployeeModel Emp { get; set; }
}
public class EmployeeModel
{
public EmpType EmployeeType { get; set; }
public string Name { get; set; }
public DateTime StartDate { get; set; }
public string EmailAddress { get; set; }
}
public enum EmpType
{
Manager = 1,
Assistant = 2,
TeamLeader = 3
}
Each EmpType will have different EditorTemplates
The Index view is
#model CompanyModel
<h3>Index</h3>
#Html.EditorFor(m => m.Emp,"Employee")
Then i have create EditorTemplates(Employee.cshtml)
#model EmployeeModel
<h2>Employee</h2>
#Html.EditorForModel("EmpType_"+ Model.EmployeeType.ToString())
EditorTemplate(EmpType_Manager.cshtml)
#model EmployeeModel
<h2>EmpType_Manager</h2>
I am Manager
For testing i am populating the model with dummy data in the controller
public ActionResult Index(CompanyModel model)
{
EmployeeModel emp = new EmployeeModel
{
EmployeeType = EmpType.Manager,
Name = "xxxx",
StartDate = DateTime.Now,
EmailAddress = "xxx#yyy.com"
};
model = new CompanyModel();
model.Emp = emp;
return View(model);
}
When i run this it does not call the EmpType_Manager template. Can some one help me on this. I have tried using partial view which works. But would like to use EditorTemplate instead of Partial view.

Well looks like this is not possible as it is by mvc design.

Related

how to bind a dropdownlist to model properly to be able to pass values back from view to controller

I am trying to update a compound page model which as one of its properties has a list of objects.
My Model looks like this:
public class PageViewModel
{
public ProgramListVM ProgramsDDL { get; set; }
public PageViewModel()
{
this.ProgramsDDL = new ProgramListVM();
}
}
The ProgramListVM class is:
public class ProgramListVM
{
public List<ProgramVM> Program_List { get; set; }
public int SelectedValue { get; set; }
public ProgramListVM()
{
this.Program_List = new List<ProgramVM>();
this.SelectedValue = 0;
}
}
and ProgramVM is:
public class ProgramVM
{
public int ProgramID { get; set; }
public string ProgramDesc { get; set; }
public ProgramVM(int id, string code)
{
this.ProgramID = id;
this.ProgramDesc = code;
}
}
I try to render this dropdownlist by the following two:
1-
<%: Html.DropDownList("ProgramsDDL", new SelectList(Model.Page6VM.ProgramsDDL.Program_List, "ProgramID", "ProgramDesc", Model.Page6VM.ProgramsDDL.SelectedValue))%>
2-
<%: Html.DropDownListFor(m => m.Page6VM.ProgramsDDL.Program_List, new SelectList(Model.Page6VM.ProgramsDDL.Program_List, "ProgramID", "ProgramDesc"), Model.Page6VM.ProgramsDDL.SelectedValue)%>
But when I try to update my model through a controller action
[HttpPost]
public ActionResult UpdateUser(PageViewModel model)
{
}
model.ProgramsDDL.count is zero.
What is the best way to render this dropdownlist and be able to set the selected index, and also be able to send the selected index back to the controller?
You mixed up the parameters for Html.DropDownListFor(). Code sample below should work.
<%: Html.DropDownListFor(m => m.SelectedValue,
new SelectList(Model.Page6VM.ProgramsDDL.Program_List, "ProgramID", "ProgramDesc"),
null) %>
You also should have a SelectedValue in your model that's posted back.
public class PageViewModel
{
public ProgramListVM ProgramsDDL { get; set; }
public int SelectedValue { get; set; }
public PageViewModel()
{
this.ProgramsDDL = new ProgramListVM();
}
}
Also default model binder can't map complex collections to your model. You probably don't need them in your post action anyway.

Binding ListBox with a model in MVC3

My model is
public class SiteConfig
{
public SiteConfig()
{
}
public int IdSiteConfig { get; set; }
public string Name { get; set; }
public byte[] SiteLogo { get; set; }
public string Brands { get; set; }
public string LinkColour { get; set; }
public IEnumerable<SiteBrand> SiteBrands { get; set; }
}
and
public class SiteBrand
{
public int Id { get; set; }
public int SiteId { get; set; }
public int BrandId { get; set; }
public Brand Brand { get; set; }
public SiteConfig SiteConfig { get; set; }
}
public class Brand
{
public int BrandId { get; set; }
public string Name { get; set; }
public IEnumerable<SiteBrand> SiteBrands { get; set; }
}
I am following Data Base first approach. Each SiteConfig record can contain one or more Brand. So Brand is saving to another table called SiteBrand.
SiteBrand contains the forign key reference to both SiteConfig(on IdSiteConfig) and Brand(BrandId).
When I am creating a SiteConfig I want to display all the available Brand as list box where user can select one or many record(may not select any brand).
But when I bind my view with the model how can I bind my list box to the list of brands and when view is posted how can I get the selected brands.
And I have to save the SiteConfig object to database with the selected Items. And this is my DB diagram.
This is my DAL which saves to db.
public SiteConfig Add(SiteConfig item)
{
var siteConfig = new Entities.SiteConfig
{
Name = item.Name,
LinkColour = item.LinkColour,
SiteBrands = (from config in item.SiteBrands
select new SiteBrand {BrandId = config.BrandId, SiteId = config.SiteId}).
ToList()
};
_dbContext.SiteConfigs.Add(siteConfig);
_dbContext.SaveChanges();
return item;
}
Can somebody advide how to bind the list box and get the selected items.
Thanks.
Add a new Property to your SiteConfig ViewModel of type string array. We will use this to get the Selected item from the Listbox when user posts this form.
public class SiteConfig
{
//Other properties here
public string[] SelectedBrands { get; set; } // new proeprty
public IEnumerable<SiteBrand> SiteBrands { get; set; }
}
In your GET action method, Get a list of SiteBrands and assign to the SiteBrands property of the SiteConfig ViewModel object
public ActionResult CreateSiteConfig()
{
var vm = new SiteConfig();
vm.SiteBrands = GetSiteBrands();
return View(vm);
}
For demo purposes, I just hard coded the method. When you implement this, you may get the Data From your Data Access layer.
public IList<SiteBrand> GetSiteBrands()
{
List<SiteBrand> brands = new List<SiteBrand>();
brands.Add(new SiteBrand { Brand = new Brand { BrandId = 3, Name = "Nike" } });
brands.Add(new SiteBrand { Brand = new Brand { BrandId = 4, Name = "Reebok" } });
brands.Add(new SiteBrand { Brand = new Brand { BrandId = 5, Name = "Addidas" } });
brands.Add(new SiteBrand { Brand = new Brand { BrandId = 6, Name = "LG" } });
return brands;
}
Now in your View, which is strongly typed to SiteConfig ViewModel,
#model SiteConfig
<h2>Create Site Config</h2>
#using (Html.BeginForm())
{
#Html.ListBoxFor(s => s.SelectedBrands,
new SelectList(Model.SiteBrands, "Brand.BrandId", "Brand.Name"))
<input type="submit" value="Create" />
}
Now when user posts this form, you will get the Selected Items value in the SelectedBrands property of the ViewModel
[HttpPost]
public ActionResult CreateSiteConfig(SiteConfig model)
{
if (ModelState.IsValid)
{
string[] items = model.SelectedBrands;
//check items now
//do your further things and follow PRG pattern as needed
}
model.SiteBrands = GetBrands();
return View(model);
}
You can have a "ViewModel" that has both the site and brand model in it. Then you can bind your view to that model. This would allow you to bind any part of the view to any part of any of the underlying models.
public class siteViewModel{
public SiteConfig x;
public Brand b; //Fill this with all the available brands
}
Of course you can include any other information your view might need (reduces the need of ViewBag as well).

Creating Dropdown List in MVC3

I am trying to create a dropdown list to display all the value in a custom collection class
such as
public class MyCustomClassCollection
{
public List<MyCustomClass> {get;set;}
}
I want it to show the Description:string of each MyCustomClass
I tried
<%: Html.DropDownList "Description", MyCustomClass %>
Resharper suggests that I cast MyCustomClass to IEnemerable
but the server returns an unable to cast error.
Any Idea how I can create this DropDownList?
__Modification___
public class ViewModel
{
public Detail detail { get; set; }
}
public class Detail //Inherited from webservce
{
public CustomClassCollection {get;set;}
.... Other Properties, a.k.a Custom Classes
}
public class CustomClassCollection
{
public List<CustomClass> {get;set;}
}
public class CustomClass {
public int Id {get;set;}
public string Description{get;set;}
... other properties
}
public ActionResult Index(int? id, DateTime? date)
{
if (id.Equals(null))
id = ######### ;
if (date.Equals(null))
date = DateTime.Today;
var vm = new ViewModel
{
Detail = _repository.Detail((int)id,(DateTime)date)
};
return View(vm);
}
The second argument of the DropDownList helper must be an IEnumerable<SelectListItem> or a SelectList which implements this interface for that matter. So in your controller action organize in such a way that you convert your custom collection into an IEnumerable<SelectListItem>. As always you could start by writing a view model:
public class MyViewModel
{
public string SelectedDescription { get; set; }
public SelectList Descriptions { get; set; }
}
and then have your controller action query the custom list and populate the view model which will be passed to the view:
public ActionResult Index()
{
var descriptions = yourCustomCollection.MyCustomClass.Select(x => new
{
Value = x.Description,
Text = x.Description
});
var model = new MyViewModel
{
Descriptions = new SelectList(descriptions, "Value", "Text")
};
return View(model);
}
and finally in your strongly typed view:
<%= Html.DropDownListFor(x => x.SelectedDescription, Model.Decriptions) %>
UPDATE:
After posting your updated models (which by the way are still incomplete and impossible to compile as you haven't provided any property names), here's an example:
public class ViewModel
{
public int SelectedId { get; set; }
public Detail Detail { get; set; }
}
public class Detail
{
public CustomClassCollection MyCollection { get; set; }
}
public class CustomClassCollection
{
public List<CustomClass> CustomClass { get; set; }
}
public class CustomClass
{
public int Id { get; set; }
public string Description { get; set; }
}
public class HomeController : Controller
{
public ActionResult Index()
{
var vm = new ViewModel
{
Detail = new Detail
{
MyCollection = new CustomClassCollection
{
CustomClass = new List<CustomClass>
{
new CustomClass
{
Id = 1,
Description = "description 1",
},
new CustomClass
{
Id = 2,
Description = "description 2",
},
new CustomClass
{
Id = 3,
Description = "description 3",
},
}
}
}
};
return View(vm);
}
}
and in the view:
<%= Html.DropDownListFor(
x => x.SelectedId,
new SelectList(Model.Detail.MyCollection.CustomClass, "Id", "Description")
) %>
What you have to understand in order to define a dropdown list in ASP.NET MVC ius that you need 2 things:
A scalar property to bind the selected value to (SelectedId in my example)
A collection to bind the list to (Model.Detail.MyCollection.CustomClass in the example)

Dropdownlist using LINQ/MVC3/C# problem getting it to bind

I am super new to MVC3 and C#, so excuse my noob questions. I have been struggling with this for almost a full day and hope someone can shed some light (I have scoured this site for clues, hints, answers as well).
I have a single table in my database which will hold all the data. It is for a profile editor which will store values that the user can populate their timekeeping entry form automatically upon select. I am on step one though, trying to populate the first dropdownlist with the profile name. I am using LINQ, MVC3/ Razer, and C#.
Here is my dbml:
Cant post image cause I am new
http://imageshack.us/photo/my-images/560/timem.png/
Here is my model:
namespace Timekeeping.Models
{
public class Profile
{
public int Profile_ID { get; set; }
public string profilename { get; set; }
public string networkuserid { get; set; }
public int projectnumber { get; set; }
public int costcode { get; set; }
public int paycode { get; set; }
public int jobtype { get; set; }
public int workorder { get; set; }
public int activity { get; set; }
public string taxarea { get; set; }
public IEnumerable<Profile> profiles { get; set; }
}
public class ProfileViewModel
{
public int Profile_ID { get; set; }
public IEnumerable<SelectListItem> profiles { get; set; }
}
}
Here is my Controller:
namespace Timekeeping.Controllers
public class TimeProfileController : Controller
{
private static String strConnString = ConfigurationManager.ConnectionStrings["timekeepingConnectionString"].ConnectionString;
[HttpGet]
public ActionResult ProfileSelect()
{
profileConnectionDataContext dataContext = new profileConnectionDataContext(strConnString);
var model = new ProfileViewModel();
var rsProfile = from fbs in dataContext.TimeProfiles select fbs;
ViewData["ProfileList"] = new SelectList(rsProfile, "Profile_ID", "profilename");
return View(model);
}
}
And here are all the different html helpers I have tried for my View(none work):
#Html.DropDownList("rsProfile", (SelectList)ViewData["ProfileList"]))
#Html.DropDownListFor(
x => x.Profile_ID,
new SelectList(Model.profiles, "Values", "Text"),
"-- Select--"
)
#Html.DropDownListFor(model => model.Profile_ID, Model.profilename)
I know this is a mess to look at, but I am hoping someone can help so I can get on with the hard parts. Thanks in advance for any help I get from the community
Hope it will work surely...
Inside Controller :
var lt = from result in db.Employees select new { result.EmpId, result.EmpName };
ViewData[ "courses" ] = new SelectList( lt, "EmpId", "EmpName" );
Inside View :
<%: Html.DropDownList("courses") %>
Try this:
public class TimeProfileController : Controller
{
private static String strConnString = ConfigurationManager.ConnectionStrings["timekeepingConnectionString"].ConnectionString;
[HttpGet]
public ActionResult ProfileSelect()
{
var dataContext = new profileConnectionDataContext(strConnString);
var profiles = dataContext.TimeProfiles.ToArray().Select(x => new SelectListItem
{
Value = x.Profile_ID,
Text = x.profilename
});
var model = new ProfileViewModel
{
profiles = profiles
};
return View(model);
}
}
and in the view:
#model ProfileViewModel
#Html.DropDownListFor(
x => x.Profile_ID,
new SelectList(Model.profiles, "Values", "Text"),
"-- Select--"
)
If you are using a model class just try this:
<%: Html.DropDownList("EmpId", new SelectList(Model, "EmpId", "EmpName")) %>
If you want to add click event for drop down list try this:
<%: Html.DropDownList("courses", ViewData["courses"] as SelectList, new { onchange = "redirect(this.value)" }) %>
In the above one redirect(this.value) is a JavaScript function

MVC3 Razor #Html.DropDownListFor

I could use some help implementing #Html.DropDownListFor. My objective is to filter the list of Products by Category.
This code will display a list box:
#model IEnumerable<Sample.Models.Product>
#{
List<Sample.Models.Category> list = ViewBag.Categories;
var items = new SelectList(list, "CategoryID", "CategoryName");
}
#Html.DropDownList("CategoryID", items)
But I'm having trouble getting #Html.DropDownListFor to work:
#model IEnumerable<Sample.Models.Product>
#{
List<Sample.Models.Category> list = ViewBag.Categories;
var items = new SelectList(list, "CategoryID", "CategoryName");
}
#Html.DropDownListFor(???, #items)
I could use some help constructing the Linq portion of #Html.DropDownListFor.
Here is the model:
public class Product
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public int CategoryID { get; set; }
public string QuantityPerUnit { get; set; }
public Decimal? UnitPrice { get; set; }
public short UnitsInStock { get; set; }
public virtual Category Category { get; set; }
}
public class Category
{
public int CategoryID { get; set; }
public string CategoryName { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
Your view is strongly typed to a collection of products so I suppose that you need a drop down for each product. If this is the case an editor template would work:
#model IEnumerable<Sample.Models.Product>
#Html.EditorForModel()
And then inside ~/Views/Shared/EditorTemplates/Product.cshtml
#model Sample.Models.Product
#{
List<Sample.Models.Category> list = ViewBag.Categories;
var items = new SelectList(list, "CategoryID", "CategoryName");
}
#Html.DropDownListFor(x => x.CategoryID, #items)
My recommendation:
Extend your LINQ data context class with a static function to return a SelectList of all categories, and use Html.DropDownList() to display this list.
Then, add a controller for this same Action that accepts category ID and return the IEnumerable<Product> list that corresponds to that category.
here is another way to do what you want.
In the model I have two entries
public class Product
{
public int CategoryID { get; set; }
public IEnumerable<SelectListItem> Category { get; set; }
}
I then populate the SelectlestItem either from a database or statically.
In the Index.cs controller
product model = new product();
model.Category = <whereever you generated the data>;
return View(model);
In the View
#using (Html.BeginForm("Edit", "Subject", FormMethard.Post, new { id = "genform"}))
{
<div class="vertical-space spaced-field">#Html.DropDownListFor(m => m.CategoryID, model,Category)</div>

Resources