Setting index of SelectedListItem razor - asp.net-mvc

I am populating a dropdown using as
[Required(ErrorMessage = "Please make a selection")]
public string SelectedPrimary { get; set; }
public IEnumerable<SelectListItem> PrimaryDrop { get; set; }
public void populateDropdown()
{
primaryDrop = new List<string>();
primaryDrop.Insert(0, "Getting ready");
primaryDrop.Insert(1, "Starting");
primaryDrop.Insert(2, "All");
PrimaryDrop = primaryDrop.Select(item => new SelectListItem { Value = item, Text = item });
}
And then my razor view is as follow
#Html.DropDownListFor(m => m.SelectedPrimary, new SelectList(Model.PrimaryDrop, "Value", "Text"), "Learning Path", new { style = "width:207px;", id = "FirstDropDown" })
Upon inspecting the element I would see this
<select data-val="true" data-val-required="Please make a selection" id="FirstDropDown" name="SelectedPrimary" style="width:207px;">
<option value="">Learning Path</option>
<option value="Getting ready">Getting ready</option>
<option value="Starting">Starting</option>
<option value="All modules">All</option>
</select>
How could I go about in setting the values to the index ?
<select data-val="true" data-val-required="Please make a selection" id="FirstDropDown" name="SelectedPrimary" style="width:207px;">
<option value="0">Learning Path</option>
<option value="1">Getting ready</option>
<option value="2">Starting</option>
<option value="3">All modules</option>
</select>

You could just use a Dictionary to build the SelectList. Then use key as the value and value as the text
var primaryDrop = new Dictionary<string, string>() {
{"0", "Getting Ready"},
{"1", "Starting"},
{"2", "All"}
};
PrimaryDrop = primaryDrop.Select(item =>
new SelectListItem { Value = item.Key, Text = item.Value });

You could fill PrimaryDrop like this (using List<T>.IndexOf(T) to get Value)
primaryDrop = new List<string>();
primaryDrop.Insert(0, "Getting ready");
primaryDrop.Insert(1, "Starting");
primaryDrop.Insert(2, "All");
PrimaryDrop = primaryDrop.Select(item => new SelectListItem
{
Value = primaryDrop.IndexOf(item),
Text = item
});

Related

Compare dropdown with value not key

I am fetching user data in the model and using SelectList, fetching the country detail with name and ID.
ID Name
1 USA
2 UK
3 CANADA
On my page, I have TEXTBOX, in which I am displaying the country NAME USA which is fetched from the model. Now SAME COUNTRY NAME I WANT TO KEEP SELECTED in my dropdown also.
var GetNewCountry = new SelectList(_manualGridService.GetCountry().OrderBy(l => l.Name)
.ToDictionary(us => us.ID, us => us.Name), "Key", "Value");
ViewBag.GetNewCountry = GetNewCountry ;
here is my view dropdown code
<div class="form-group">
<select asp-for="ConId" asp-items="#ViewBag.GetNewCountry" class="form-control">
<option value=""> Select </option>
</select>
<span asp-validation-for="ConId" class="text-danger"></span>
</div>
Parameter details
public int ConId { get; set; }
Here is my textbox code with parameter
public string UserConName{ get; set; }
<div class="form-group">
<input asp-for="UserConName" class="form-control" readonly="readonly" autocomplete="off" placeholder="Country Name" style="width:107%" />
</div>
The UserConName, textbox contains value USA, I want to keep seleted USA in my DROPDOWN LIST also.
MY SOLUTION
string strId = "";
foreach (var item in GetNewCountry )
{
if (item.Text == res.ConName)
{
strId = item.Value;
}
}
if (!string.IsNullOrEmpty(strId))
{
res.ConId= int.Parse(strId);
}
Shorten Answer
var GetNewCountry = new List<SelectListItem>();
foreach (var item in _manualGridService.GetCountry().OrderBy(l => l.Name).ToDictionary(us => us.ID, us => us.Name))
{
GetNewCountry.Add(new SelectListItem() {
Value = item.Key.ToString(),
Text = item.Value,
Selected = item.Value == "USA" ? true : false
});
}
ViewBag.GetNewCountry = GetNewCountry ;
Detailed explanation
Firstly you need know, by using new SelectList(_manualGridService.GetCountry().OrderBy(l => l.Name) .ToDictionary(us => us.ID, us => us.Name), "Key", "Value"), the Key equals to Id's value, the Value equals to Name's value.
Then compare with this constructor definition: public SelectList(IEnumerable items, string dataValueField, string dataTextField), we can know that ID represents the <option>'s value, 'Name' represents the <option>'s text.
<option value="IDValue">NameValue</option>
Finally the SelectList contains another constructor which can set the dropdownlist selected value:
public SelectList(IEnumerable items, string dataValueField, string dataTextField, object selectedValue)
Above all, in your scenario the selected value does not match the ID, it matched Name value, so you need change the SelectList like below:
var GetNewCountry = new SelectList(_manualGridService.GetCountry().OrderBy(l => l.Name)
.ToDictionary(us => us.ID, us => us.Name), "Value", "Value","USA");
Generated html:
<select class="form-control" data-val="true" data-val-required="The ConId field is required." id="ConId" name="ConId">
<option value=""> Select </option>
<option selected="selected" value="NameValue1">NameValue1</option>
<option value="NameValue2">NameValue2</option>
//...
</select>
Note:
In this way you can get the value="USA" option selected, but another question, your select <select asp-for="ConId"> here binds value to ConId, but the option value now represents Name, so it cannot bind successfully if you do form submit.
So if you do not want to change the <select asp-for="ConId"> to <select asp-for="UserConName">, you need modify your backend code like below:
var GetNewCountry = new List<SelectListItem>();
foreach (var item in _manualGridService.GetCountry().OrderBy(l => l.Name).ToDictionary(us => us.ID, us => us.Name))
{
GetNewCountry.Add(new SelectListItem() { Value = item.Key.ToString(), Text = item.Value, Selected = item.Value == "USA" ? true : false });
}
ViewBag.GetNewCountry = GetNewCountry ;

