MVC SelectList Drop down default - model-view-controller

In the SelectList drop down, I like if the Count is 1, I like to default the value of what is there in the drugfamilylist which in this case is just 1 value. I cannot figure out how to do this.
I had the following below:
var drugfamilylist = (from dt in DataContext.Drugs
select dt.Drugvalue).Distinct().ToList();
if (drugfamilylist.Count == 1)
{
ViewBag.DrugFamily = new SelectList(drugfamilylist);
}
I tried but that idd not work either :
var drugfamilylist = (from dt in DataContext.Drugs
select dt.Drugvalue).Distinct().ToList();
if (drugfamilylist.Count == 1)
{
ViewBag.DrugFamily = new SelectList(drugfamilylist,drugfamilylist);
}

Typically I would have View strongly-typed to a ViewModel. The ViewModel would contain both the list of available items and the corresponding value of the currently selected element.
public class MyViewModel
{
public IList<string> DrugFamilyList;
public string SelectedDrugFamily;
}
In the controller you could then populate both the list of available items and the Selected items when the list of available items was a single element.
public ActionResult MyAction()
{
var vm = new MyViewModel();
vm.DrugFamilyList = (from dt in DataContext.Drugs
select dt.Drugvalue).Distinct().ToList();
vm.SelectedDrugFamily = (vm.DrugFamilyList.Count==1) ?
vm.DrugFamilyList[0] : null;
return View(vm);
}
And then use the HtmlHelper to build the select box:
#Html.DropDownListFor(m => m.SelectedDrugFamily, new SelectList(Model.DrugFamilyList, Model.SelectedDrugFamily))
However, if you didn't want to use the recommended ViewModel pattern, you could always accomplish the same thing with ViewBag.
ViewBag.DrugFamilyList = (from dt in DataContext.Drugs
select dt.Drugvalue).Distinct().ToList();
ViewBag.SelectedDrugFamily = (ViewBag.DrugFamilyList.Count==1) ?
ViewBag.DrugFamilyList[0] : null;
And then in the View use a similar helper:
#Html.DropDownList("desiredfieldname", new SelectList(ViewBag.DrugFamilyList, "", "", ViewBag.SelectedDrugFamily ))
This was written free-hand and not tested. I hope it helps.

Related

How to populate the retrieved values from DB in ListBox using asp.net mvc

Can anyone help me how to populate the retrieved values in ListBoxFor. I tried this but doesn't works.
Code in Model:-
public List<SelectListItem> SafetyRepresentataives { get; set; }
public List<string> BusinessUnitSiteSafetyRepresentative { get; set; }
Code in Controller:=
var site = entityDB.ClientBusinessUnitSites.FirstOrDefault(m => m.ClientBusinessUnitSiteId ==
siteId);
var siteRepresentatives = from representatives in entityDB.ClientBusinessUnitSiteRepresentatives
where representatives.ClientBUSiteID == siteId
select representatives;
local.SafetyRepresentataives = (from o in entityDB.SystemUsersOrganizations.ToList()
from c in entityDB.Contact.ToList()
where o.OrganizationId == clientId && c.UserId ==
o.UserId
select new SelectListItem
{
Text = c.FirstName + "," + c.LastName,
Value = c.UserId.ToString()
}).ToList();
foreach (var representative in siteRepresentatives)
{
local.BusinessUnitSiteSafetyRepresentative.Add(representative.SafetyRepresentative.ToString());
}
Code in View:-
#Html.ListBoxFor(x => Model.BusinessUnitSiteSafetyRepresentative, new
MultiSelectList(Model.SafetyRepresentataives,"Value","Text"))
I have retrieved the values from DB as shown above. But I am unable to link these retrieved values to ListBox so as to populate them. How to do this?? Help me out please!!!!!!!!!
I think this link should help you
http://www.asp.net/mvc/tutorials/javascript/working-with-the-dropdownlist-box-and-jquery/using-the-dropdownlist-helper-with-aspnet-mvc
In the sample they pass the combobox items in the viewbag.
I recomend you use a jquery plugin like autocomplete or typeahead from twitter bootstrap. So you can load asynchronously the elements.
Simply adding a default list helped me in resolving my issue. Here is the solution.
local.BusinessUnitSiteSafetyRepresentative = new List<string>();
foreach (var representative in siteRepresentatives)
{
local.BusinessUnitSiteSafetyRepresentative.Add(representative.SafetyRepresentative.ToString());
}

How to create a DropDownList from a LINQ query in MVC3?

