How to assign value to dropdown for viewbag element? - asp.net-mvc

I am developing MCV app with Razor syntax.
I have pass the elements to the dropdown list and I want to show selected item in that dropdown from viewbag element.
below code displays the dropdow code.
Controller Code
[SessionFilterAction]
public ViewResult Details(int id)
{
ViewBag.HODList = new SelectList(db.Employees.Where(e => e.DesignationType == "HOD"), "Id", "FullName");
ViewBag.ItemToBeSelectedInList = 5;
return View(paymentadvice);
}
View Code
if(ViewBag.DesignationTypeOfLoggedUser == "Staff")
{
#Html.DropDownList("HODList", String.Empty ,new { ???? })
}
Now I want to use viewbag element which will be select the one of the item of dropdown.
How to do this ?

ViewBag is designed to pass data from the controller to the view not to the other way.
You can use HTTP Get method for populating drop down like
[HttpGet]
public MyAction()
{
MyModel model = new MyModel();
// model.DropDwonValues is generic list class in model
model.DropDwonValues= db.Values //replace with your db table
.Select(v => new DropDownItem
{
Text = v.Name //value to go in your text field
Value = v.Id.ToString() //value to go in your ID field
})
.ToList();
return View(model);
}
Then in your view you can do:
#using(Html.BeginForm())
{
#Html.LabelFor(m => m.DropDownId)
#Html.DropDownListFor(m => m.DropDownId , Model.DropDwonValues )
}

Related

Confused about how to Populate DropDown thru ViewBag

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>

How can i change values that are bound to first parameter (lambda expression) in the html helper function ListBoxFor() method?

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();

How to work with DropDownListFor in an EDIT view

Hi I have a problem with DropDownListFor on the Edit view.
Basically I'm using a partial view which contains my form and in my Edit and Create view I call this partial view.
I have around 5 similiar DropdownlistFor and these work well on create action but in edit doesn't, mainly i'm not getting (unable) to set the selected value.
In my Edit Action (GET), I fill my property ViewModel if the true object has the property filled.
if(icb.BAOfficer != null)
editICB.BAOfficer = icb.BAOfficer;
List<Staff> staffs = _fireService.GetAllStaffs().ToList();
staffs.Insert(0, new Staff { StaffId = -1, Name = "" });
editICB.BAOfficers = staffs;
return View(editICB);
This is how I'm filling my drop down and how I'm trying to set the selected value.
#Html.DropDownListFor(model => model.BAOfficerSelected, new SelectList(Model.BAOfficers, "StaffId", "Name", (Model.BAOfficer!= null ? Model.BAOfficer.StaffId:-1)), new { #class = "rounded indent" })
#Html.ValidationMessageFor(model => model.BAOfficer.StaffId)
I solve the problem setting a value to my model.BAOfficerSelected in Edit Action, this was the (easy) secret.
I need the first item like a empty option because is not a required information, but on the edit view if has value I need to set it as selected option.
In the end, it was my code.
My Model
public int BAOfficerSelected { get; set; }
public SelectList BAOfficers { get; set; }`
My Controller Create/Edit Action
if (icb.BAOfficer != null) // only for edit action
editICB.BAOfficerSelected = icb.BAOfficer.StaffId; //this will set the selected value like a mapping
//for Edit and Create
List<Staff> staffs = _fireService.GetAllStaffs().ToList();
staffs.Insert(0, new Staff { StaffId = -1, Name = "" });
editICB.BAOfficers = new SelectList(staffs, "StaffId", "Name");
return View(editICB);`
My View
#Html.DropDownListFor(model => model.BAOfficerSelected, Model.BAOfficers, new { #class = "rounded indent" })
I hope this can help others.
The best and cleanest way of doing this is setting the selected value in server side, in the SelectList object.
So, if your BAOfficerSelected is nullable... it is all simpler: You don't need to rely in adding a dummy item to hold the -1 for not selected value.
Instead, you do it this way:
List<Staff> staffs = _fireService.GetAllStaffs().ToList();
editICB.BAOfficers = new SelectList(staffs, "StaffId", "Name", editICB.BAOfficer != null ? editICB.BAOfficer.StaffId : null);
Of course, the BAOfficers need to be changed type from List<Staff> to SelectList.
Then, in your partial view you do:
#Html.DropDownListFor(model => model.BAOfficerSelected, Model.BAOfficers, "Select one...", new { #class = "rounded indent" })
Adding the 3rd parameter is needed to indicate that the default value (if nothing is selected) is that text.
Instead of using a SelectList, I often find it works better to use a List<SelectListItem>.
Further, I usually use an EditorTemplate for my dropdowns to keep my views clean.
So if my select list returns List<SelectListItem>:
public List<SelectListItem> BAOfficers { get; set };
You can set it up like this:
model.BAOfficers = staffs.Select(staff =>
new SelectListItem { Text = staff.Name, Value = staff.StaffId }).ToList();
Then in your EditorTemplate:
<!-- EditorTempaltes\DropDownList.cshtml -->
#model System.String
<p>
#Html.LabelFor(m => m):
#Html.DropDownListFor(m => m, new SelectList(
(List<SelectListItem>)ViewData["selectList"], "Value", "Text",
String.IsNullOrEmpty(Model) ? String.Empty : Model), String.Empty)
#Html.ValidationMessageFor(m => m)
</p>
And then in the view, just pass the SelectList into the EditorTemplate:
#Html.EditorFor(m => m.BAOfficerSelected, "DropDownList",
new { selectList = Model.BAOfficers() })
I met the same problem ,too.
According the article https://dotnetfiddle.net/PIGNLF which way gave a simple way to deal with this problem without two Models or more classes.enter link description here
here is my code
add model
public class NoteSelectLisModel
{
public string Value { get; set; }
public string Name { get; set; }
}
add Controller
public ActionResult Edit(int? _ID)
{
ViewBag.NoteState = new SelectList(new List<NoteSelectLisModel>()
{
new NoteSelectLisModel() {Value="1",Name="A)"},
new NoteSelectLisModel() {Value="2",Name="B"},
new NoteSelectLisModel() {Value ="3",Name ="C"}
}, "Value", "Name", 1);
Table ut = _db.Tables.Find(_ID);
if (ut == null)
{
return HttpNotFound();
}
else
{
return View(ut);
}
}
add View .cshtml
#Html.DropDownListFor(m => m.NOTE, (IEnumerable<SelectListItem>)ViewBag.NoteState, "No Selected")
The edit's Model is the same and the dropdownlist passed by View.bag

