How can I bind CountryNames in DropDownListFor - c#

I'm using mvc4. How can I Bind CuntryName and its values in DropdownList
Country?
public class Country
{
public int Cnt_Id { get; set; }
public string Cnt_Name { get; set; }
}
This is my private class
public class HybridEmployee
{
public IEnumerable<Country> GetCount { get; set; }
}
Controller
public ActionResult GetCountry()
{
var x = ObjRepo.GetCountry();
hybrid.GetCount = x;
return View(hybrid);
}
Index.cshtml
#model Mvc_Application.Models.HybridEmployee
#using Mvc_Application.Models
#using (Html.BeginForm("SaveEmp", "Home", FormMethod.Post))
{
#Html.DropDownListFor(x=>x.GetCount.FirstOrDefault().Cnt_Id),new SelectList(Model.GetCount,"","");
}

We can have two approaches as shown below:
Using a ViewBag containing the data for dropdown list.
Model file:
public class State
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public int CountryID { get; set; }
}
In .cs file:
ViewBag.Countries = countryService.All().Select(x => new SelectListItem() { Text = x.Name, Value = x.Id.ToString() }).ToList();
In .cshtml file:
#Html.DropDownListFor(x => x.CountryID, ViewBag.Countries as IEnumerable<SelectListItem>, "Select Country", new { #class = "form-control" })
Using a Model's property containing the data for dropdown list.
Model file:
public class State
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public int CountryID { get; set; }
public List<SelectListItem> Countries { get; set; }
}
In .cs file:
model.Countries = countryService.All().Select(x => new SelectListItem() { Text = x.Name, Value = x.Id.ToString() }).ToList();
In .cshtml file:
#Html.DropDownListFor(x => x.CountryID, Model.Countries, "Select Country", new { #class = "form-control" })

This expression totally doesn't makes sense:
#Html.DropDownListFor(x=>x.GetCount.FirstOrDefault().Cnt_Id),new SelectList(Model.GetCount,"","");
The first argument of DropDownListFor helper (Expression<Func<TModel, TProperty>> expression) doesn't use LINQ expression, it is model binding expression - you must use a property to hold selected value instead. The drop down list binding should be used like this:
Model
public class Country
{
public int Cnt_Id { get; set; }
public string Cnt_Name { get; set; }
public int SelectedCountry { get; set; } // additional property to get selected value
}
View
#Html.DropDownListFor(x => x.SelectedCountry, new SelectList(Model.GetCount, "Cnt_Id", "Cnt_Value"), null)

Related

Altering the output value of a SelectList in DropDownListFor in MVC View

