Optgroup in mvc - asp.net-mvc

My issue is optgroup is not display properly
public ActionResult AddMember()
{
ViewBag.ddlEventSelectListItem = GetEventWithNotice();
return View();
}
public List<SelectListItem> GetEventWithNotice()
{
List<SelectListItem> ddllst = new List<SelectListItem>();
DataTable dt = objEN.GetEventWithNoticeList();
foreach(DataRow dr in dt.Rows)
{
ddllst.Add(new SelectListItem { Value = dr["Id"].ToString(), Text= dr["Title"].ToString(), Group=new SelectListGroup { Name=dr["OptGroup"].ToString()}});
}
return ddllst;
}

Your current code is generating a new SelectListGroup object for each SelectListItem item you are generating inside your loop. That is why you are seeing one group for each option in the rendered SELECT element.
What you should be doing is, creating unique SelectListGroup objects and use/reuse the corresponding group object for each of theSelectListItems
public List<SelectListItem> GetEventWithNotice()
{
var dt = objEN.GetEventWithNoticeList();
// First read the items from data table to a list of anonymous objects
var items = dt.AsEnumerable().Select(a => new
{
Id = a.Field<int>("Id"),
Title = a.Field<string>("Title"),
Group = a.Field<string>("OptGroup")
});
// Let's get unique Group names and build a dictionary
// Where the key is the Group name and
// the value is the SelectListGroup object created from the name
var groupsDict = items.Select(a => a.Group)
.Distinct()
.ToDictionary(k => k, y => new SelectListGroup() { Name = y });
// Let's build the list of SelectListItem's from items
// and gets the group from above dictionary
// while creating each SelectListItem object.
return items.Select(s => new SelectListItem
{
Value = s.Id.ToString(),
Text = s.Title,
Group = groupsDict[s.Group]
}).ToList();
}

Related

How to explicitly convert type 'System.Collections.Generic.List<System.Web.Mvc.SelectListItem>' to 'System.Web.Mvc.SelectList'?

I am trying to create a new SelectList and return it via return Acctlist.ToList<SelectListItem>(); statement, but can't because of the error
Cannot implicitly convert type 'System.Collections.Generic.List<System.Web.Mvc.SelectListItem>' to 'System.Web.Mvc.SelectList'
private SelectList RemoveCustomersWithoutSites(SelectList CustomerSelectList)
{
// Update the Account Number dropdown in the SafeContacts pages to only include accounts that have at least one monitored location in Stages.
SelectList CustList = null;
List<SelectListItem> Acctlist = new List<SelectListItem>();
foreach (SelectListItem AcntNumber in CustomerSelectList.Items){
IEnumerable<SelectListItem> siteList = null;
siteList = objAPICommon.GetSites(AcntNumber.ToString());
// Add this Account if it has a site
if (siteList != null && siteList.Count() > 0)
{
SelectListItem item;
item = new SelectListItem { Text = AcntNumber.Text, Value = AcntNumber.Value };
Acctlist.Add(item);
}
}
return ***Acctlist.ToList<SelectListItem>()***;
}
How should I Cast or Convert Acctlist into a SelectList please? Thank you.
Create a new SelectList with the items:
new SelectList(items)

SelectList how to set selected item only when valid value for System.Web.Mvc.SelectList

When you create a SelectList you can optionally pass in the SelectedValue property for which the documentation says
// selectedValue:
// The selected value. Used to match the Selected property of the corresponding
// System.Web.Mvc.SelectListItem.
However, if you pass it a value object which is not contained in the list of items, it still sets the selected value. Try this:
using System.Web.Mvc;
class SomeItem
{
public int id { get; set; }
public string text { get; set; }
}
class CreateSelectList
{
public static SelectList CreateSelectList()
{
List<SomeItem> items = new List<SomeItem>();
for (int i = 0; i < 3; i++)
{
items.Add(new SomeItem() { id = i, text = i.ToString() });
}
// 5 is not in the list of items yet the property SelectedValue does = 5
return new SelectList(items, "id", "text", 5);
}
}
My questions are:
Since I want to lazily set my selected value only if it exists, I just want to pass in a value and have it ignored when it does not exist in the list, but how? (is this a bug or a design feature), or
If you create a SelectList without the SelectedValue, after you have constructed it, how can you set the SelectedValue (again when it exists in the list) ?
If your code is near to your real scenario, you could use something like this
// check if there is any element with id = 5
if (items.Any(i => i.id == 5))
{
// there is an element with id = 5 so I set the selected value
return new SelectList(items, "id", "text", 5);
}
else
{
// there is no element with id = 5 so I don't set the selected value
return new SelectList(items, "id", "text");
}