get dropdownlist selected value in controller MVC3 Razor

Hi in my MVC3 Project with RAZOR, i Have one doubt.
i have a page named CatlogPage.cshtml. in that page i have a Dropdownlist control.
#(Html.Telerik().DropDownListFor(m => m.CatalogName)
.BindTo(Model.CatalogName).HtmlAttributes(new { style = "width:235px" }))
<input type="submit" value="Next" />
I have a controller named Hierarchy.cs:
in that controller,
public ActionResult Hierarchy()
{
// Need to get the selected value in DropDownList
return View("Hierarchy");
}
How to get the value(CatalogName) from dropDownList to the controller?
This is my model code.
public List<SelectListItem> GetCatalogNameModel()
{
try{
var cat = from s in _entities.Catalogs.ToList()
select new SelectListItem()
{
Text = s.CatalogName,
Value = s.CatalogName
};
return cat.ToList();}
catch (Exception ex)
{
CreateLogFiles.ErrorLog(HttpContext.Current.Server.MapPath("~/Logs/ErrorLog"), ex, "CatalogService", "GetCatlogName");
return null;
}
}
So assuming that the first code snippet is from a strongly typed view (object DatabaseModel.CatalogModel) and that you are submitting the form to the Hierachy method, then passing in a CatalogModel and accessing the CatalogName should be what your after?
i.e.
public ActionResult Hierarchy(DatabaseModel.CatalogModel inputModel)
{
inputModel.CatalogName; //This will be the value from the drop down list
return View("Hierarchy");
}
For DropDownList, I use an Int prop to receive the selected Id. So My answer is:
Add this property to your ViewModel:
public Int32 SelectedCatalogId {get;set;}
And bind it to the DropDownList:
#Html.DropDownListFor(m => m.SelectedCatalogId, Model.GetCatalogNameModel())

SelectList selected value not carried over to DropDownList

I have a Razor page with a drop down list inside a form:
#using (Html.BeginForm("ProductsByOwners", "Report", FormMethod.Post, new { #id = "ProductsByOwners" }))
{
#Html.Label("Choose product owner: ")
#Html.DropDownList("OwnerList", (SelectList)ViewBag.OwnerList, new { #onchange = "this.form.submit();" })
}
The selected value of my SelectList is not being carried over to the DropDownList. I've debugged and stepped through the code and found that (SelectList)ViewBag.OwnerList evaluates properly and has the expected value selected, but the resulting HTML does not have any of the option tags selected.
Can anyone see what I'm doing wrong here?
UPDATED
Here is how the SelectList is created in my action:
ViewBag.OwnerList = new SelectList(ListUtils.ProductOwners(), "Key", "Value", values["OwnerList"]);
The result has the value indicated by values["OwnerList"] selected.
Thanks!
You are not using the DropDownList helper properly. In order to create a dropdownlist you need 2 things:
a scalar property to bind to the selected value when the form is submitted
a collection to bind the options to
In your example you have only one of those 2 things (the second). Your first argument is called OwnerList and you have ViewBag.OwnerList passed as second argument.
So:
#Html.DropDownList(
"SelectedOwnerId",
(SelectList)ViewBag.OwnerList,
new { #onchange = "this.form.submit();" }
)
Obviously I would recommend you using strongly typed views ans view models. And obviously get rid of the weakly typed ViewBag/ViewData/ViewCrap.
So start by designing a view model to meet the requirements of your view (which from what you have shown so far is to display a dropdownlist):
public class OwnerViewModel
{
[DisplayName("Choose product owner: ")]
public string SelectedOwnerId { get; set; }
public IEnumerable<SelectListItem> OwnerList { get; set; }
}
then a controller:
public class ReportController: Controller
{
public ActionResult ProductsByOwners()
{
var model = new OwnerViewModel
{
// preselect the second owner
SelectedOwnerId = "2",
// obviously those come from your database or something
OwnerList = new[]
{
new SelectListItem { Value = "1", Text = "owner 1" },
new SelectListItem { Value = "2", Text = "owner 2" },
new SelectListItem { Value = "3", Text = "owner 3" },
}
};
return View(model);
}
[HttpPost]
public ActionResult ProductsByOwners(OwnerViewModel model)
{
...
}
}
and you have a corresponding strongly typed view:
#model OwnerViewModel
#using (Html.BeginForm("ProductsByOwners", "Report", FormMethod.Post, new { id = "ProductsByOwners" }))
{
#Html.LabelFor(x => x.SelectedOwnerId)
#Html.DropDownListFor(
x => x.SelectedOwnerId,
Model.OwnerList,
new { onchange = "this.form.submit();" }
)
}
The most common reason the selected item is not selected in the DDL is you've named the selectlist the same as the model.
Strongly typed views are preferred, but it's fine to pass the SelectList in a Viewbag. See my tutorial Working with the DropDownList Box and jQuery and my blog Cascading DropDownList in ASP.Net MVC

Resources