I need to know how I could create a drop down list to represent all the categories in my "Categories" table.
I have already extracted the names and the values of each category I need, using this LINQ query :
var dbcontext = new LNQ2SQLDataContext();
var Q = from P in dbcontext.Categories
where P.SUB_CAT == null
select P;
I can pass this "Q" to my view like this :
In Controller :
return View(Q);
And in the View :
#model IEnumerable<MyAppName.Models.Category>
But I have no idea how to use #html.DropDownListFor() to make a darn good drop down list out of the model. :|
PLUS:
I could make a SelectList from the query "Q" like this :
var category_list = new SelectList(Q, "CAT_ID", "CAT_Name");
BUT I don't know how to create a drop down list (without using ViewBag to pass the category_list to the view) from a simple SelectList, either :|
I searched through as many blogs and websites as I could. But they didn't have the solution for my problem. I only got more and more confused!
So can anybody help please ? :/
To use DropDownListFor you'll either have to have a model that has a SelectList or data to make a selectlist out of and a property to store the selected value of the dropdown OR use the ViewBag to pass the category_list. So you can go with...
Public Class MyViewModel
{
Public Integer SelectedCategory { get; set; }
Public SelectList Categories { get; set; }
}
Public Class ItemsController : Controller
{
Public ActionResult Index()
{
var dbcontext = new LNQ2SQLDataContext();
var Q = from P in dbcontext.Categories
where P.SUB_CAT == null
select P;
var vm = new MyViewModel();
vm.Categories = new SelectList(Q, "CategoryID", "Name");
return View(vm);
}
[HttpPost()]
Public ActionResult Index(MyViewModel vm)
{
var theSelectedCategory = vm.SelectedCategory;
}
}
The view would be...
#model MyViewModel
#Html.DropDownListFor(model => model.SelectedCategory, Model.Categories, "Select Category")
Note: I don't typically code in C# so I can't guarantee the syntax is exactly right.

How do you properly create a MultiSelect <select> using the DropdownList helper?

(sorry, there are several item here but none seems to allow me to get this working.)
I want to create a DropDownList which allows multiple selection. I am able to populate the list but I can't get the currently selected values to seem to work.
I have the following in my controller:
ViewBag.PropertyGroups = from g in db.eFinGroups
where g.GroupType.Contents == "P"
select new
{
Key = g.Key,
Value = g.Description,
Selected = true
};
ViewBag.SelectedPropertyGroups = from g in company.Entities
.First().Properties.First().PropertyGroups
select new {
g.eFinGroup.Key,
Value = g.eFinGroup.Description };
In the view I have:
#Html.DropDownListFor(model => model.PropertyGroupsX,
new MultiSelectList(ViewBag.PropertyGroups
, "Key", "Value"
, ViewBag.SelectedPropertyGroups),
new { #class = "chzn-select", data_placeholder = "Choose a Property Group", multiple = "multiple", style = "width:350px;" })
PropertyGroupX is a string[] in the model.
I have tried all types of iterations with the selected properties... passing just the value, just the key, both, etc.
Also, what type is PropertyGroupX supposed to be? Is string array correct? Or should it be a dictionary that contains the current propertygroups? I really am having a hard time finding doc on this.
Someone suggested I should be using ListBoxFor. I have changed to that and still have the same issue. The selected values are not being set as selected when the option tags are rendered. Here is what I have tried:
#Html.ListBoxFor(model => model.PropertyGroups, new MultiSelectList(ViewBag.PropertyGroups, "Key", "Value"))
I have tried the model.PropertyGroups as a collection of string matching the Values, as a collection of Guid matching this IDs and as an anonymous type with both a Key and Value to match the items in the ViewBag. Nothing seems to work.
You don't use DropDownListFor if you want to create a multiselect list. You use the ListBoxFor helper.
View model:
public class MyViewModel
{
public string[] SelectedIds { get; set; }
public IEnumerable<SelectListItem> Items { get; set; }
}
Controller:
public ActionResult Index()
{
var model = new MyViewModel
{
// preselect the first and the third item given their ids
SelectedIds = new[] { "1", "3" },
// fetch the items from some data source
Items = Enumerable.Range(1, 5).Select(x => new SelectListItem
{
Value = x.ToString(),
Text = "item " + x
})
};
return View(model);
}
View:
#model MyViewModel
#Html.ListBoxFor(x => x.SelectedIds, Model.Items)

maintain state of dropdownlist in MVC3

How do I maintain the selected value of dropdownlist in MVC3?
I'm using the following code to create the drop down list:
<%= Html.DropDownList("PEDropDown",
(IEnumerable<SelectListItem>)ViewData["PEDropDown"],
new { onchange = "this.form.action='/Screener/Screener';this.form.submit();" }
)%>
Here is one example, I use. I am not sure, this is the way you use to populate the DropDownList
<%=Html.DropDownList("ddlCategories", IEnumerable<SelectListItem>)ViewData["PEDropDown"], "CategoryId", "CategoryName", Model.CategoryId), "Select Category", new { onchange = "this.form.action='/Screener/Screener';this.form.submit();"})%>
Another way is, make a select list in controller as follows
List<SelectListItem> CategoryList = new List<SelectListItem>();
foreach (var item in Categories)
{
CategoryList.Add(new SelectListItem
{
Selected = Model.CategoryId,
Text = item.CategoryName, Value = Convert.ToString(item.CategoryId) });
}
ViewData["PEDropDown"]=CategoryList;
and use in view as
<%:Html.DropDownList("ddlCategories",IEnumerable<SelectListItem>)ViewData["PEDropDown"], "CategoryId", "CategoryName", new { onchange = "this.form.action='/Screener/Screener';this.form.submit();"})%>
I'm not 100% sure I get what you want to do, but I assume you want to get the selected value from the dropdown list?
In that case:
new { onchange = "alert(this.options[this.selectedIndex].value);" }
I put it in an alert for now, because I don't know what you want to do with the value
pass the value back into your controller and then populate a List of SelectListItems in the controller:
public actionresult yourmethod (int idToPass)
{
List<SelectListItem> SLIList = new List<SelectListItem>();
foreach (Model model in dropdownList)
{
SelectListItem SLI = new SelectListItem();
SLI.text = model.CategoryName;
SLI.selected = model.CategoryId == idToPass;
SLIList.Add(SLI);
}
ViewData["myDDL"] = SLIList;
}
You may try this.
Using ViewBag instead of ViewData (I suggest, it is better to use Model object)
Html.DropDownList("PEDropDown", new SelectList(ViewBag.PEDropDown, "Key", "Value", Model.PEDropDownSelectedValue), new { onchange = "document.location.href = '/ControllerName/ActionMethod?selectedValue=' + this.options[this.selectedIndex].value;" }))
The fourth argument in SelectList is the selected value. It must be passed using the model object.
When you call the particular action method, set the model object as below.
public ActionResult ActionMethod(string selectedValue)
{
ViewModelPE objModel = new ViewModelPE();
// populate the dropdown, since you lost the list in Viewbag
ViewBag.PEDropDown = functionReturningListPEDropDown();
objModel.PEDropDownSelectedValue = selectedValue;
return View(objModel);
// You may use the model object to pass the list too instead of ViewBag (ViewData in your case)
}