MVC dropdownlist : Setting the value and text based upon table in database

I have a table in database
I've been able to show the list of TypeName in my dropdownlist in my View
Currently i'm doing this is my controller
[HttpGet]
public ActionResult CreateModule()
{
var moduleTypes = _db.ModuleTypes.Select(moduleType => moduleType.TypeName).ToList();
var model = new CreateModule
{
TypeNames = moduleTypes.Select(m => new SelectListItem
{
Value = m,
Text = m,
})
};
return View(model);
}
and in view
<div class ="input-block-level">#Html.DropDownListFor(model => model.SelectedModuleTypeName, Model.TypeNames)</div>
That results to something like this
based upon my code, I'll get the TypeName from the view in my controller's post method.
How I can I change my code in order to access Id of the TypeName in controller?
Modify your Action:
public ActionResult CreateModule()
{
var moduleTypes = _db.ModuleTypes.Select(moduleType => new { TypeName = moduleType.TypeName, Id = moduleType.Id }).ToList();
var model = new CreateModule
{
TypeNames = moduleTypes.Select(m => new SelectListItem
{
Value = m.Id.ToString(),
Text = m.TypeName,
})
};
return View(model);
}
Select multiple items instead of single
var moduleTypes = _db.ModuleTypes
.Select(
moduleType => new {
Id = moduleType.Id
TypeName = moduleType.TypeName}
).ToList();
var model = new CreateModule
{
TypeNames = moduleTypes.Select(m => new SelectListItem
{
Value = m.Id.ToString(),
Text = m.TypeName,
})
};
The first statement is creating anonymous object using linq, and second statement is using it to create CreateModule

Adding a default SelectListItem

public IEnumerable<SelectListItem> GetList(int? ID)
{
return from s in db.List
orderby s.Descript
select new SelectListItem
{
Text = s.Descript,
Value = s.ID.ToString(),
Selected = (s.ID == ID)
};
}
I return the above to a view and populate a DropDownList. I would like to add a default SelectListItem (0, "Please Select..") to the above linq result before it is returned to the view. Is this possible?
return new[] { new SelectListItem { Text = ... } }.Concat(
from s in db.List
orderby s.Descript
select new SelectListItem
{
Text = s.Descript,
Value = s.ID.ToString(),
Selected = (s.ID == ID)
});
As you are using ASP.NET MVC, you can do this in the view by specifying a value for the optionLabel parameter of the DropDownField method of the HtmlHelper - e.g:
htmlHelper.DropDownList("customerId", selectList, "Select One");
Putting this type of code in your UI layer is probably more appropriate than having it in the data layer. One downside to doing this is that your select box will have an empty string value, not a "0" for the 'Select One' option, but that is not really a problem as you can treat this as a null value if your controller action method can accept a nullable int for the relevant parameter - e.g.
public ActionResult DoSomething(int? customerId)
{
if(customerId != null)
{
// do something with the value
}
}
var list = from s in db.List
orderby s.Descript
select new SelectListItem
{
Text = s.Descript,
Value = s.ID.ToString(),
Selected = (s.ID == ID)
};
list.Insert(0, new SelectListItem { Text = "Please Select...", Value = string.Empty });
return list;
firt put your default value in the list
list.add(your default list item)
and then do list.addrange(linq select query)
cheers
Here is what I did, I read my values from an XML file into an IList. I then inserted a new record into the IList at position 0. Then make a select list from the IList.
IList< MY_DATA > mydata = (from tmp in myXML.Descendants("R").ToList()
select new MY_DATA
{
NR = tmp.Attribute("NR").Value,
NA = tmp.Attribute("NA").Value
}).ToList<MY_DATA>();
mydata.Insert(0, new My_DATA() { NR = "", NA = "--Click to Select--" });
SelectList mylist = new SelectList(mydata, "NR", "NA");
After I reviewed many questions, and I don't find what i'm looking for.I don't need many lines of code to just have a simple drowpdown. so I want to share with you what I use and it easy and simple.. ( specially if you don't want to use and Entity Framework..
using System.Web.Mvc;
SelectList(IEnumerable items, string dataValueField, string dataTextField);
For Example:
in Controller add :
SelectList slTitle = new SelectList(Query.SelectAllTitle(), "TitleID", "TitleName");
ViewBag.TitleSelectList = slTitle;
in View add :
#Html.DropDownList("TitleSelectList", "--please select--")
This is just for people who are using Webpages framwork (not MVC and webform) with Razor V2 and C#, you need do
#Html.DropDownList("category", "Please select", listData)
Note: OptionalLabel need to be the middle parameter.
Equivalent would be add a SelectListitem to your list data:
var list=db.Query("select id, name from dbtable");
List<SelectListItem> listData = new List<SelectListItem>();
listData.Add(new SelectListItem
{
Text = "Please select",
Value = "",
});
foreach(var item in list) {
listData.Add(new SelectListItem {
Text = item.Name,
Value = item.id,
Selected = isSelected
});
}
#Html.DropDownList("play" , listData)