I have this code inside my form:
<div class="form-group">
#Html.LabelFor(c => c.ClosingHourId)
#Html.DropDownListFor(c => c.ClosingHourId, new SelectList(Model.ClosingHours, "Id", "Time"), "Select time", new { #class = "form-control" })
#Html.ValidationMessageFor(c => c.ClosingHourId)
</div>
The "Time" property is of type DateTime, so when I click the dropdown list on my page I see full dates and times, but the thing is I want to display only the hours, without the dates, so I want to use something like Time.ToString("H:mm") but I don't know where can I write this so it will work. Maybe the right approach would be to add something like [Display(Name = Time.ToString("H:mm"))] annotation in my ClosingHour Model? I'm not sure if it's possible.
My View Model:
public class CinemaFormViewModel
{
public int? Id { get; set; }
[Required]
[StringLength(255)]
public string Name { get; set; }
[Required]
public string Address { get; set; }
[Required]
[Display(Name = "Total Seats")]
public int TotalSeats { get; set; }
public IEnumerable<OpeningHour> OpeningHours { get; set; }
[Required]
[Display(Name = "Opens At")]
public byte? OpeningHourId { get; set; }
public IEnumerable<ClosingHour> ClosingHours { get; set; }
[Required]
[Display(Name = "Closes At")]
public byte? ClosingHourId { get; set; }
}
My ClosingHour Model:
public class ClosingHour
{
public byte Id { get; set; }
[Required]
public DateTime Time { get; set; }
}
The Action inside the controller which calls the view:
public ActionResult New()
{
var openingHours = _context.OpeningHours.ToList();
var closingHours= _context.ClosingHours.ToList();
var viewModel = new CinemaFormViewModel
{
OpeningHours = openingHours,
ClosingHours = closingHours
};
return View("CinemaForm", viewModel);
}
change you by adding string time property
public class ClosingHour
{
public byte Id { get; set; }
[Required]
public DateTime Time { get; set; }
[NotMapped]
public string ShortTime { get; set; }
}
action
public ActionResult New()
{
var closingHours= _context.ClosingHours.ToList();
var openingHours = _context.OpeningHours.ToList();
closingHours.ForEach(i=> i.ShortTime=i.Time.ToShortTimeString());
openingHours.ForEach(i=> i.ShortTime=i.Time.ToShortTimeString());
// or you can try
closingHours.ForEach(i=> {
i.ShortTime=i.Time.ToShortTimeString();
i.Time=null;
});
openingHours.ForEach(i=> {
i.ShortTime=i.Time.ToShortTimeString();
i.Time=null;
});
var viewModel = new CinemaFormViewModel
{
OpeningHours = openingHours,
ClosingHours = closingHours
};
return View("CinemaForm", viewModel);
}
view
....
#Html.DropDownListFor(c => c.ClosingHourId,
new SelectList(Model.ClosingHours, "Id", "ShortTime"), "Select time", new { #class = "form-control" })
.....

List item inside model contains null on post

I have a model class. Inside that, I have a class and a list which is that type.
public class ItemSetupModel
{
public class UPC
{
public int ItemNumberForUPC { get; set; }
public string GCOwner { get; set; }
public string GCFeeItem { get; set; }
public string GCBranded { get; set; }
public string query { get; set; }
}
public List<UPC> lstUPC { get; set; }
public UPC upc;
public ItemSetupModel()
{
this.upc = new UPC();
this.lstUPC = new List<UPC>();
this.lstUPC.Add(this.upc);
}
}
cshtml is as below :
#model PricingUpdates.Models.ItemSetupModel
#using (Html.BeginForm())
{
#for (int i = 0; i < Model.lstUPC.Count; i++)
{
#Html.Label("ItemNumberForUPC", "ItemNumber")
#Html.TextBoxFor(m => m.lstUPC[i].ItemNumberForUPC, new { #class = "form-control", Name = "UPCUpdate" + i })
}
}
Whenever I am posting the values, the action result model will never contain the values entered by me in the textbox. It will always show null values for the list.

BeginCollectionItem can not bind partial values

I´m doing Editing a variable length list, ASP.NET MVC 2-style tutorial, but I can´t bind values of my ViewModel to my Create View
Model:
public class WebPages
{
[Key]
public int WebPagesId { get; set; }
public String DomainName { get; set; }
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public DateTime DomainStart { get; set; }
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public DateTime DomainExp { get; set; }
public String DomainEmails { get; set; }
public String DomainUsers { get; set; }
public String DomainPasswords { get; set; }
}
}
ViewModel:
public class WebPagesViewModel
{
[Key]
public int Id { get; set; }
public String DomainName { get; set; }
public class Domain
{
public String DomainEmails { get; set; }
public String DomainUsers { get; set; }
public String DomainPasswords { get; set; }
}
public List<Domain> Domains { get; set; }
}
}
Create GetController
public ActionResult Create(WebPages model)
{
var ejemdata = new List<WebPagesViewModel.Domain>
{
new WebPagesViewModel.Domain
{
DomainEmails = "email#gmail.com",
DomainUsers = "Testuser",
DomainPasswords = "testpassword"
}
};
var vm = new WebPagesViewModel
{
Clients = new SelectList(db.ClientsList, "ClientsId", "ClientsName"),
Domains = ejemdata
};
return View(vm);
}
Create View:
#foreach (var item in Model.Domains)
{
{ Html.RenderPartial("_WebPagesPartial", item);}
}
Partial:
#using xxx.Models.ViewModels
#model WebPagesViewModel.Domain
#using HtmlHelpers.BeginCollectionItem
<h2>Partial View</h2>
<div>
#using (Html.BeginCollectionItem("Domains"))
{
Html.EditorFor(x => x.DomainPasswords);
Html.EditorFor(x => x.DomainUsers);
Html.EditorFor(x => x.DomainEmails);
}
I use breakpoint debug, and controller gets values from my ejemdata and it pass to my create view into foreach
Receiving data in View photo
So when the page loads it only loads label from partial but no display anything that is in BeginCollectionItem method and I get this on HTML
HTML:
<input type="hidden" name="Domains.index" autocomplete="off" value="28f4e8e7-cde3-44fe-a739-b4c8acb15ec2">
You use of
Html.EditorFor(x => x.DomainPasswords);
just calls the method but does not output its result. You need to change it to
#Html.EditorFor(x => x.DomainPasswords)
(and ditto for the other 2 HtmlHelpers)

