I was wondering if there was a way to pass more than 1 list to a view to render.
Here is my code in PeopleController
public ActionResult Index()
{
EmployeeContext db = new EmployeeContext();
//Sites
List<SelectListItem> listSelectListItem = new List<SelectListItem>();
foreach (Sites loc in db.Locations)
{
SelectListItem selectListItem = new SelectListItem()
{
Text = loc.HRSite,
Value = loc.HRSite
};
listSelectListItem.Add(selectListItem);
}
SiteViewModel siteViewModel = new SiteViewModel();
siteViewModel.Sites = listSelectListItem;
//Cost Centers
List<SelectListItem> listSelectListItem2 = new List<SelectListItem>();
foreach (CostCenter cc in db.CostCenterNumbers)
{
SelectListItem selectListItem = new SelectListItem()
{
Text = cc.CostCenterNumber,
Value = cc.CostCenterNumber
};
listSelectListItem2.Add(selectListItem);
}
CCViewModel ccViewModel = new CCViewModel();
ccViewModel.CostCenter = listSelectListItem2;
List<object> myModel = new List<object>();
myModel.Add(siteViewModel);
myModel.Add(ccViewModel);
return View(myModel);
Here is my View:
#model IEnumerable<object>
#{
List<MVCDemo.Models.CostCenter> lstCostCenter = Model.ToList()[0] as List<MVCDemo.Models.CostCenter>;
List<MVCDemo.Models.Sites> lstLocation = Model.ToList()[1] as List<MVCDemo.Models.Sites>;
}
<h3>Cost Center</h3>
<ul>
#foreach (var item in lstCostCenter)
{
<li>#item.CostCenterNumber</li>
}
</ul>
<hr />
<h3>Site</h3>
<ul>
#foreach (var item in lstLocation)
{
<li>#item.HRSite</li>
}
</ul>
How can I change the view to contain 2 listboxes instead of 2 "lists"?
Create a concrete view containing a collection for each of your lists.
Then for each of your collections use
#Html.ListboxFor(m => m.YourCollection)
More info: https://msdn.microsoft.com/en-us/library/system.web.mvc.html.selectextensions.listboxfor(v=vs.118).aspx
I suggest creating a ViewModel to hold your data. It is far more convenient that simply passing "object" around. There are many benefits of it and one would be that you could use the strongly typed html helpers in razor.
Then you can use the #Html.ListboxFor as suggested by dan m
Related
I am a beginner to ASP.NET MVC technology. In my controller page I am using this code below
[HttpGet]
public ActionResult UrunEkle() {
List<SelectListItem> degerler = (from i in db.tblKategoriler.ToList()
select new SelectListItem
{
Text = i.KategoriAd,
Value = i.KategoriId.ToString()
}).ToList();
ViewBag.dgr = degerler;
return View(degerler);
}
this is view page
model MVCSTOK.Models.Entity.tblKategoriler
<div>
<label>Ürün Kategori</label>
#Html.DropDownListFor(m=>m.KategoriAd,(List<SelectListItem>)ViewBag.dgr, new { #class = "form-control" });
</div>
I am geting this error
The model item passed into the dictionary is of type System.Collections.Generic.List`1[System.Web.Mvc.SelectListItem]', but this dictionary requires a model item of type 'MVCSTOK.Models.Entity.tblKategoriler.
Your returning data's type isn't corresponding to MVCSTOK.Models.Entity.tblKategoriler, that you return it from UrunEkle() Action method. You return List<SelectListItem>, but your View's type of model is MVCSTOK.Models.Entity.tblKategoriler.
I think you can do (return view without model):
[HttpGet]
public ActionResult UrunEkle() {
List<SelectListItem> degerler = (from i in db.tblKategoriler.ToList()
select new SelectListItem
{
Text = i.KategoriAd,
Value = i.KategoriId.ToString()
}).ToList();
ViewBag.dgr = degerler;
return View();
}
And you can do this in .cshtml view (without model):
<div>
<label>Ürün Kategori</label>
#Html.DropDownListFor(m=>m.KategoriAd,(List<SelectListItem>)ViewBag.dgr, new { #class = "form-control" });
</div>
Below is my code of
view:
#model MvcDemo.Models.viewmodelCities
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div>
#using (#Html.BeginForm())
{
#Html.ListBoxFor(x => x.SelectedCities, Model.Cities, new {
size=#Model.Cities.Count()})
<br/>
<input type="submit" value="submit" />
}
</div>
model:
public class viewmodelCities
{
public IEnumerable<SelectListItem> Cities { get; set; }
public IEnumerable<String> SelectedCities { get; set; }
}
controller action method for Get:
[HttpGet]
public ActionResult Index()
{
EmployeeDbContext db = new EmployeeDbContext();
List<SelectListItem> listSelecteditem = new List<SelectListItem>();
foreach (tblCity city in db.tblCities)
{
SelectListItem selectListItem = new SelectListItem()
{
Text = city.Name,
Value = city.ID.ToString(),
Selected = city.IsSelected
};
listSelecteditem.Add(selectListItem);
}
viewmodelCities vmc = new viewmodelCities();
vmc.Cities = listSelecteditem;
return View(vmc);
}
& controller action method for post:
[HttpPost]
public string Index(IEnumerable<string> SelectedCities)
{
if(SelectedCities==null)
{
return "You did not select any city";
}
else
{
StringBuilder sb = new StringBuilder();
sb.Append("You selected - "+string.Join(",",SelectedCities));
return sb.ToString();
}
}
In the output when i select any cities, In the post method their ID's are automatically bound to the IEnumerable.So when i select cities with Id's:3 & 4 i get the below output.
You selected - 3,4
As you can see in the whole code i'm nowhere inserting values into selectCities. Since i'm newbie into mvc and don't completely understand it's conventions can someone explain how values are getting bound to the IEnumerable during postback? How can i tweak here to post the names of the cities instead of Id's?Is there a way to get around this?
PS:I got this code from an online tutorial
You actually are setting the values for selectCities.
In your view, you have the following form:
#using (#Html.BeginForm())
{
#Html.ListBoxFor(x => x.SelectedCities, Model.Cities, new {
size=#Model.Cities.Count()})
<br/>
<input type="submit" value="submit" />
}
Here, you're using the following line to generate the listbox:
#Html.ListBoxFor(x => x.SelectedCities, Model.Cities, new { size=#Model.Cities.Count()})
Take a look at the documentation for this function. This is how you're "inserting" the selected cities when you click the button.
Essentially, you are supplying the following to the function:
x => x.SelectedCities --> The cities that are selected in the listbox by default from your viewModel AND the Selectedcities that will be posted to the POST Index method of your controller when you submit the form.
Model.Cities --> All of the available options in the listbox from your viewModel.
new { size=#Model.Cities.Count()} --> Setting the HTML Attribute size.
Because you're using a form, whenever you click the "submit" button, the client sends IEnumerable<string> SelectedCities to your POST method, Index. This is how your controller is receiving the selected values and then outputting that text.
Hopefully that helps. I can try to clarify further if needed. I suggest reading the documentation for that function, and the BeginForm() function to get some more insight.
EDIT: I realized you were also asking how to set the selectedCities list. You would set this list the same way as you set your Cities member of your ViewModel in your GET Index method on your controller:
vmc.Cities = listSelecteditem;
You would just need to generate another list of models that represents the cities you want selected. How you implement that function is, of course, up to you.
For example:
[HttpGet]
public ActionResult Index()
{
EmployeeDbContext db = new EmployeeDbContext();
List<SelectListItem> listSelecteditem = new List<SelectListItem>();
foreach (tblCity city in db.tblCities)
{
SelectListItem selectListItem = new SelectListItem()
{
Text = city.Name,
// Tweaked to use Name instead of ID in post.
Value = city.Name,
Selected = city.IsSelected
};
listSelecteditem.Add(selectListItem);
}
viewmodelCities vmc = new viewmodelCities();
// Simply set your SelectedCities here, and it will be reflected on your page.
vmc.SelectedCities = SomeService.GetSomeCities(someFilter);
vmc.Cities = listSelecteditem;
return View(vmc);
}
where SomeService.GetSomeCities is a function I made up that would return IEnumerable<String> of City IDs. I also changed the initialization of the select list to use name as it's value instead of ID.
For a listbox control, the selected values are going to be posted. If you would like the city names instead of the IDs, you can set Value = city.Name when you are populating the SelectList.
foreach (tblCity city in db.tblCities)
{
SelectListItem selectListItem = new SelectListItem()
{
Text = city.Name,
Value = city.Name, // <-- change to this
Selected = city.IsSelected
};
listSelecteditem.Add(selectListItem);
}
Also, if you're interested in code golf, you can use LINQ's Select() extension to project your dbtblCities into a List<SelectListItem> without using a loop explicitly:
var listSelecteditem = db.tblCities.Select(x => new SelectListItem {
Text = city.Name,
Value = city.Name,
Selected = city.IsSelected }).ToList();
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
I have simple table with users, which have edit column, so when you click it, you can edit this specific row. One of columns in my tables is TimeZone, so you can choose in which time zone you are. So proper way to create edit filed is Dropdown list.
So I find this code and implemented it in my controller:
public ActionResult Edit(int id = 0)
{
using (var dbVn = new userDbEntities())
{
var edit = dbVn.UsersTables.Find(id);
if (edit == null)
{
return HttpNotFound();
}
SelectListItem item;
var zoneList = new List<SelectListItem>();
item = new SelectListItem();
item.Text = "TimeZone1";
item.Value = "1";
zoneList.Add(item);
item = new SelectListItem();
item.Text = "TimeZone2";
item.Value = "2";
zoneList.Add(item);
ViewBag.ZoneT = zoneList;
return View(edit);
}
}
And in my view I have this:
<div class="editor-field">
#Html.DropDownListFor(model => model.TimeZoneId, new SelectList((IEnumerable<SelectListItem>)ViewBag.ZoneT, "Value", "Text", "1"))
#Html.ValidationMessageFor(model => model.TimeZoneId)
</div>
This works fine if we would have a few items (3 to 4). But if we have a list of timezonese (96), is proper to use datatable (TimeZoneTable).
Any Idea how to implement it in above code in controller...
I have an edit page with a Html.DropDownList in it....I cant show the dropdownlist value it always shows up with Select instead i want to make the dropdown show an item as selected based on a model value say Model.Mes_Id... Any suggestion how it can be done...
<p>
<label for="MeasurementTypeId">MeasurementType:</label>
<%= Html.DropDownList("MeasurementType", // what should i give here?)%>
<%= Html.ValidationMessage("MeasurementTypeId", "*") %>
</p>
EDIT: It has the list items but i want to show a value selected in the edit view...
public ActionResult Edit(int id)
{
var mesurementTypes = consRepository.FindAllMeasurements();
ViewData["MeasurementType"] = mesurementTypes;
var material = consRepository.GetMaterial(id);
return View("Edit", material);
}
My repository method,
public IEnumerable<SelectListItem> FindAllMeasurements()
{
var mesurements = from mt in db.MeasurementTypes
select new SelectListItem
{
Value = mt.Id.ToString(),
Text= mt.Name
};
return mesurements;
}
Set the selected item when you create the IEnumerable<SelectListItem>.
Personally I would create a specialized viewmodel for the form but going by your code, do something like:
public ActionResult Edit(int id)
{
//Put this first
var material = consRepository.GetMaterial(id);
//pass in your selected item
var mesurementTypes = consRepository.FindAllMeasurements(material.MeasurementTypeId);
ViewData["MeasurementType"] = mesurementTypes;
return View("Edit", material);
}
Then change your repository method to something like:
public IEnumerable<SelectListItem> FindAllMeasurements(int selectedId)
{
var mesurements = from mt in db.MeasurementTypes
select new SelectListItem
{
Value = mt.Id.ToString(),
Text= mt.Name,
Selected = mt.Id == selectedId
};
return mesurements;
}
HTHs,
Charles
Have a look at this blog entry.
http://weblogs.asp.net/ashicmahtab/archive/2009/03/27/asp-net-mvc-html-dropdownlist-and-selected-value.aspx
Basically, you need to convert your mesurementTypes list/enumerable into a SelectList or IEnumerable<SelectListItem>.
I would recommend, if possible, upgrading to ASP.NET MVC2 and using Html.DropDownListFor()
You should be returning a SelectionList which can specify a selected item.
How to create a DropDownList with ASP.NET MVC
Assuming that Model.Mes_Id contais the selected value, you can do something like this
<%
var Measurements = new SelectList((IEnumerable)ViewData["MeasurementType"], "Id", "Name", Model.Mes_Id);
Response.Write(Html.DropDownList("measurement_type", Measurements, "Select"));
%>
Html.DropDownListFor didn't work for me So I got the poppy like this
(in Edit method )
CreatList(long.Parse(wc.ParentID.ToString()));
private void CreatList(long selected= 0)
{
SqlConnection conn = new SqlConnection(Config.ConnectionStringSimple);
conn.Open();
Category wn = new Category(conn);
CategoryCollection coll = new CategoryCollection();
Category.FetchList(conn, ref coll);
ViewBag.ParentID = GetList(coll, selected);
}
private List<SelectListItem> GetList(CategoryCollection coll, long selected)
{
List<SelectListItem> st = new List<SelectListItem>();
foreach (var cat in coll)
{
st.Add( new SelectListItem
{
Text = cat.Name,
Value = cat.ID.ToString(),
Selected = cat.ID == selected
});
}
SelectListItem s = new SelectListItem {
Text = Resources.lblSelect,
Value = "0"
};
st.Insert(0, s);
return st;
}
<div class="editor-label">
#Html.LabelFor(model => model.ParentID)
</div>
<div class="editor-field">
#Html.DropDownList("ddlCat", (List<SelectListItem>)ViewBag.ParentID)
#Html.ValidationMessageFor(model => model.ParentID)
</div>