Setting DropDownListFor default text MVC - asp.net-mvc

I am new to MVC, and am trying to do something that should be easy, but it is eluding me. I am using a DropDownListFor in a partial view to display a list of product names. That part works fine. What I am having trouble with is setting the initial value of the DropDownListFor to display "Select one". The code I am working with is as follows:
#Html.DropDownListFor(model => model.ProductId, new SelectList(ViewBag.ProductData, "ProductId", "Name"), "---Select one---", new { htmlAttributes = new { #id = "ProductName" } });
The controller which sets the ViewBag is as follows:
public ActionResult AddProduct(int quoteId, int quoteDetailId)
{
var items = db.Products.ToList();
ViewBag.ProductData = items;
ViewData["QuoteId"] = quoteId;
ViewData["QuoteDetailId"] = quoteDetailId;
return PartialView("EditQuoteDetail", new QuoteDetail { QuoteId = quoteId, QuoteDetailId = quoteDetailId, ProductId = 1, ProductName = " ", Amount = 1, ListPrice = 0, Discount = 0, Price = 0 });
}
Once I hit the dropdown arrow on the DropDownListFor, "Select one" appears at the top of the list. But when the DropDownListFor is first displayed, the first product name appears in the box, instead of "Select one". How can I fix this? Any help would be much appreciated.

Don't specify a value for the id property in your model:
public ActionResult AddProduct(int quoteId, int quoteDetailId)
{
var items = db.Products.ToList();
ViewBag.ProductData = items;
return PartialView("EditQuoteDetail", new QuoteDetail { QuoteId = quoteId, QuoteDetailId = quoteDetailId, ProductId = 0, ProductName = " ", Amount = 1, ListPrice = 0, Discount = 0, Price = 0 });
}

Related

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

MVC3 Html.DropDownListFor with both static and dynamic values

I'd like to populate a Html.DropDownListFor with both static and dynamic values in my controller. I can't seem to figure out how to make this work. I've tried a few different approaches, but most center around (1) define the static values in a variable, (2) try to append the dynamic values (3) pass all values via the viewModel to my partial view.
Here is a sample of the above approach.
//retrieve categories from DB
List<Category> categoryFromDb = new GetCategory().GetCategoryDropdownList(MySession.Current.AccountId).FindAll(c => c.StageId == currentStage);
//local variable with static values and trying to add the dynamic values from above
var categoryDropDown = new [] {
new {CategoryId = "", CategoryName = "Select Activity"},
new {CategoryId = "0", CategoryName = "Note"},
new {CategoryId = categoryFromDb[0], CategoryName = categoryFromDb[3]} //THIS IS THE LINE I CAN'T FIGURE OUT
};
var viewModel = new ActivityTimelineViewModel
{
ActivityTimeline = new GetActivity().GetActivityTimeline(MySession.Current.AccountId, MySession.Current.CandidateId),
CategoryList = categoryDropDown,
Date = DateTime.Today
};
I'm sure given my novice ability I am missing something simple.
-Tim
You'll have to find a common type and than you can put them into a combined collection. Can you make the static values of type Category?
List<Category> categoryFromDb = new GetCategory().GetCategoryDropdownList(MySession.Current.AccountId).FindAll(c => c.StageId == currentStage);
var staticCategories = new[]
{
new Category{CategoryId = "", CategoryName = "Select Activity"},
new Category{CategoryId = "0", CategoryName = "Note"}
};
var combinedCategories = staticCategories.Union(categoryFromDb);
Or if the Category won't work than put them into a SelectListItem like this.
List<SelectListItem> selectItemsFromDB =
new GetCategory().GetCategoryDropdownList(MySession.Current.AccountId).FindAll(
c => c.StageId == currentStage)
.Select(c=> new SelectListItem{Value = c.CategoryId, Text = c.CategoryName});
var staticCategories = new[]
{
new SelectListItem{Value = "", Text = "Select Activity"}
new SelectListItem{Value = "0", Text = "Note"}
};
var combinedCategories = staticCategories.Union(selectItemsFromDB);

telerik treeview asp.net mvc - link does not work for non root nodes

I am using this code in my view:
#(Html.Telerik().TreeView()
.Name("AjaxTreeView")
.BindTo(Model, (item, category) =>
{
// bind initial data - can be omitted if there is none
item.Text = category.Name;
item.Action("Details", "Categories", new { Id = category.Id });
item.Value = category.Id.ToString();
item.LoadOnDemand = category.NOChildren > 0;
})
.DataBinding(dataBinding => dataBinding
.Ajax().Select("_TreeViewAjaxLoading", "Categories")
)
)
It works fine (ajaxified expand and collapse). The action links work fine but only for the root nodes. My current controller that spews out JSON for the ajax load:
[Transaction]
[HttpPost]
public ActionResult _TreeViewAjaxLoading(TreeViewItem node)
{
int? ParentId = !string.IsNullOrEmpty(node.Value) ? (int?)Convert.ToInt32(node.Value) : null;
var nodes = from item in CategoryRepository.GetChildren(ParentId)
select new TreeViewItem
{
Text = item.Name,
Value = item.Id.ToString(),
LoadOnDemand = item.NOChildren > 0
};
return new JsonResult { Data = nodes };
}
does not set the action link. How can I set the action link here? Thanks.
Christian
This seems to do the trick:
[Transaction]
[HttpPost]
public ActionResult _TreeViewAjaxLoading(TreeViewItem node)
{
int? ParentId = !string.IsNullOrEmpty(node.Value) ? (int?)Convert.ToInt32(node.Value) : null;
UrlHelper u = new UrlHelper(this.ControllerContext.RequestContext);
var nodes = from item in CategoryRepository.GetChildren(ParentId)
select new TreeViewItem
{
Text = item.Name,
Value = item.Id.ToString(),
LoadOnDemand = item.NOChildren > 0,
Url = u.Action("Details", "Categories", new { Id = item.Id} )
};
return new JsonResult { Data = nodes };
}

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