I have a problem getting asp.net and the razor engine to create a drop down list with the correct element selected. No matter what I try, if one of the values available is "0", that item will always be selected.
What I am trying to create is a select for a rating that span from -2 to 2, with 0 being the middle value, but that should NOT be pre-selected. The user should be forced to make a decision and therefore the defualt value should be empty.
Creating the dropdownlist with an option label like the code below shows does not leave the default as empty. This would work if the values were 1-5 for instance.
#Html.DropDownListFor(model => model.Rating, new SelectList(new List<SelectListItem>()
{
new SelectListItem() {Text = "-2", Value = "-2"},
new SelectListItem() {Text = "-1", Value = "-1"},
new SelectListItem() {Text = "0", Value = "0"},
new SelectListItem() {Text = "1", Value = "1"},
new SelectListItem() {Text = "2", Value = "2"}
}, "Value", "Text"), String.Empty, new { #class = "rating-select" })
The above code adds a selected tag to the 0-item and creates the following html:
<select class="rating-select valid" data-val="true" data-val-number="The field Rating must be a number." data-val-required="Rating is required." id="Rating" name="Rating">
<option value=""></option>
<option value="-2">-2</option>
<option value="-1">-1</option>
<option selected="selected" value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
I have tried all versions of selecting a blank value, but all result in the same; the 0-item gets generated with a selected tag.
Creating a blank item with Selected = true
#Html.DropDownListFor(model => model.Rating, new SelectList(new List<SelectListItem>()
{
new SelectListItem() {Text = "Null", Value = "", Selected = True},
new SelectListItem() {Text = "-2", Value = "-2"},
new SelectListItem() {Text = "-1", Value = "-1"},
new SelectListItem() {Text = "0", Value = "0"},
new SelectListItem() {Text = "1", Value = "1"},
new SelectListItem() {Text = "2", Value = "2"}
}, "Value", "Text"), String.Empty, new { #class = "rating-select" })
Creating a blank item object and setting the object as selected in selectlist
#{SelectListItem blankItem = new SelectListItem() {Text = "Null", Value = ""}}
#Html.DropDownListFor(model => model.Rating, new SelectList(new List<SelectListItem>()
{
blankItem,
new SelectListItem() {Text = "-2", Value = "-2"},
new SelectListItem() {Text = "-1", Value = "-1"},
new SelectListItem() {Text = "0", Value = "0"},
new SelectListItem() {Text = "1", Value = "1"},
new SelectListItem() {Text = "2", Value = "2"}
}, "Value", "Text", blankItem), String.Empty, new { #class = "rating-select" })
None of the above work when one of the values is 0.
Does anyone know of a proper solution or if this is a bug in the framework?
I can solve it with a work-around hack, but I'd rather not...
I would look at what the type of the model.Rating property is, I am assuming it is an int. If this is an (int) type and you are not providing a value, it will be bound to a 0 when it comes across to a view. As such, when the view is processed, 0 will be marked as selected, that is what the view engine thinks the right value is and will override the selected value that you manually chose. Try making the model.Rating property a nullable int (int?) and see if you have the same issues.
Secondly, you could always look into a quick jQuery function to reset the drop-down to the first provided value, but that might be a little more "hacky" than what you are looking for.
The solution is to either avoid an item having 0 as value because Rating is an int (with default value equal 0), or, handle binding of DropdownList yourself by using Html.DropDownList instead. If you choose latter, you also have to specify Selected for the item user has selected while binding it.
Related
So I have the following scenario in which I am using two ViewBag(s):
To get the select list item
To get the particular item in concern
So it looks like this:
var currentType = "2";
List<SelectListItem> contentData = new List<SelectListItem>();
contentData.Add(new SelectListItem
{
Text = "Show 0 only",
Value = "0",
});
contentData.Add(new SelectListItem
{
Text = "Show 2 Only",
Value = "2",
});
ViewBag.currentType = currentType;
ViewBag.contentData = contentData;
Now in my Razor View, I am able to generate the DropDownList like this:
#Html.DropDownList("ContentTypeId", (IEnumerable<SelectListItem>)ViewBag.contentData, null, new { #class = "form-control" , #style = "width: 150px;" })
How can I can bind my ViewBag.currentType on the drop down list so it shows the pre selected value by default when the component is rendered?
Is it even possible to use two ViewBag value in this component ?
I tried like this:
#Html.DropDownList("ContentTypeId", (IEnumerable<SelectListItem>)ViewBag.contentData, null, new { #class = "form-control" , #style = "width: 150px;", #selected= (string)ViewBag.currentType})
But not getting the correct output.
Any tips/suggestions/solutions?
ViewBag is not working in your case, you will have to select an option manually, using Selected=true. HtmlDropDown is an outdated helper too.
Using html5 select with an asp helper is the best way to select item automatically
view
#{
var currentType = "2";
List<SelectListItem> contentData = new List<SelectListItem>();
contentData.Add(new SelectListItem
{
Text = "Show 0 only",
Value = "0",
});
contentData.Add(new SelectListItem
{
Text = "Show 2 Only",
Value = "2",
});
//or I guess you can take the from viewbag
string currentType = ViewBag.currentType;
List<SelectListItem> contentData = ViewBag.currentData
}
.....
<select class="form-control" id="levels" asp-for="#currentType"
asp-items="#contentData">
<option value="0" > Select </option>
</select>
this is working for dropdown list
#{
currentType = ViewBag.currentType;
contentData = ViewBag.contentData;
var dropDownItems = new SelectList(contentData,"Value","Text", currentType);
}
.....
#Html.DropDownList("#currentType",#dropDownItems,"Select",new { #class = "form-control" })
The SelectListItem Class has a Selected property.
You can just do :
List<SelectListItem> contentData = new List<SelectListItem>{
new SelectListItem
{
Text = "Show 0 only",
Value = "0",
},
new SelectListItem
{
Text = "Show 2 Only",
Value = "2",
Selected = true
});
I also wanted to post an answer with the attempt that I had made on this aspect and was able to achieve. I used the standard way of defining the pure HTML element instead of using the Razor helper tags. You can do this if you have dynamic elements which are not a part of your Model:
<select class="form-control" id="ContentDataId" name="ContentDataId">
#foreach (SelectListItem option in ViewBag.contentData as List<SelectListItem>)
{
<option value="#option.Value" #(option.Value == Convert.ToString(ViewBag.currentType) ? "selected='selected'" : "")>#option.Text</option>
}
</select>
The above definition will generate the same HTML if you used the helper tags. For those who have confusion using the helper tags, this is a more conventional way of generating your drop down list with dynamic ViewBag.
I have an edit view that implements a normal editor text field. The user can manually enter a value that can be saved to the model. However, alongside this editor field I also need a dropdownlist that the user can select from that will edit the editor field. However, the value I am putting in the editor field is not the same as the value selected from the dropdownlist, this value comes from another list which uses the index of the item selected by the dropdownlist to put the value. To illustrate:
I have a text field "Name Id" and and two lists "Name" and "Id". The user will select a "Name" and the view will place the "Id" into the "Name Id" Field.
Example:
Name Id: 2 <----- 2 was entered because Bob was selected
Name:
Alex
Bob
Carl
Dennis
Note: Don't forget to include JQuery reference for js code.
Razor Code:
#{
var domainsList = new SelectList(new []
{
new SelectListItem { Text = "Please Select", Value = "0", Selected = true },
new SelectListItem { Text = "Alex", Value = "1" },
new SelectListItem { Text = "Bob", Value = "2"},
new SelectListItem { Text = "Carl", Value = "3"},
new SelectListItem { Text = "Dennis", Value = "4"}
}, "Value", "Text");
}
#Html.Editor("NameId", new {#class="form-control"})
#Html.DropDownList("Nameslst", domainsList,new {#class="form-control"})
Js Code
<script>
$(function(){
$('#Nameslst').on('change',function(){
$('#NameId').val($(this).val())
})
})
</script>
For a Dropdown (as a SelectList) in my View, I can successfully set the value to the Id returned by my model, but the list does not update to reflect the selected Id as the selected item.
<%var type = Model.CompanyTypeId; %>
<%= Html.DropDownList("Type", (ViewData["Types"] as SelectList),
new Dictionary<string, object>()
{
{ "class", "form-control form-input"},
{ "Id", "CoType"},
{ "Name", "CoType"},
{ "value", type },
{ "option", "selected" }
})%>
I expect the dropdown list to update the selected item to the corresponding Id
(In ChromeDev tools I can verify the Id=Model.CompanyTypeId and option="selected", but the dropdown list still shows the item selected by default.
I expect the dropdown list to update the selected item to the corresponding Id
(In ChromeDev tools I can verify the Id=Model.CompanyTypeId and option="selected", but the dropdown list still shows the item selected by default.
<select id="CoType" name="CoType" class="form-control form-input"
option="selected" value="1">
<option value="-1">- Assign Type - </option>
<option value="1">Dummy</option>
<option value="2">Test CompanyType</option>
</select>
Since you already have Model.CompanyTypeId, you can easily use Html.DropDownListFor. You don't set value on the HTML attributes.
Controller
public ActionResult Index()
{
var model = new TestModel
{
CompanyTypeId = 1
};
ViewBag.Types = new List<SelectListItem>
{
new SelectListItem { Value = "-1", Text = "-- Assign Type --" },
new SelectListItem { Value = "1", Text = "Dummy" },
new SelectListItem { Value = "2", Text = "Test" },
};
return View(model);
}
View
#Html.DropDownListFor(m => m.CompanyTypeId,
(ViewBag.Types as List<SelectListItem>),
new Dictionary<string, object>()
{
{ "class", "form-control form-input"},
{ "Id", "CoType"},
{ "Name", "CoType"}
})
I don't understand why the initial value is not selected when the form is loaded.
Here's my code
model.LUIsUsed = new List<SelectListItem>()
{
new SelectListItem { Value = "0", Text = "Ignore" },
new SelectListItem { Value = "1", Text = "Required" },
new SelectListItem { Value = "2", Text = "Optional" },
};
In my view
#Html.DropDownListFor(x => x.Foo[i].IsUsed, Model.LUIsUsed, new { #class= "form-control input-sm is-used" })
x.Foo[i].IsUsed value is "1", but required is not selected. I can't figure out why.
Is it because x.Foo is an array?
EDIT: When I don't use an array, it works
It looks like there's a problem with DropDownListFor inside a for loop.
I had to build a SelectList and specify the selected value.
#Html.DropDownListFor(x => x.Criterias[i].IsUsed, new SelectList(Model.LUIsUsed,"Value","Text", Model.Criterias[i].IsUsed))
It works, but I would like to know why.
I have a BIT type in a sql database that I want to turn into a DropDownList.
I pass a model to the page which has an active field. This field is either true or false. I'm adding the ability to modify this column in the database.
Is it possible to create a DropDownListFor that will give them the option of "Active" "Disable" and then return the correct value to the database?
#Html.DropDownListFor(m => m.active, ??)
#Model.active
I have never tried this but how about this:
#Html.DropDownListFor(m=> m.active, new List<SelectListItem>() { new SelectListItem { Text = "Active", Value = "true", Selected = Model.active }, new SelectListItem { Text = "Inactive", Value = "false", Selected = Model.active } })
This solution works great. The only thing I had to change for my code is the "Selected" value if the model value is "False"
#Html.DropDownListFor(m=> m.active, new List<SelectListItem>() { new SelectListItem { Text = "Active", Value = "true", Selected = Model.active }, new SelectListItem { Text = "Inactive", Value = "false", Selected = !Model.active } })
It was displaying Active even though it should display Inactive.