ViewBag property value in DropDownListFor instead of Model property value

We found strange behaviour in DropDownListFor (ASP.NET MVC3 release). It selects ViewBag property value instead of Model property value in dropdown.
Model:
public class Country {
public string Name { get; set; }
}
public class User {
public Country Country { get; set; }
}
Controller Index action:
ViewBag.CountryList = new List<Country> { /* Dropdown collection */
new Country() { Name = "Danmark" },
new Country() { Name = "Russia" } };
var user = new User();
user.Country = new Country(){Name = "Russia"}; /* User value */
ViewBag.Country = new Country() { Name = "Danmark" }; /* It affects user */
return View(user);
View:
#Html.EditorFor(user => user.Country.Name)
#Html.DropDownListFor(user => user.Country.Name,
new SelectList(ViewBag.CountryList, "Name", "Name", Model.Country), "...")
It will show text box with "Russia" value and dropdown with "Danmark" value selected instead of "Russia".
I didn't find any documentation about this behaviour. Is this behaviour normal? And why is it normal? Because it is very hard to control ViewBag and Model properties names.
This sample MVC3 project sources
I'm not so sure why this decision was made, but it was happened because MVC framework tried to use the ViewData-supplied value before using the parameter-supplied value. That's why ViewBag.Country override parameter-supplied value Model.Country.
That was how it was written in MVC framework in the private method SelectInternal.
object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(fullName, typeof(string[])) : htmlHelper.GetModelStateValue(fullName, typeof(string));
// If we haven't already used ViewData to get the entire list of items then we need to
// use the ViewData-supplied value before using the parameter-supplied value.
if (!usedViewData) {
if (defaultValue == null) {
defaultValue = htmlHelper.ViewData.Eval(fullName);
}
}
if (defaultValue != null) {
IEnumerable defaultValues = (allowMultiple) ? defaultValue as IEnumerable : new[] { defaultValue };
IEnumerable<string> values = from object value in defaultValues select Convert.ToString(value, CultureInfo.CurrentCulture);
HashSet<string> selectedValues = new HashSet<string>(values, StringComparer.OrdinalIgnoreCase);
List<SelectListItem> newSelectList = new List<SelectListItem>();
foreach (SelectListItem item in selectList) {
item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text);
newSelectList.Add(item);
}
selectList = newSelectList;
}
This code defaultValue = htmlHelper.ViewData.Eval(fullName); tried to get the value from ViewData and if it can get the value, it will override the supplied parameter selectList with new list.
Hope it can help. Thanks.
side-node: ViewBag is just a dynamic wrapper class of ViewData.
The following line from your action method is what is confusing the code:
ViewBag.Country = new Country() { Name = "Danmark" }; /* It affects user */
That's because the html helpers look into a few different places to pick up values for the generated controls. In this case ViewData["Country"] is clashing with ModelState["Country"] Rename that property to something else and everything should work.

Resources