Search code examples
asp.net-mvcasp.net-coremodel-view-controller

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);
                }

Solution

  • 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 ;