selecting an option in html.dropdown helper method using boolean result

I am working on an asp.net application. I have a viewbag with a boolean result (true or false) and I need to select one option from a razore view using this viewbag. I have done it like this.
Controller:
ViewBag.AMZ = result.shipment.ShipAMZ ;
View:
#{
var IsAmzSelected = (bool)ViewBag.AMZ;
}
<select id="amz" name="amz" class="form-input">
#if (IsAmzSelected == true)
{
<option value='1' selected>AMZ</option>
<option value='0'>BBW</option>
}
else
{
<option value='1'>AMZ</option>
<option value='0' selected>BBW</option>
}
</select>
I tried using Html dropdownlist helper method but it didn't work.
in controller i did it like this:
ViewBag.AMZ = new SelectList(new List<SelectListItem>() { new SelectListItem() { Text = "AMZ", Value = "1" }, new SelectListItem() { Text = "BBW", Value = "0",Selected=true } }, "Value", "Text" , result.shipment.amz);
and then bound it to htmldropdown to this viewbag but it didn't work
Can you please suggest how to do it using html.dropdown?

Retain Value on editing drop down on Razor

Want to reduce my logic on View data from drop down won't come from data base.
Current code
#Html.DropDownListFor(m => m.MyViewModel.Value,
new List<SelectListItem> {
new SelectListItem { Text = "1",Value = "1" },
new SelectListItem { Text = "2", Value = "2" },
new SelectListItem { Text = "3", Value = "3" },
new SelectListItem { Text = "4", Value = "4" },
new SelectListItem { Text = "5", Value = "5" },
});
Trying to achieve
<select id="MyViewModel.name" name="MyViewModel.name">
<option value="">--Select--</option>
#for (int i = 1; i <= 5; i++)
{
<option value="#i">#i</option>
}
</select>
On submitting the form I am getting the selected value in my ViewModel i.e action but on editing am not the selected value Like
<select data-val="true" id="ddl" name="">
<option value="1">1</option>
<option value="2">2</option>
**<option selected="selected" value="3">3</option>**
<option value="4">4</option>
<option value="5">5</option>
</select>
You code for generating the SelectList can be simplified to
#Html.DropDownListFor(m => m.yourProperty, new SelectList(new List<int> { 1, 2, 3, 4, 5 }))
However, that code belongs in the controller, not the view, and ideally you should have a view model with property IEnumerable<SelectListItem>, for example
public class MyViewModel
{
[Required(ErrorMessage = "...."]
[Display(Name = "....")]
public int? SelectedItem { get; set; } // nullable to protect against under-posting attacks
public IEnumerable<SelectListItem> Options { get; set; }
....
}
and in the GET method
MyViewModel model = new MyViewModel
{
Options = new SelectList(new List<int> { 1, 2, 3, 4, 5 })
};
return View(model);
and in the view
Html.DropDownListFor(m => m.SelectedItem, Model.Options, "Please select")
it will be best to define the data at the control level than in Razor
so create and edit actions will return a list which will be used in DropDownListFor
but Edit will also set the selected value

error : The field ID must be a number. in #Html.DropDownListFor method

My model:
public class ViewRequestModel
{
[Required(ErrorMessage = "some")]
[Display(Name = "some")]
public int RequestType { get; set; }
}
my controller:
[HttpPost]
[Authorize(Roles = "P")]
public PartialViewResult ViewRequests(ViewRequestModel model)
{
string vn = "";
switch (model.RequestType)
{
...
}
return PartialView(vn);
}
my view:
#{
var reqTypes = new List<ListItem> { new ListItem { Text = "t1", Value = "1" },
new ListItem { Text = "t2", Value = "2" },
new ListItem { Text = "t3", Value = "3" } };
}
#Html.DropDownListFor(model => model.RequestType, new SelectList(reqTypes), new { id = "ddlType" })
#Html.ValidationMessageFor(model => model.RequestType)
when I try to post my form, jquery validation blocks it and show the error The field RequestType must be a number
where's my mistake?
where's my mistake?
The fact that you are mixing some classic WebForms classes (ListItem) with ASP.NET MVC. The consequence of this is that your <option> elements of the dropdown do not have a value attribute. So nothing gets submitted to the form and the validation obviously fails.
Here's the correct way to populate the dropdown:
var reqTypes = new[]
{
new SelectListItem { Text = "t1", Value = "1" },
new SelectListItem { Text = "t2", Value = "2" },
new SelectListItem { Text = "t3", Value = "3" }
};
#Html.DropDownListFor(
model => model.RequestType,
reqTypes,
new { id = "ddlType" }
)
As you can see from this example I am using the SelectListItem class which is specific for ASP.NET MVC. This generates:
<select data-val="true" data-val-number="The field some must be a number." data-val-required="some" id="ddlType" name="RequestType">
<option selected="selected" value="1">t1</option>
<option value="2">t2</option>
<option value="3">t3</option>
</select>
wheres your code generates:
<select data-val="true" data-val-number="The field some must be a number." data-val-required="some" id="ddlType" name="RequestType">
<option>t1</option>
<option>t2</option>
<option>t3</option>
</select>
The difference is obvious.