Getting Values to Dropdown from Model

I am trying to pull a list from my ViewModel to populate a drop-down. I can get the objects from the Model and pass them to the View, but the view just shows the name of the ViewModel as the value in the dropdown. Not sure how to get the actual values to the Dropdown or if am going in the wrong direction. No intellesence past the definition of the object "model.InitialFeesChart". Thanks in advance for looking.
Controller: Objects contain needed data
public ActionResult CreateFranchise()
{
var model = new FranchiseVM();
model.FranStates = new List<string> { "AZ", "NV", "CA" };
//Grap the Package Identificaton to determine Package selected by Franshise
model.InitialFeesChart = (from f in _db.InitalFeesCharts
select new InitalFeesChartVM {IFCPackage = f.IFCPackage}).ToList();
return View(model);
}
ViewModel:
namespace Compass.Models
{
public class FranchiseVM
{
[Key]
public int FranchiseID { get; set; }
public string FranPID { get; set; }
public string FranBusinessName { get; set; }
public string FranAddress { get; set; }
public string FranCity { get; set; }
public string FranState { get; set; }
public string FranPostalCode { get; set; }
public string FranPhonePrimary { get; set; }
public string FranPhonePrimaryCell { get; set; }
public string FranFAX { get; set; }
public string FranOwnerFirstName { get; set; }
public string FranOwnerLastName { get; set; }
public string FranAlternateFirstName { get; set; }
public string FranAlternateLastName { get; set; }
public string FranAlternatePhone { get; set; }
public string FranNotes { get; set; }
public string IFCPackageCurrent { get; set; }
public IList<string> FranStates { get; set; }
//public IList<InitalFeesChartVM> InitialFeesChart { get; set; }
//Added
public string IFCPackage { get; set; }
private readonly List<InitialFeesChart> _InitialFeesChart;
public IEnumerable<SelectListItem> IFCItems
{
get { return new SelectList(_InitialFeesChart, "InitialFeesID", "IFCPackage"); }
}
}
}
View:
<div class="form-group">
#Html.LabelFor(model => model.IFCPackageCurrent, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.IFCPackageCurrent, Model.IFCItems))
</div>
</div>
Final working code:
ViewModel
public IList<InitalFeesChartVM> InitialFeesChart { get; set; }
[Display(Name = "Franchise Package")]
public string IFCPackageCurrent { get; set; }
View:
<div class="form-group">
#Html.LabelFor(model => model.IFCPackageCurrent, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.IFCPackageCurrent, new SelectList(Model.InitialFeesChart, "InitialFeesID", "IFCPackage"))
</div>
</div>
Controller:
public ActionResult CreateFranchise()
{
var model = new FranchiseVM();
model.FranStates = new List<string> { "AZ", "NV", "CA" };
model.InitialFeesChart = (from f in _db.InitalFeesCharts select new InitalFeesChartVM { IFCPackage = f.IFCPackage, InitialFeesID = f.InitialFeesID }).ToList();
return View(model);
You need to specify what properties to use in the Select List. Specify the value field and the text field like this: SelectList(Items, "Id", "Title")
I've created a fiddle that uses your classes. You will have to change the string values in the part when the select list is created so that they match the properties you want to use from your InitalFeesChartVM http://dotnetfiddle.net/9052ZH

One-to-many dropdownlist suggestion

I'm having hard time trying to figure out which way to go.
Before i start, here some of the classes :
public class Car
{
[Key]
[Required]
[DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[Required]
[MaxLength(255)]
public string Title { get; set; }
[Required]
public DateTime Date{ get; set; }
public virtual Category Category { get; set; }
}
public class Category {
[Key]
[Required]
[DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public int ID {get;set;}
public Category Parent{get;set;}
[Required]
[MaxLength(255)]
public string Title {get;set;}
}
So, to create a new "Car", I simply need a page with a dropdown for all of the categories. To do that, I wrote a new class and passed it to "ActionResult Create"...
Here it is :
public class CarCreate
{
public Car Car { get; set; }
public List<Category> Categories
{
get
{
List<Category> list = new List<Category>();
SystemContext sc = new SystemContext();
list = sc.Categories.ToList();
list.Insert(0, null);
sc.Dispose();
return list;
}
}
}
And from the controller I passed it like this:
public ActionResult Create()
{
return View(new CarCreate());
}
And within the view, I created a dropdown for List in CarCreate class:
<div class="col-md-4">
#Html.LabelFor(t => t.Car.Title)
#Html.TextBoxFor(model => model.Car.Title, new { #class = "form-control" })
</div>
<div class="col-md-4">
#Html.LabelFor(t => t.Car.Category)
#Html.DropDownListFor(model => model.Car.Category, new SelectList(Model.Categories, "ID", "Title","Select"), new { #class = "form-control" })
</div>
And when I check the Car.Category within the ActionResult that handles postback like this:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CarCreate emc)
{
Response.Write(emc.Car.Title);
Response.Write(emc.Car.Category== null ? "null" : "notnull");
return View(new CarCreate());
}
I can get title. But category is always null.
What would I have to do to get category from postback?
DropDownListFor is mapped with a value wich is defined by the option selected in the select.
You try to set this value in a complex object.
I think you should have a things like
public class Car
{
[Key]
[Required]
[DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[Required]
[MaxLength(255)]
public string Title { get; set; }
[Required]
public DateTime Date{ get; set; }
public virtual int CategoryID { get ; set;}
public virtual Category Category { get; set; }
}
And
<div class="col-md-4">
#Html.LabelFor(t => t.Car.Category)
#Html.DropDownListFor(model => model.Car.CategoryID, new SelectList(Model.Categories, "ID", "Title","Select"), new { #class = "form-control" })
</div>
I believe it's because your Category is not instanciate. Try to add this in the Car constructor :
public class Car
{
public Car()
{
this.Category = new Category();
}
}
Hope it helps !
I would keep my viewmodels as lite as i can. Just keep the properties you really need in your view. Also i prefer to keep those as simple POCO's(not with data loading logic in that) so that i can use that in many places.
public class CreateCarVM
{
[Required]
public string Title { set;get;}
public List<SelectListItem> Categories { set;get;}
[Required]
public int SelectedCategory { set;get;}
public CreateCarVM()
{
Categories =new List<SelectListItem>();
}
}
and in my create action method,
public ActionResult Create()
{
var vm=new CreateCarVM();
vm.Categories=GetCategories();
return View(vm);
}
private List<SelectListItem> GetCategories()
{
var list=new List<SelectListItem>();
//2 items hard coded for demo. You may load it from db
list.Add(new SelectListItem { Value="1", Text="Sedan"});
list.Add(new SelectListItem { Value="2", Text="SUV"});
return list;
}
and in your View which is strongly typed to the CreateCarVM
#model CreateCarVM
#using(Html.BeginForm())
{
#Html.TextBoxFor(s=>s.Title)
#Html.DropDownListFor(s=>s.SelectedCategory,Model.Categories,"Select")
<input type="submit" />
}
Now when the form is posted, You can check the SelectedCategory property of the viewmodel
[HttpPost]
public ActionResult Create(CreateCarVM model)
{
if(ModelState.IsValid)
{
//check for model.SelectedCategory now
// to do :Save and Redirect (PRG pattern)
}
model.Categories=GetCategories();
return View(model);
}

Categories

Resources