How can I add an item to a SelectList in ASP.net MVC

Basically I am looking to insert an item at the beginning of a SelectList with the default value of 0 and the Text Value of " -- Select One --"
Something like
SelectList list = new SelectList(repository.func.ToList());
ListItem li = new ListItem(value, value);
list.items.add(li);
Can this be done?
There really isn't a need to do this unless you insist on the value of 0. The HtmlHelper DropDownList extension allows you to set an option label that shows up as the initial value in the select with a null value. Simply use one of the DropDownList signatures that has the option label.
<%= Html.DropDownList( "DropDownValue",
(IEnumerable<SelectListItem>)ViewData["Menu"],
"-- Select One --" ) %>
I got this to work by Populating a SelectListItem, converting to an List, and adding a value at index 0.
List<SelectListItem> items = new SelectList(CurrentViewSetups, "SetupId", "SetupName", setupid).ToList();
items.Insert(0, (new SelectListItem { Text = "[None]", Value = "0" }));
ViewData["SetupsSelectList"] = items;
This is possible.
//Create the select list item you want to add
SelectListItem selListItem = new SelectListItem() { Value = "null", Text = "Select One" };
//Create a list of select list items - this will be returned as your select list
List<SelectListItem> newList = new List<SelectListItem>();
//Add select list item to list of selectlistitems
newList.Add(selListItem);
//Return the list of selectlistitems as a selectlist
return new SelectList(newList, "Value", "Text", null);
I liked #AshOoO's answer but like #Rajan Rawal I needed to preserve selected item state, if any. So I added my customization to his method AddFirstItem()
public static SelectList AddFirstItem(SelectList origList, SelectListItem firstItem)
{
List<SelectListItem> newList = origList.ToList();
newList.Insert(0, firstItem);
var selectedItem = newList.FirstOrDefault(item => item.Selected);
var selectedItemValue = String.Empty;
if (selectedItem != null)
{
selectedItemValue = selectedItem.Value;
}
return new SelectList(newList, "Value", "Text", selectedItemValue);
}
private SelectList AddFirstItem(SelectList list)
{
List<SelectListItem> _list = list.ToList();
_list.Insert(0, new SelectListItem() { Value = "-1", Text = "This Is First Item" });
return new SelectList((IEnumerable<SelectListItem>)_list, "Value", "Text");
}
This Should do what you need ,just send your selectlist and it will return a select list with an item in index 0
You can custome the text,value or even the index of the item you need to insert
Here html helper for you
public static SelectList IndividualNamesOrAll(this SelectList Object)
{
MedicalVarianceViewsDataContext LinqCtx = new MedicalVarianceViewsDataContext();
//not correct need individual view!
var IndividualsListBoxRaw = ( from x in LinqCtx.ViewIndividualsNames
orderby x.FullName
select x);
List<SelectListItem> items = new SelectList (
IndividualsListBoxRaw,
"First_Hospital_Case_Nbr",
"FullName"
).ToList();
items.Insert(0, (new SelectListItem { Text = "All Individuals",
Value = "0.0",
Selected = true }));
Object = new SelectList (items,"Value","Text");
return Object;
}
The .ToList().Insert(..) method puts an element into your List. Any position can be specified. After ToList just add .Insert(0, "- - First Item - -")
Your code
SelectList list = new SelectList(repository.func.ToList());
New Code
SelectList list = new SelectList(repository.func.ToList().Insert(0, "- - First Item - -"));
May not sound very elegant, but I usually do something like this:
var items = repository.func.ToList();
items.Insert(0, new funcItem { ID = 0, TextValue = "[None]" });
ViewBag.MyData = new SelectList(items);
Okay I like clean code so I made this an extension method
static public class SelectListHelper
{
static public SelectList Add(this SelectList list, string text, string value = "", ListPosition listPosition = ListPosition.First)
{
if (string.IsNullOrEmpty(value))
{
value = text;
}
var listItems = list.ToList();
var lp = (int)listPosition;
switch (lp)
{
case -1:
lp = list.Count();
break;
case -2:
lp = list.Count() / 2;
break;
case -3:
var random = new Random();
lp = random.Next(0, list.Count());
break;
}
listItems.Insert(lp, new SelectListItem { Value = value, Text = text });
list = new SelectList(listItems, "Value", "Text");
return list;
}
public enum ListPosition
{
First = 0,
Last = -1,
Middle = -2,
Random = -3
}
}
Usage (by example):
var model = new VmRoutePicker
{
Routes =
new SelectList(_dataSource.Routes.Select(r => r.RouteID).Distinct())
};
model.Routes = model.Routes.Add("All", "All", SelectListHelper.ListPosition.Random);
//or
model.Routes = model.Routes.Add("All");
As this option may need in many different manners, i reached to conclusion to develop an object so that it can be used in different scenarios and in future projects
first add this class to your project
public class SelectListDefaults
{
private IList<SelectListItem> getDefaultItems = new List<SelectListItem>();
public SelectListDefaults()
{
this.AddDefaultItem("(All)", "-1");
}
public SelectListDefaults(string text, string value)
{
this.AddDefaultItem(text, value);
}
public IList<SelectListItem> GetDefaultItems
{
get
{
return getDefaultItems;
}
}
public void AddDefaultItem(string text, string value)
{
getDefaultItems.Add(new SelectListItem() { Text = text, Value = value });
}
}
Now in Controller Action you can do like this
// Now you can do like this
ViewBag.MainCategories = new SelectListDefaults().GetDefaultItems.Concat(new SelectList(db.MainCategories, "MainCategoryID", "Name", Request["DropDownListMainCategory"] ?? "-1"));
// Or can change it by such a simple way
ViewBag.MainCategories = new SelectListDefaults("Any","0").GetDefaultItems.Concat(new SelectList(db.MainCategories, "MainCategoryID", "Name", Request["DropDownListMainCategory"] ?? "0"));
// And even can add more options
SelectListDefaults listDefaults = new SelectListDefaults();
listDefaults.AddDefaultItme("(Top 5)", "-5");
// If Top 5 selected by user, you may need to do something here with db.MainCategories, or pass in parameter to method
ViewBag.MainCategories = listDefaults.GetDefaultItems.Concat(new SelectList(db.MainCategories, "MainCategoryID", "Name", Request["DropDownListMainCategory"] ?? "-1"));
And finally in View you will code like this.
#Html.DropDownList("DropDownListMainCategory", (IEnumerable<SelectListItem>)ViewBag.MainCategories, new { #class = "form-control", onchange = "this.form.submit();" })
A work-around is to use #tvanfosson's answer (the selected answer) and use JQuery (or Javascript) to set the option's value to 0:
$(document).ready(function () {
$('#DropDownListId option:first').val('0');
});
Hope this helps.
Try something like the following code:
MyDAO MyDAO = new MyDAO();
List<MyViewModel> _MyDefault = new List<MyViewModel>() {
new MyViewModel{
Prop1= "All",
Prop2 = "Select all"
}
};
ViewBag.MyViewBag=
new SelectList(MyDAO
.MyList().Union(
_MyDefault
), "Prop1", "Prop2");
I don't if anybody else has a better option...
<% if (Model.VariableName == "" || Model.VariableName== null) { %>
<%= html.DropDpwnList("ListName", ((SelectList) ViewData["viewName"], "",
new{stlye=" "})%>
<% } else{ %>
<%= html.DropDpwnList("ListName", ((SelectList) ViewData["viewName"],
Model.VariableName, new{stlye=" "})%>
<% }>

Resources