ASP .Net MVC 3 Html.DropDown not binding to variable

I have a list of Organizations (CalledOrganizationSelectList) and one of them is the one that's being called (CalledOrganizationId). I set both in my ViewModel but MVC / Razor doesn't render the dropdown correctly (ie does not set the selected="selected" attribute for the correct item in the dropdown).
There is a workaround which makes even less sense. I added a new member to my ViewModel and bound the dropdown to that. This works fine. Until just now when it's stopped working...
public class CallViewModel{
public int? CalledOrganizationId { get; set; }
public SelectList CalledOrganizationSelectList { get; set; }}
In my controller:
var vm = new CallViewModel();
var calledOrganizationSelectList = new List<object>();
calledOrganizationSelectList.Add( new {Text="",Id=""});
calledOrganizationSelectList.AddRange(
db.MyOrganizations.OrderBy(x=>x.Name)
.Select(x => new { Text = x.Name, Id = x.Id.ToString()}).ToList());
var sl = new SelectList(calledOrganizationSelectList, "Id", "Text",
vm.CalledOrganizationId);
vm.CalledOrganizationSelectList = sl;
return View(vm);
In my view:
<div>CalledOrganizationId = #Model.CalledOrganizationId :
select list contains
<ul>#foreach (var itm in Model.CalledOrganizationSelectList)
{<li>Value: #itm.Value Text: #itm.Text Is Selected: #itm.Selected</li>}
</ul>
</div>
#Html.DropDownList("CalledOrganizationId", Model.CalledOrganizationSelectList)
In my rendered page source:
<div>CalledOrganizationId = 38 : select list contains
<ul>
<li>Value: Text: Is Selected: False</li>
<li>Value: 37 Text: rrr Is Selected: False</li>
<li>Value: 38 Text: sss1 Is Selected: True</li>
</ul>
</div>
<select data-val="true" data-val-number="The field CalledOrganizationId must be a number." id="CalledOrganizationId" name="CalledOrganizationId">
<option selected="selected" value=""></option>
<option value="37">rrr</option>
<option value="38">sss1</option> </select>
I've worked around it after first pulling out what was left of my hair and then by introducing a new variable on my ViewModel, which seems to work ok.
Having 2 properties on your viewmodel is the correct way to do DropDownLists. One property holds all of the available options, and the other holds the currently selected option:
public class CallViewModel
{
// this captures the selected item
public int? CalledOrganizationId { get; set; }
// this contains the select list options
public IEnumerable<SelectListItem> CalledOrganizationSelectList { get; set; }
}
However, you do not need to add the empty option in the controller. You can do this in the view:
#Html.DropDownListFor(m => m.CalledOrganizationId,
Model.CalledOrganizationSelectList, "")
You can just get away with this in the controller:
var vm = new CallViewModel();
//var calledOrganizationSelectList = new List<object>();
//calledOrganizationSelectList.Add( new {Text="",Id=""});
//calledOrganizationSelectList.AddRange(
//db.MyOrganizations.OrderBy(x=>x.Name)
// .Select(x => new { Text = x.Name, Id = x.Id.ToString()}).ToList());
//var sl = new SelectList(calledOrganizationSelectList, "Id", "Text",
// vm.CalledOrganizationId);
//vm.CalledOrganizationSelectList = sl;
vm.CalledOrganizationSelectList = db.MyOrganizations.OrderBy(x => x.Name)
.Select(x => new SelectListItem
{
Text = x.Name,
//Id = x.Id.ToString() // do not use "Id" for the property name,
Value = x.Id.ToString() // use "Value" -- it is a SelectListItem property
});
// if you want to set the selected item on the dropdownlist, do it here
vm.CalledOrganizationId = 37;
return View(vm);

Resources