I am having a problem with a selectlistitem, the values of which are being retrieved from a database.
It is displaying the list of items in the view, but it is not passing through (POSTing) the selected value into the model.
So when the user submits, or the page reloads due to validation, the select value (PositionApplied) is empty.
Can anyone give me some pointers as to where I am going wrong?
In my controller:
[HttpGet]
public ActionResult Index()
{
PopulateJobsDropdown();
return View();
}
private void PopulateJobsDropdown()
{
IEnumerable<SelectListItem> items = _service.GetJobs()
.Select(c => new SelectListItem
{
Value = c.JobID.ToString(),
Text = c.JobTitle
});
ViewData["PositionApplied"] = items;
}
In my ViewModel
public IEnumerable<SelectListItem> PositionApplied { get; set; }
In my View
<%=Html.DropDownList("PositionApplied")%>
Thanks in advance for any pointers!
So, where is the code line that get's the
ViewData["PositionApplied"] = items;
into
public IEnumerable<SelectListItem> PositionApplied { get; set; }
something like:
this.PositionApplied = ViewData["PositionApplied"] as IEnumerable<SelectListItem>;
and you can simple use in your View:
<%
IEnumerable<SelectListItem> PositionApplied =
ViewData["PositionApplied"] as IEnumerable<SelectListItem>;
%>
...
<%= Html.DropDownList("myDropDOwnId", PositionApplied) %>
or is there some of automagical happening under MVC2 that I'm not aware about? As I use the example I give you, all the time.
Added
in order to avoid Linq to Entities error (if you are using it) change your method to
private void PopulateJobsDropdown()
{
IQueryble<Your_Table> jobs = _service.GetJobs();
List<SelectListItem> items = new List<SelectListItem>();
foreach(var job in jobs)
items.add(new SelectListItem
{
Value = c.JobID.ToString(),
Text = c.JobTitle
});
ViewData["PositionApplied"] = items;
}
and all will work fine.
Related
I have problem with the data that I select from table tblemployee that I want to bind it to the dropdownlist.
model
public class UserModels
{
public string EmployeeName { get; set; }
public int EmployeeCode { get; set; }
public IEnumerable<SelectListItem> Employee { set; get; }
}
Controller
public ActionResult Education() {
var query = (from e in context.tblEmployee_Employee
select new
{
empID = e.Code,
EmpName = e.NameEng
}
).ToList();
var model = new UserModels();
var _Emp = query;
foreach (var item in _Emp)
{
model.EmployeeCode = item.empID;
model.EmployeeName = item.EmpName;
model.Employee = new SelectList(_Emp, "EmpName", "EmpName");
}
return View(model);
}
View
<%= Html.DropDownListFor(x => x.EmployeeName, Model.Employee, "select EmployeeName")%>
And I got the error message "Object reference not set an instance of an object".Anyone know please kindly tell me how to solve it.
Thanks,
Try like this:
public ActionResult Education()
{
var model = new UserModels();
model.Employee = context
.tblEmployee_Employee
.ToList()
.Select(e => new SelectListItem
{
Value = e.Code.ToString(),
Text = e.NameEng
});
return View(model);
}
And make sure that your view is strongly typed to the UserModels view model and then:
<%= Html.DropDownListFor(
x => x.EmployeeName,
Model.Employee,
"select EmployeeName"
) %>
I am creating a record in a table that has foriegn key in it. The foriegn key is getting passed in the query string and I have set the value in the ViewBag. I have added this to the form but it will not work.
Here is the code from the controller:
public ActionResult Create(int propertyId)
{
ViewBag.storagePropertyId = propertyId;
return View();
}
Here is the code from the view.
#Html.HiddenFor(model => model.propertyId, new { value =ViewBag.propertyId })
Is this how I should be doing this? If so, is there a problem with that form
Why not just set the value of the Model.PropertyID in the controller, or better yet in a viewmodel.
ViewModel
public class MyViewModel()
{
public int PropertyID { get; set; }
public MyViewModel() { }
public MyViewModel(int propertyID)
{
this.PropertyID = propertyID;
}
}
Action Result
public ActionResult Create(int propertyId)
{
return View(new MyViewModel(propertyId));
}
View
#model MyViewModel
#Html.HiddenFor(m => m.PropertyID)
Then the value of the Hidden field will contain the value of the property ID.
I have a model which has a field
[DisplayName("Receive occasional email notifications about new services or features")]
public bool ReceiveEmail { get; set; }
In my view I want a checkbox which will come checked by default.
I tried this:
<%:Html.CheckBoxFor(m => m.registerModel.ReceiveEmail, new { #checked = "checked" })%>
But did not work...
Any help will be appreciated.
Thanks
Arnab
The proper way to do this is to set your view model property in the controller action rendering this view:
public ActionResult Foo()
{
var model = new MyViewModel
{
registerModel = new registerModel
{
ReceiveEmail = true
}
};
return View(model);
}
Now all you need in your strongly typed view is:
<%= Html.CheckBoxFor(m => m.registerModel.ReceiveEmail) %>
and the checkbox will be automatically checked.
I am trying to figure out how this DropDownListFor works but with no success.
My controller creates a list of SelectListItems where I put all the groups found in the database:
viewModel.Groups = LoadGroups(viewModel.User.AssociatedGroups);
this it the method:
private IList<SelectListItem> LoadGroups(List<String> associatedGroups)
{
var groups = _SecurityService
.LoadGroups()
.Select(e => new SelectListItem
{
Selected = associatedGroups.Contains<System.String>(e.Id.ToString()),
Value = e.Id.ToString(),
Text = e.Name
}).ToList();
return (groups);
}
As you can see I set the Selected element if there are associated groups in the list.
I put this list in a field (Groups) of my custom viewmodel:
public class UsersViewModel
{
public UsersViewModel()
{
this.Groups = new List<SelectListItem>();
}
public Models.User User { get; set; }
public IList<SelectListItem> Groups { get; set; }
}
and send UsersViewModel to the view. I use this code to build a dropdown with multi-selection:
<%=Html.DropDownListFor(m => m.User.AssociatedGroups, (List<System.Web.Mvc.SelectListItem>)Model.Groups, new { #class = "dropDownGroups", multiple = "multiple" })%>
AssociatedGroups is a field the class Users (which is a member of my viewmodel):
public List<String> AssociatedGroups { get; set; }
There's nothing peculiar here.
If I use this code I can I can't see the elements of the dropdown selected (and they have the attribute set, I've double checked), but I can bind the selections with AssociatedGroups when I post the form.
If I change AssociatedGroups (field of the User class) with a string:
public String AssociatedGroups { get; set; }
I have the opposite behaviour:
I can see the elements of the dropdown checked but when I post the form there's no binding, or better, only one element is bound.
I've spend most of my day trying to figure out what the problem and I've tried different combinations but none of them seem to work.
Is there anyone who can try to help me?
Thanks.
You need two properties on your view model: one that will contain the selected group ids and one that will contain the list:
public class UsersViewModel
{
public IEnumerable<SelectListItem> Groups { get; set; }
public IEnumerable<string> SelectedGroupIds { get; set; }
}
and then you would use the ListBoxFor helper to allow for multiple choices:
<%= Html.ListBoxFor(
m => m.SelectedGroupIds,
new SelectList(Model.Groups, "Value", "Text"),
new { #class = "dropDownGroups" }
) %>
Now assuming the following view model is passed to the view:
public ActionResult Index()
{
var model = new UsersViewModel
{
// TODO: Use a repository to fetch those values
// and map them to the view model
Groups = new[]
{
new SelectListItem { Value = "1", Text = "group 1" },
new SelectListItem { Value = "2", Text = "group 2" },
new SelectListItem { Value = "3", Text = "group 3" },
},
// We want to preselect the last two groups in the listbox
SelectedGroupIds = new[] { "2", "3" }
};
return View(model);
}
[HttpPost]
public ActionResult Index(IEnumerable<string> selectedGroupIds)
{
// Here we will get the list of selected ids
// when the form containing the listbox is
// submitted
...
}
Then on the view the last two elements will be automatically preselected.
Im new to MVC2/3 so keep that in mind. Also, using Ajax or jQuery is NOT an option.
I have a web page where the user must choose an item out of a dropdown list and then hit a "Filter" button. (Clicking this button will simply trigger the default POST action in my controller and return a filtered list of results.
I have everything working except I am running into one issue. When the Filter action is complete and returns control back to my view, the dropdown list contents are lost (ie, null). The results are returned no problem, it's just that my dropdown list is blank - thus preventing user from selecting another item out of the list.
Am I supposed to re-fill the dropdown list on the Filter action or is there a cleaner way to do this?
Here is a snapshot of my code:
My ViewModel
public class MyViewModel {
[DisplayName("Store")]
public IEnumerable<Store> StoreList { get; set; }
public string SelectedStore { get; set; }
}
My View (Index.cshtml)
#using (Html.BeginForm()) {
<h2>Search</h2>
#Html.LabelFor(m => m.StoreList)
#Html.DropDownListFor(m => m.SelectedStore, new SelectList(Model.StoreList, "StoreCode", "StoreCode"), "Select Store")
<input type="submit" value="Filter" />
}
My Controller:
public class MyController : Controller
{
public ActionResult Index() {
MyViewModel vm = new MyViewModel();
var storelist = new List<Store>();
storelist.Add(new Store { StoreCode = "XX" });
storelist.Add(new Store { StoreCode = "YY" });
storelist.Add(new Store { StoreCode = "ZZ" });
vm.StoreList = storelist;
return View(vm);
}
[HttpPost]
public ActionResult Index(MyViewModel model, string SelectedStore, FormCollection collection) {
if (ModelState.IsValid) {
/* this works, model state is valid */
/* BUT, the contents of model.StoreList is null */
}
return View( model);
}
}
Yes, you have to repopulate any models (including ViewData) that are passed to the view. Remember, it's a stateless system, your controller is re-instantiated with every call and starts effectively from scratch.
I would do it thus:
public class MyController : Controller
{
private List<Store> GetStoreList()
{
List<Store> StoreList = new List<Store>();
// ... Do work to populate store list
return StoreList;
}
public ActionResult Index() {
MyViewModel vm = new MyViewModel();
vm.StoreList = GetStoreList();
return View(vm);
}
[HttpPost]
public ActionResult Index(MyViewModel model, string SelectedStore, FormCollection collection) {
if (ModelState.IsValid) {
/* this works, model state is valid */
/* BUT, the contents of model.StoreList is null */
}
model.StoreList = GetStoreList();
return View( model);
}
}
Short answer is yes, you need to refill the drop-down list in the Filter action. ASP.NET MVC isn't WebForms - there is no ViewState to preserve the contents of your list.
Again fill the dropdown as mvc don't have View state
[HttpPost]
public ActionResult Index(MyViewModel model, string SelectedStore, FormCollection collection) {
if (ModelState.IsValid) {
/* this works, model state is valid */
/* BUT, the contents of model.StoreList is null */
}
model.StoreList = GetStoreList();
return View( model);
}