View
#Html.DropDownListFor(m => m.InsertCustomer.CountryID, Model.lstCountry, new { #class = "DropDownListFor" })
#Html.ValidationMessageFor(m =>m.InsertCustomer.CountryID)
View Model
[Required(ErrorMessage = "Please Select Country")]
public string CountryID { get; set; }
Method to create a list for the dropdown
public IEnumerable<SelectListItem> getCountry()
{
DNC_DAL.clsCustomerMaster _objDalUser = new DNC_DAL.clsCustomerMaster();
DataTable dtCountry = new DataTable();
dtCountry = _objDalUser.GetCountry();
List<SelectListItem> lstCountry = new List<SelectListItem>();
SelectListItem firstOption = new SelectListItem() { Text = "---Select One---" };
lstCountry.Add(firstOption);
foreach (DataRow drCountry in dtCountry.Rows)
{
SelectListItem Country = new SelectListItem() { Text = drCountry["DCM_DESC"].ToString(), Value = drCountry["DCM_ID"].ToString() };
lstCountry.Add(Country);
}
return lstCountry;
}
Controller
public ActionResult wfrmCustomerMaster()
{
Models.clsCustomerMaster CustomerModel = new Models.clsCustomerMaster();
IEnumerable<SelectListItem> strCountry = null;
strCountry = CustomerModel.getCountry();
CustomerModel.lstCountry = strCountry;
return View(CustomerModel);
}
All the other validations( Not posted in the question) work perfectly on the page except for the dropdown validation, I wonder why?
Your code is adding the first option as
<option>---Select One---</option>
which does not have a value="" attribute, which means if you select it, the value of the <select> element will be "---Select One---", which is valid (i.e. its not null or an empty string).
Instead, to generate a label option with a null value, use the overload that accepts a optionLabel, which will generate the first option as
<option value="">---Select One---</option>
and remove the code in the getCountry() which generates this option
Related
In my viewmodel I've a getter property as below.
[Display(Name = "Users System:")]
public string UsersSystem { get; set; }
public IEnumerable<SelectListItem> SystemsList
{
get
{
List<SelectListItem> lst = new List<SelectListItem>();
string[] UsersSystem = ConfigurationManager.AppSettings["UsersSystem"].ToString().Split(new char[] { ',' });
foreach (var item in UsersSystem)
{
lst.Add(new SelectListItem { Text = item, Value = item });
}
return lst;
}
}
I need to bind the values to a dropdownlist but I m getting Object reference not set to an instance of an object. My view has the following mark up
#model GazetteerAddressRequest.Lib.Model.ChangeRequestModel
#Html.DropDownListFor(model => model.UsersSystem, Model.SystemsList , new { #class = "form-control" })
Any ideas? thanks
As Stephen has mentioned you can't use the same name for the model property and the SelectList. Add a new property in ChangeRequestModel to hold the value of the selected item in the Dropdown.
public string UserSystemSelected { get; set; }
In your View
#Html.DropDownListFor(model => model.UserSystemSelected, Model.UsersSystem, new { #class = "form-control" })
Here you are populating the dropdown with Model.UsersSystem which has the list of all the SelectListItem and the VALUE SELECTED from the dropdown gets binded to UserSystemSelected.
EDIT:
You can also try this:
In your controller, inside the Action method
ViewBag.SystemList = new SelectList(
ConfigurationManager.AppSettings["UsersSystem"].ToString()
.Split(',')
.Select(x => new KeyValuePair<string, string>(x, x)),"Key", "Value");
And in your View
Html.DropDownListFor(m => m.UserSystemSelected, (SelectList)ViewBag.SystemList)
You have to pass the model into view, otherwise the model will be null in view.
Eg. first you can pass the SelectListItem list into ChangeRequestModel and then that into the view.
public ActionResult YourPage(){
return View(changeRequestModel);
}
I am really stuck here for a long time and I don't know why its not working. I followed this post where it explained how to implement validation in MVC. But not working for me.
My problem is I am able to display list in drop down but it is not showing any error message when I am in default option which was supposed to display error message.
My code is show below :
Model class :
public class ValidationModel
{
public IEnumerable<SelectListItem> options { get; set; }
[Required(ErrorMessage = "Please select atleast one mode")]
public int optionselected { get; set; }
}
Controller :
public ActionResult validation()
{
var validation = new ValidationModel();
validation.options = new List<SelectListItem>()
{
new SelectListItem() {Text = "Add or Update Customer", Value = "1" },
new SelectListItem() { Text = "Update Customer Credit", Value = "2"}
};
return View(validation);
View :
#using (Html.BeginForm("Validation", "home",FormMethod.Post))
{
#Html.DropDownListFor( m => m.optionselected, Model.options, "Select List")
#Html.ValidationMessageFor(m => m.optionselected)
<input type="submit" value="OK" />
}
Here by default select list option will be displayed in my drop downlist. But here I want my error message to be displayed. But it is not displaying. When user select value 1 or 2 then this error message should not display.
I tried using Modelstate also in my controller but not working :
[HttpPost]
public ActionResult Validation()
{
var validation = new ValidationModel();
validation.options = new List<SelectListItem>()
{
new SelectListItem() {Text = "Add or Update", Value="1"},
new SelectListItem() {Text = "Update Customer", Value="2"}
};
if (!ModelState.IsValid)
{
return View(model);
}
return RedirectToAction("bill");
}
The code blow might fulfill your expectation
public ActionResult validation()
{
var validation = new ValidationModel();
validation.options = new List<SelectListItem>()
{
new SelectListItem() {Text = "-- Select one --", Value = "" },
new SelectListItem() {Text = "Add or Update Customer", Value = "1" },
new SelectListItem() { Text = "Update Customer Credit", Value = "2"}
};
return View(validation);
}
#using (Html.BeginForm("Validation", "home",FormMethod.Post))
{
#Html.DropDownListFor( m => m.optionselected, Model.options)
#Html.ValidationMessageFor(m => m.optionselected)
<input type="submit" value="OK" />
}
After spending long time with this stupid validation, i got to know I just had to change order of scripts in my layout.cshtml. Thanks to this post. Bloody MVC!!!
I have an action that retrieves data and sends it to a view. In a view I have two dropdown menus.
First drop down shows salutation (such as "Mr.", "Ms.", etc.) and does not select value I sent for some reason. The other dropdown shows language list and correctly selects value I sent to the view. The relevant code in view is shown below.
#Html.DropDownListFor(model => model.Salutation, ViewBag.salutation as IEnumerable<SelectListItem>)
#Html.DropDownListFor(model => model.Language, ViewBag.languages as IEnumerable<SelectListItem>)
In the controller I have the following code to get the dropdown data.
ViewBag.salutation = new List<SelectListItem>() {
new SelectListItem() { Text = "", Value = "" },
new SelectListItem() { Text = "Mr.", Value = "Mr." },
new SelectListItem() { Text = "Ms.", Value = "Ms." },
new SelectListItem() { Text = "Mrs.", Value = "Mrs." }
};
and
var languages = (from l in db.Languages.ToList()
select new SelectListItem()
{
Text = l.Language,
Value = l.LanguageId.ToString()
}).ToList();
languages.Insert(0, new SelectListItem() { Text = "", Value = "" });
ViewBag.languages = languages;
The only difference I could think of is that the languages dropdown has an integer as value, whereas salutation dropdown has text as value. Is this why the salutation dropdown doesn't work? I know I could go through each salutation List<SelectListItem> item and set Selected property based on the value I retrieved from database. But I was hoping there would be a cleaner way to do this.
Any ideas?
Thanks
UPDATE
I decided to do what I did for another project.
IList<SelectListItem> _salutation = new List<SelectListItem>()
{
new SelectListItem() { Value = "", Text = "" },
new SelectListItem() { Value = "Mr.", Text = "Mr." },
new SelectListItem() { Value = "Ms.", Text = "Ms." },
new SelectListItem() { Value = "Mrs.", Text = "Mrs." }
};
// I could put the following in the declaration above, but for testing purposes it's in foreach loop.
foreach (var item in _salutation)
{
// compare to what's retrieved from database
item.Selected = item.Value == _viewData.Salutation;
}
ViewBag.salutation = _salutation;
After foreach loop I output .Value, .Selected property of each item in _salutation and I get all the correct values with one item being selected. Inside the view I did the following.
#foreach (var item in ViewBag.salutation as IEnumerable<SelectListItem>)
{
<b>#item.Value : #item.Text : #item.Selected</b><br />
}
All the correct Text/Values come up but none are Selected! This happens if I output the values after I execute #Html.DropDownListFor(). If I output the ViewBag.salutation before the html helper the correct value is selected.
SOLUTION
I found the following article useful: DropDownListFor with ASP.NET MVC.
Instead of using ViewBag I added the following to the ViewModel. (Showing the part for salutations drop down.)
public class TheViewModel
{
private IList<string> _salutations = new List<string>() { "", "Mr.", "Ms.", "Mrs." };
public IEnumerable<SelectListItem> SalutationItems
{
get
{
var salutations = _salutations.Select(s => new SelectListItem { Value = s, Text= s });
return salutations;
}
}
// The rest of the ViewModel
}
And in the View I have the following.
#Html.DropDownListFor(model => model.Salutation, Model.SalutationItems)
Instead of just supplying the list to the DropDownListFor helper you could provide it a SelectList. The SelectList constructor takes the list and allows you to explicitly set the selected value as well as an overload that lets you specify the Text and Value fields.
#Html.DropDownListFor(model => model.Salutation,
new SelectList(ViewBag.salutation as IEnumerable<SelectListItem>,
"Value", "Text", Model.Salutation))
Try this,
#Html.DropDownListFor(m =>m.DDCountryModel,IEnumerable<SelectListItem>)ViewBag.salutation)
#Html.DropDownListFor(model => model.Language, IEnumerable<SelectListItem>)ViewBag.languages)
Your Model should be like this,
public class Model
{
public IEnumerable<SelectListItem> DDCountryModel{ get; set; }
public IEnumerable<SelectListItem> Language{ get; set; }
}
I have one static dropdown list in my view
<select>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
I want to bind this drop down list with my model so that when I submit selected value of drop down , I get that value from model in my controller.
Also I want to select option in drop down as per data in my model.
I just made list item for static dropdown list & passed it to dropdown list where I binded it with my viewmodel.
#{
var listItems = new List<ListItem> {new ListItem {Text = "Single", Value = "Single"}, new ListItem {Text = "Married", Value = "Married"}, new ListItem {Text = "Divorse", Value = "Divorse"}};
}
#Html.DropDownListFor(model => model.EmployeeDetail.MaritalStatus, new SelectList(listItems),"-- Select Status --")
It works perfectly for me as it shows value which comes from model & also stores value of dropdown list in model when I submit data.
Instead of constructing the drop down list in HTML, build it in your service/controller and add it to your model:
ViewModel:
public class YourViewModel
{
public string SelectedCarManufacturer { get; set; }
public Dictionary<string, string> CarManufaturers { get; set; }
// your other model properties
}
Controller get action method
[HttpGet]
public ActionResult SomeAction()
{
var model = new YourViewModel
{
SelectedCarManufacturer = null, // you could get this value from your repository if you need an initial value
CarManufaturers = new Dictionary<string, string>
{
{ "volvo", "Volvo" },
{ "saab", "Saab" },
{ "audi", "Audi" },
/// etc.
}
};
return this.View(model);
}
In your view, replace the hard coded drop down list with:
#Html.DropDownListFor(m => m.SelectedCarManufacturer , new SelectList(Model.CarManufaturers , "Key", "Value"), "Select a manufacturer...")
Controller post action method
[HttpPost]
public ActionResult SomeSaveAction(YourViewModel model)
{
// do something with the model...
// model.SelectedCarManufacturer
}
OR
[HttpPost]
public ActionResult SomeSaveAction()
{
var model = someService.BuildYourViewModel()
this.TryUpdateModel(model);
// do something with the model...
someService.SaveYourViewModel(model);
}
I hope this helps...
in controller
List<SelectListItem> items = new List<SelectListItem>();
items.Add(new SelectListItem { Text = "Volvo", Value = "volvo"});
items.Add(new SelectListItem { Text = "Saab", Value = "saab" });
items.Add(new SelectListItem { Text = "Mercedes", Value = "mercedes" });
items.Add(new SelectListItem { Text = "Audi", Value = "audi" });
on view
Html.DropDownListFor(Model.items)
I have this VM properties
public IList<Guid> SelectedEligiableCategories { get; set; }
public IList<SelectListItem> EligiableCategories { get; set; }
I have this helpers in my view
#Html.LabelFor(x => x.EligibleCategoryFrmVm.SelectedEligiableCategories, "Eligible Categories:")
#Html.ListBoxFor(x => Model.EligibleCategoryFrmVm.SelectedEligiableCategories, Model.EligibleCategoryFrmVm.EligiableCategories, new { #class = "eligibleCategoryListBox" })
I have this code in my controller
List<SelectListItem> eligibleCategoriesListItems = Mapper.Map<List<EligibleCategory>, List<SelectListItem>>(eligibleCategories);
foreach (var rewardTier in creditCard.RewardTiers)
{
CbRewardTierFrmVm rewardTierFrmVm = new CbRewardTierFrmVm();
rewardTierFrmVm.EligibleCategoryFrmVm.EligiableCategories = eligibleCategoriesListItems;
foreach (var ec in rewardTier.EligibleCategories)
{
rewardTierFrmVm.EligibleCategoryFrmVm.SelectedEligiableCategories.Add(ec.Id);
}
vm.CbRewardTierFrmVm.Add(rewardTierFrmVm);
}
Yet when I load up my view. None of values for my ListBox are selected. I am not sure why. If this was a selectList this would work as it would match up the SelectedEligiableCategories to the value in the list.
I am not sure if this is because there is multiple selects
Edit
<select name="CbRewardTierFrmVm[63b504c0-0f9a-47ba-a8ff-db85f48d5f0f].EligibleCategoryFrmVm.SelectedEligiableCategories" multiple="multiple" id="CbRewardTierFrmVm_63b504c0-0f9a-47ba-a8ff-db85f48d5f0f__EligibleCategoryFrmVm_SelectedEligiableCategories" data-val-required="Must choose at least one eligible category." data-val="true" class="eligibleCategoryListBox ui-wizard-content ui-helper-reset ui-state-default" style="display: none;">
<option value="ed2bb5f9-4565-4f69-ab15-9fca011c0692">Gas</option>
</select>
Do you think it is because I am using http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/ ?
Edit2
I gone ahead and make an example. I must be missing something(not sure what). When I use "Darin Dimitrov" it works.
I switched the example to a dropdown as I am getting the same problem with it as well.
In this example I am not using a viewmodel since my initial assumption was somehow the helper I was using from Steven Sanders might be effecting it so I was going off his example.
This does not seem to be the case as I removed it and still get this problem.
public class Gift
{
public string Name { get; set; }
public double Price { get; set; }
public string SelectedItem { get; set; }
public IList<SelectListItem> Items { get; set; }
}
public ActionResult Index()
{
List<SelectListItem> items = new List<SelectListItem>
{
new SelectListItem {Value = "",Text ="--"},
new SelectListItem {Value = "1",Text ="1"},
new SelectListItem {Value = "2",Text ="2"},
};
var initialData = new[] {
new Gift { Name = "Tall Hat", Price = 39.95, Items = items, SelectedItem = "2" },
new Gift { Name = "Long Cloak", Price = 120.00, Items = items, SelectedItem = "1" }
};
return View("Index3",initialData);
}
#model IList<EditorDemo.Models.Gift>
#{
ViewBag.Title = "Index3";
}
#for (int i = 0; i < Model.Count; i++)
{
#Html.DropDownListFor(x => x[i].SelectedItem, new SelectList(Model[i].Items, "Value", "Text"))
}
It seems to not be able to handle when you put it in forloop and try it make more than one dropdown list.
The following works for me.
Model:
public class MyViewModel
{
public IList<Guid> SelectedEligiableCategories { get; set; }
public IList<SelectListItem> EligiableCategories { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
SelectedEligiableCategories = new[]
{
// preselect the second and the fourth item
new Guid("35830042-3556-11E1-BCDC-A6184924019B"),
new Guid("4253876A-3556-11E1-BC17-B7184924019B")
}.ToList(),
EligiableCategories = new[]
{
new SelectListItem { Value = "2DA62E3A-3556-11E1-8A0A-9B184924019B", Text = "item 1" },
new SelectListItem { Value = "35830042-3556-11E1-BCDC-A6184924019B", Text = "item 2" },
new SelectListItem { Value = "3D07EBAC-3556-11E1-8943-B6184924019B", Text = "item 3" },
new SelectListItem { Value = "4253876A-3556-11E1-BC17-B7184924019B", Text = "item 4" },
}
};
return View(model);
}
}
View:
#model MyViewModel
#using (Html.BeginForm())
{
#Html.ListBoxFor(
x => x.SelectedEligiableCategories,
Model.EligiableCategories,
new { #class = "eligibleCategoryListBox" }
)
}
Result:
UPDATE:
Now that you have shown an example allowing to illustrate the problem, you could specify the selected item when building the SelectList:
#Html.DropDownListFor(
x => x[i].SelectedItem,
new SelectList(Model[i].Items, "Value", "Text", Model[i].SelectedItem)
)
The reason a value was not preselected was because you were binding the dropdownlist to a list of properties (x => x[i].SelectedItem) whereas in my example I was using a simple property.
And if you wanted to do this with the ListBoxFor helper you could use the following:
#Html.ListBoxFor(
x => x[i].SelectedItems,
new MultiSelectList(Model[i].Items, "Value", "Text", Model[i].SelectedItems)
)
The SelectedItems property becomes a collection and we use a MultiSelectList instead of a SelectList.
The main problem is using
#Html.DropDownListFor
instead of this
#Html.ListBoxFor
Using the DropDownListFor will NOT help you with multiple values, whatever you do and no matter what your model is. Once you use ListBoxFor ... it will automatically just work !