I'm trying to generate a dropdownlist in my view, like the one below except I want my option label ("Please select...") to have a value of -1 as blank is already occupied by another option. Is there anyway to do this without adding it to the select list in my controller or view model, or creating a new html helper?
<%: Html.DropDownListFor(model => model.stuff.Id, new SelectList(Model.stuff, "Id", "Name"), "Please select...")%>
Thanks
I want my option label ("Please select...") to have a value of -1
You cannot do this out of the box with the DropDownListFor helper. It will always use blank for this value. You have two possibilities:
Write a custom helper
Add it manually to the collection
Actually you have a third possibility which IMHO is the best and what I would recommend you:
Don't use blank as values. This should be reserved for the Please Select default value. It doesn't seem logical to use blank as the value of something that the user can actually select. You might also have problems with the validation.
Just use the Concat method to add a new item to the SelectList after you get your values from the database. Then set the value to 0 and text to "Please Select".
var selectList = new SelectList(types.Concat( new[]{new MediaType() {MediaTypeId = 0, Type = "Please select"}})
, "mediatypeid", "type");
Related
I was wondering if anyone has ever experienced a problem like I'm currently having.
Controller:
_OpsAdminViewModel.userRoleID = _OpsAdminViewModel.retrieveHighestUserRoleGuidFromUserID(id.Value);
_OpsAdminViewModel.ActiveRoleList = _OpsAdminViewModel.GetActiveRoles();
_OpsAdminViewModel.UserRoleSelectList = new SelectList(_OpsAdminViewModel.ActiveRoleList, "RoleID", "RoleName", _OpsAdminViewModel.userRoleID);
View:
#Html.DropDownListFor(model=>model.selectedRoleID, Model.UserRoleSelectList)
Now, here is where it gets very odd. When I place a break on the Controller's Return line or the View's DropDownListFor line, I literally see that the value I want to have selected should be selected. Expanding the UserRoleSelectList object, reveals the correct "SelectedValue" ID and in the "Results View", the correct value has a "True" for selected. However, when the page is rendered, the pull-down menu is displaying the 0-position element of the pull-down menu.
Model binding works by binding to the value of your property. When your use DropDownListFor() the method internally builds a new IEnumerable<SelectListItem> and sets the Selected property based on the value of your property. In your case, the value of selectedRoleID does not match the value of one of the options so the first option is selected (because something has to be).
Set the value of selectedRoleID in the GET method before you pass the model to the view
model.selectedRoleID = _OpsAdminViewModel.userRoleID;
return View(model);
and delete the last parameter in your SelectList constructor since its pointless.
I have a Webgrid with a column containing a dropdown:
#Html.DropDownList("abc", new SelectList(Model.holdTypes),#item.holdType,"")
Here Model.holdTypes is a String List. #item.holdType contains the text that needs to be selected.
You are using a wrong overload. You should use this version.
#Html.DropDownList("abc", new SelectList(Model.holdTypes,item.holdType))
While this will render the SELECT element with a selected option, It will generate a SELECT element with only the text, There will not be a value attribute for the option items. So if you are planning to submit the selected option value to a form, This approach might not be very useful. You can use another version for that use case.
#Html.DropDownList("abc",
new SelectList(Model.holdTypes.Select(v=>new SelectListItem { Value = v,
Text = v}),"Value","Text",item.holdType))
In my model class for view, I have an enum type property SubjectType:
[Required(ErrorMessage = "This field is required.")]
public SubjectType SubjectType { get; set; }
I would like to create drop-down list for this property. But by default I would like it to be set to null so that user has to choose something, and the validation message will be shown if he would try to submit form without choosing any option.
What is the best approach to achieve this?
I was trying to change SubjectType property to nullable, and setting the default value to null, but the validation still passed on this field (somehow) and the form was submitted to the server. By default the value of this field was set to the first value from enum definition. No JavaScript allowed, I'd like to keep everything in code-behind. I will be grateful for any advice.
so far i render it this way:
#Html.DropDownList("SubjectType", EnumHelper.GetSelectList(typeof(SubjectType)))
#Html.LabelFor(model => model.SubjectType)
#Html.ValidationMessageFor(model => model.SubjectType)
You are able to solve problem doing this:
Change submit button to button with onclick action, then validate it in javascript and if form and this enum field is valid submit the form using jQuery.
Edit: I think the problem was three fold. first your attribute is named SubjectType but your dropdown is named Type so it cannot be bound to SubjectType.
second, Apparently you have to use #HTML.dropdownlistfor(). I did a viewsource with my two different versions dropdown and dropdownlistfor and dropdownlistfor is the only one that adds the validation classes (see below)
third, we needed to add the option label parameter "Select a Type" as a default value. I'm sure it'll work for you now.
In Model:
[Required(ErrorMessage = "Error!")]
public string SubjectType{ get; set; }
In Html:
#Html.DropDownListFor(m => m.SubjectType, new SelectList(Enum.GetNames(typeof(SubjectType))), "Select a Type", new { #class = "pretty" } )
now I see you have a helper that furnishes an enumerable I think that will be just fine if you replace my second param with that.
Dropdownlist vs DropdownlistFor Rendering of Select Element:
DropdownList:
<select name="SubjectType" class="pretty" id="SubjectType">...</select>
DropdownListFor:
<select name="SubjectType" class="pretty" id="SubjectType" data-val-required="Error!" data-val="true">...</select>
As you can see data-val-required and data-val classes are missing when doing a simple dropdown thus not turning on validation FOR that attribute. Sorry for all the pain of getting here. Don't forget to mark me right if it works.
I have populated a selectlist in my viewmodel in the form:
DeliveryCentres = new SelectList(deliveryCentres, "Id", "CentreName");
in my View I have:
#Html.DropDownListFor(m => m.DeliveryCentreId, Model.DeliveryCentres, "-- Not Required --");
The problem is that on display the dropdown defaults to the first item in the list as opposed to the -- Not Required -- value.
How do I make this the default?
#Stephen Muecke has answered the question. I just needed to leave the ID as null in the ViewModel before rendering.
From comments:
The selected value will be whatever the value of DeliveryCentreId is. If its value is null or does not match one of the option values, then the "Not Required" option will be selected
I am working on a .Net MVC3 application. I have a couple different models which all have an attribute or two with a DataType of varchar(1). For each of these want to have a drop down menu for Yes/No with a value of 'Y' or 'N'.
My current solution is as follows: I have a method in a public class which sends gives me my List of Yes/No values for the dropdown:
List<SelectListItem> items = new List<SelectListItem>();
items.Add(new SelectListItem() { Text = "Yes", Value = "Y" });
items.Add(new SelectListItem() { Text = "No", Value = "N" });
return items;
In my Controller, I then set this list into the ViewBag and send it into the View:
ViewBag.YesNo = new SelectList(repository.GetYesNo(), "Value", "Text");
And then I use it for a specific Model attribute like this:
#Html.DropDownListFor(model => model.PARAMETER_REQUIRED, (SelectList)ViewBag.YesNo)
This gets the job done but I don't like the ViewBag method because it's pretty tedious to maintain it when switching Views and I don't like having to repeat code. I want to change this up so that I can just use
#Html.EditorFor(model => model.PARAMETER_REQUIRED)
and have Razor know that I want this to be a DropDown with my Yes/No attributes.I also want to have this be reusable so that I can use the same template for any fields (in other models) that I want to edit with this Yes/No dropdown.
Is this possible? I know that 'templating' DisplayFor is possible. Can we achieve something similar with EditorFor?
Here are some really good examples of the built-in display templates and editor templates. Take a look at EditorTemplates/Boolean.ascx. You'll want something like this, in fact I'm not sure why you can't use the Boolean template as-is and change your view model to just be List or other suitable collection. Then, if necessary, you can customize the Boolean editor template to give you the exact DropDownList view you need.
An edit template uses the view assigned to it by the type given; what you may want to do is create a named template and apply the name to the Html.EditorFor overload. Then, you can create a specialized template for that scenario, and not have it be globally defined for the char type. Check out this example.