I'm looking into creating an Edit page for a Company object that has multiple categories (that are predefined in a list). I have the list being sent through the ViewBag, and have the categories that the user selected in the Create page in an Array thanks to a ViewModel.
I can't figure out a way to have the ListBox prepopulate with the multiple values in my array. I was playing around with jQuery and was able to get one of the values to be selected, but when I try more than one nothing shows up. Any ideas?
#Html.ListBox("Category", new SelectList(ViewBag.Category, "Text", "Value"))
The SelectListItem object has a Selected property to indicate this. So I guess it would come down to how you build the SelectList. Currently you do this:
new SelectList(ViewBag.Category, "Text", "Value")
Which works, but gives you no control over the individual SelectListItems. Instead of building a SelectList, you can build an IEnumerable<SelectListItem> using the same method overload. Initially that might look like this:
ViewBag.Category.Select(c => new SelectListItem
{
Text = c.Text,
Value = c.Value
});
At this point you have more control over the individual items. Now it's just a matter of determining which ones should be selected. How do you determine that? Is it a property on the Category object? Something like this?:
ViewBag.Category.Select(c => new SelectListItem
{
Text = c.Text,
Value = c.Value,
Selected = c.Selected
});
Or perhaps some other condition?:
ViewBag.Category.Select(c => new SelectListItem
{
Text = c.Text,
Value = c.Value,
Selected = c.SomeValue == SomeCondition
});
How you determine that is up to you, and ideally something you can logically add to the backing model being used here.
Related
I have a list of a certain object, each object contains fields. I need to do a DropDownListFor or DropDownList for that field within that object but its not binding
I initially tried this with a List and this works fine for binding to a normal object field. I then tried converting to SelectList() by doing
#Html.DropDownListFor(model => Model.MyListOfObjects[i].FieldName, new SelectList(Model.MySelectList, "Value", "Text"))
I then tried to set the "Selected" property on the SelectListItem I needed to be selected but still no luck
for (var i = 0; i < Model.MyListOfObjects.Count; i++){
#Html.DropDownListFor(model => Model.MyListOfObjects[i].FieldName, Model.MySelectList)
}
Model.MySelectList is List<SelectListItem>
public List<MyCustomObject> MyListOfObjects {get;set;} //populated
public class MyCustomObject{
public string FieldName {get;set;}
}
So in the end, I need the value of Model.MyListOfObjects[i].FieldName tp be selected from the Model.MySelectList(). The value in the select list does match so I cant see whats wrong
Thank you. Appreciate any help
EDIT: I know I can use "EditorFor" templates for the object used in Model.MyListOfObjects but I would prefer to avoid it if possible as I am using that object with other things so if I need another version of the object in editorfor then I wouldnt be able to do it. As a last resort though, I will just have to change the object to a unique one and go down the editorfor route
selectListItem contains text and value.
You need to bind value field to dropdown not text field.
i.e. model => Model.MyListOfObjects[i].FieldValue
Check This will help you
Have some problems trying to solve this. Have two DropDownListFor where the first is populated with data and the second should be populated using the selected value from the first.
Lets say the first DropDownlist contains these data:
RoutesList;
Value = "CoOs", Text = "Copenhagen - Oslo",
Value = "StOs", Text = "Stockholm - Oslo",
Value = "OsCo", Text = "Oslo - Copenhagen"
In my razor view I'm trying to create a new list based on the selected value.
How do I get the selected value, lets say "StOs" and format it so it only contains the first two letters "St"? Trying to do this with C# and not Jquery.
My code
// Loads RoutesList to departureRouteSelectList
var departureRouteSelectList = Model.RoutesList;
// Finds selected value
var selectedItem = departureRouteSelectList.Select(x => x.Value);
// Create new selectList for returnRoute
List<SelectListItem> returnRouteSelectList = null;
I'm not sure if the "Select" command does what I want and getting the "StOs"?
Understanding what you want make me think this post will resolve your problem:
Can't get my DropDownListFor to select a selected SelectListItem item in a Dropdown menu
I have a view which has roughly 10 dropdowns, when I load this page against an ID which has no data saved against it the dropdowns have the selected value of "Please Select" which is create as im creating a new record.
When I navigate back to this view with an ID that has data saved against it, the selected values of each drop down is set by the data I pass in to the view which again is correct.
But if I then reload the page with an ID that has no data saved against it, the selected values of the drop downs are set from the previous record! I have debugged this over and over and for the ID that has no data linked it I can see its passing in NULL for the selected values for each drop downs. I'm assuming this is to do with the ModelState? So I tried the following at the beginning of my controller
ModelState.Clear();
Before the load method is called, but the issue still exists has anyone come across this? I've googled for a solution but the only things that come up are "MVC Dropdown doesn't remember the selected value" which is the opposite to the issue I have.
Update *
I think I have found the issue, I'm currently using how to cache objects in MVC so when I load the dropdowns from the db for the page I then store them in the cache as follows:
if (CacheExtension.IsIncache("ListType"))
{
model.ListType = CacheExtension.GetFromCache<List<SelectListItem>>("ListType");
model.ListTime = CacheExtension.GetFromCache<List<SelectListItem>>("ListDuration");
model.ListPostageOption = CacheExtension.GetFromCache<List<SelectListItem>>("ListPostage");
model.ListPricingType = CacheExtension.GetFromCache<List<SelectListItem>>("ListPrice");
}
else
{
const string queryMultiple = #"
SELECT StatusId, StatusDescription from [Status].table1
SELECT StatusId, StatusDescription from [Status].table2
SELECT StatusId, StatusDescription from [Status].table3
SELECT StatusId, StatusDescription from [Status].table4";
using (var sqlCon = new SqlConnection(Con.ReturnDatabaseConnection()).QueryMultiple(queryMultiple))
{
var duration = sqlCon.Read().ToList();
var type = sqlCon.Read().ToList();
var options = sqlCon.Read().ToList();
var pricing = sqlCon.Read().ToList();
model.ListType = new List<SelectListItem>();
model.ListTime = new List<SelectListItem>();
model.ListPostageOption= new List<SelectListItem>();
model.ListPricingType = new List<SelectListItem>();
model.ListType .AddRange(
type.Select(
item => new SelectListItem { Text = item.StatusDescription, Value = item.StatusId.ToString() }));
model.ListTime.AddRange(
duration.Select(
item => new SelectListItem { Text = item.StatusDescription, Value = item.StatusId.ToString() }));
model.ListPostageOption.AddRange(
options.Select(
item => new SelectListItem { Text = item.StatusDescription, Value = item.StatusId.ToString() }));
model.ListPricingType.AddRange(
pricing.Select(
item => new SelectListItem { Text = item.StatusDescription, Value = item.StatusId.ToString() }));
// Cache everything
CacheExtension.SaveTocache("ListType", model.ListAdvertType, new DateTime(1));
CacheExtension.SaveTocache("ListDuration", model.ListDuration, new DateTime(1));
CacheExtension.SaveTocache("ListPostage", model.ListPostageOption, new DateTime(1));
CacheExtension.SaveTocache("ListPrice", model.ListPricingType, new DateTime(1));
}
}
and I re-load the page instead of calling the database I check the cache, if it exists I pull from there (this is where the problem is) I have just commented out the pulling from the cache and it works the dropdowns no longer remember the previous values but why?
I know this is an old question, but as there was no concrete answer here for me when I stumbled onto this question during my own similar issue, I thought I would go ahead and put an answer in that worked for me and explains why its happening.
The best answer above is from #StephenMuecke, as his suggestion about
storing the collections instead of a SelectList is spot on.
The reason is because with any form of in-memory caching, the cached objects returned are pointers to the object in cache, so any change made to the returned cache object is actually written to the cache. In my case I was storing a List<SelectListItem>. Each SelectListItem has a selected attribute, and on my cshml pages when I used that List<SelectListItem> in a DropDownListFor(...) razor statement, it would assign whatever item was selected back into the cache.
The problem would arise on the next page load for a different record, if that dropdownvalue was null, the cached list I retrieved retained the last saved selected item, and because the new item was null, it was not overwritten, thus it would show the previously selected value when it should have been null and nothing should have been selected.
To fix:
Cache List<YourObjectName>, and on retrieval convert it to a
List<SelectListItem>.
Other options include cloning or deserializing/serializing the
List<SelectListItems> from cache.
Final option is don't use in-memory cache, use an out of process or
distributed cache mechanism, as this will effectively serialize and
deserialize the object.
Good day sirs.
The following block of code is used to make the selected value of a dropdownlistfor persist after submit:
#Html.DropDownListFor(x => Model.Value, new SelectList(Model.Values, #Model.Value))
In this block of code, Model.Values is a list of strings and the #Model.Value specifies which value is selected.
This block of code works great but I'm trying to do the same thing with a list of SelectListItems (rather than a list of strings). In the following code Model.Values is a list of SelectListItems.
#Html.DropDownListFor(x => Model.Value, Model.Values, Model.Value,
new
{
id = "ValueDD", onchange = "this.form.submit()"
})
Is it possible to use #Model.Value as I did in the first code block to set the selected value?
SelectListItem has a property Selected that needs to be set for the selected item, see http://msdn.microsoft.com/en-us/library/system.web.mvc.selectlistitem.ASPX
So in your controler you can just set the Selected property of the item that needs to be selected, assuming you are using the controler to build the list of Model.Values
My page view currently has a dropdownlist on it that is getting bound to a collection from the controller. This is working fine, However I want to insert an item to the top of the dropdownlist that is not in my collection e.g the list currently gets the following items
Open
Closed
I want to add a third option of "All" but I don't want to add this option to my database. In Webforms I would have just bound the control then inserted another item however it seems this is not possible with MVC, am I right in thinking I will need to add some Javascript to the view to add this new item once the dropdownlist has been bound?
Thanks
No. Construct your data as a list of SelectListItems and prepend in the controller.
var list = db.Table
.Select( t => new SelectListItem
{
Key = t.ID.ToString(),
Value = t.Name
} )
.ToList();
list.Insert( 0, new SelectListItem { Key = "-1", Value = "All" } );
ViewData["TableSelect"] = list;
On the view side:
<%= Html.DropDownList( "TableID",
(IEnumerable<SelectListItem>)ViewData["TableSelect"] ) %>
Simple
you can make it as you wish in controller.
and pass it in viewdata.
other option is directly in view page.
<%= Html.DropDownList("DropDown","all" )%>
But you can add only one option..
Make sure you are not storing added options in ur db, right?
so before you save it, check option value in action and apply your logic.
Newer implementation
var list = _db.Status.ToList();
list.Add(new Status(){DevelopmentStatusID = -1, DevelopmentStatusDesc = "All"});
var result = list.OrderBy(d => d.StatusID).ToList();
ViewBag.StatusID = new SelectList(result, "StatusID", "StatusDesc");
Then in the index.html
#Html.DropDownList("StatusID", null, htmlAttributes: new {#class = "form-control"})