Compare dropdown with value not key - asp.net-mvc

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 ;

Related

Setting index of SelectedListItem razor

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

Html.DropDownListFor selected value not being selected

EDIT: I've found a solution and what I think is the reason why, see answer below.
I've got a drop down list where the selected calue is not being rendered correctly.
The code to create is as follows:
In the controller
var dlvm = new DonorIndexViewModel();
return View(dlvm);
The ViewModel is created by
public DonorIndexViewModel() {
var list = CreateSearchList();
SearchList = new SelectList(list, "Value", "Text", list.First().Value);
}
CreateSearchList is:
private IEnumerable<SelectListItem> CreateSearchList() {
var list = new List<SelectListItem> {
CreateSelectListItem(Constants.SurnameName, Constants.SurnameValue),
CreateSelectListItem(Constants.CodeName, Constants.CodeValue),
CreateSelectListItem(Constants.PostcodeName, Constants.PostcodeValue),
CreateSelectListItem(Constants.Address1Name, Constants.Address1Value)
};
return list;
}
View code is:
<div class="form-group">
#Html.LabelFor(model => model.SearchList, htmlAttributes: new {#class = "control-label col-md-1"})
<div class="col-md-11">
#Html.DropDownListFor(model => model.SearchListId, Model.SearchList, "Select Search Type", htmlAttributes: new { #class = "control-label input-width-xlarge"})
</div>
</div>
In the view, the model shows the first item is selected:
But the item is not being selected in the browser. Rendered code is as follows:
<select class="control-label input-width-xlarge" data-val="true" data-val- number="The field SearchListId must be a number." data-val-required="The SearchListId field is required." id="SearchListId" name="SearchListId">
<option value="">Select Search Type</option>
<option value="1">Surname</option>
<option value="2">Code</option>
<option value="3">PostCode</option>
<option value="4">Address (Line 1)</option>
</select>
Everything else works fine, e.g. selected value on postback is correct.
Thanks!
The API takes in an object of the selected item, try:
SearchList = new SelectList(list, "Value", "Text", list.First());
No need to add Value.
Got it to work by setting the Id in the controller:
var dlvm = new DonorIndexViewModel();
dlvm.SearchListId = 1;
return View(dlvm);
The value of this seems to determine what is selected, so if it's not set - i.e. has a value 0 - then nothing is selected. Seems a bit counter-intuitive, maybe I'll put in a feature request for this!

How to save selected value in dropdownlist in MVC-4 after submit?

How to save chosen value in dropdownlist after submit. So the value that you choose in dropdownlist stays after user click on submit.
In my controller I did this:
List<SelectListItem> uraList = new List<SelectListItem>();
for (int i = 1; i < 7; i++)
{
uraList.Add(new SelectListItem
{
Value = i + ":00",
Text = i + ":00"
});
}
ViewBag.IzberiUro = uraList;
ViewBag.IzbranaUra = model.Ura;
In my Model (I think that here is mistake):
public string Ura { get; set; }
And in View I have:
#Html.DropDownList("Ura", ((IEnumerable<SelectListItem>)ViewBag.IzberiUro).Select(t => new SelectListItem() {Text = t.Text, Value = t.Text,Selected = (t.Text == ViewBag.IzbranaUra)}), new {#class = "css"})
The result is, in view I have dropdownlist with values from 1:00 to 6:00 (whitch is correct, and first choosen value is 1:00), but, when I choose e.g. 4:00 and click on submit, the value in dropdown returns to 1:00.
Realy thanks for help.
my generated HTML is then like this:
<select class="form-control" id="Ura" name="Ura" placeholder="Ura" style="width: 100px;">
<option value="1:00">1:00</option>
<option value="2:00">2:00</option>
<option value="3:00">3:00</option>
<option value="4:00">4:00</option>
<option value="5:00">5:00</option>
<option value="6:00">6:00</option>
</select>
Use DropDownListFor instead of DropDownList
#Html.DropDownListFor(m => m.Ura, Model.uraList)

Able to Select multiple options for radiobuttons in ASP.NET MVC

I am working on developing on a voting page mechanism. Here I will have the List of questions and against each question I have 3 options(I am using radio buttons). I have attached my View and Controller method. I am getting the value saved to DB correctly, but my problem is I am able to select multiple options where radio buttons are used. I want to make sure that, if one option is selected for a question the other options must be automatically deselected, which is not happening for me.
My View :
#using (Html.BeginForm())
{
<div>
#foreach (var a in ViewBag.Questions)
{
<h4>#a.Questions</h4>
<div>
#foreach (var b in Model)
{
if (b.QuestionsID == a.id)
{
#Html.RadioButton(b.AnswersOptions,
new {Answerid= b.id, Questionid=a.id })
#b.AnswersOptions
}
}
</div>
}
</div>
<br/>
<div >
<input type="submit" value="Vote Now!!"
onclick="return confirm('Are you sure you want to
submit your choices?');"/>
</div>
}
My Controller :
public ActionResult VotingResult_Post(FormCollection resultcollection)
{
int resultcollectionCount = resultcollection.Count;
if (resultcollectionCount == CountofQuestionsDisplayed)
{
for (int i = 0; i < resultcollectionCount; i++)
{
string SelectedIDArray = resultcollection[i];
string SelectedAnswerIDValue = GetValue("Answerid", SelectedIDArray);
string SelectedQuestionID = GetValue("Questionid", SelectedIDArray);
InsertUsersReponses(SelectedQuestionID, SelectedAnswerIDValue);
}
}
List<Voting_Questions> QuesList = PopulateQuestions();
ViewBag.Questions = QuesList;
List<Voting_Answers> Answers = aobj.Voting_Answers.ToList();
return View(Answers);
}
You need an HTML helper like the following
public static System.Web.Mvc.MvcHtmlString RadioButtonForSelectList<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
IEnumerable<SelectListItem> listOfValues
{
var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var sb = new StringBuilder();
string ForFormat = String.Empty;
if (listOfValues != null)
{
// Create a radio button for each item in the list
// need to create correct ID here
var baseID = metaData.PropertyName;
foreach (SelectListItem item in listOfValues)
{
// Generate an id to be given to the radio button field
var id = string.Format("{0}_{1}", baseID, item.Value);
// Create and populate a radio button using the existing html helpers
var label = htmlHelper.Label(id, HttpUtility.HtmlEncode(item.Text));
// extracting the text for="##" from the label and using this for the control ID
// ASSUMES the format<label for="TestRadio_1">Line 1</label> and splitting on the quote means that the required value is in the second cell of the array
String[] temp = label.ToString().Split('"');
var radio = htmlHelper.RadioButtonFor(expression, item.Value, new { id = temp[1] }).ToHtmlString();
// Create the html string that will be returned to the client
// e.g. <input data-val="true" data-val-required="Option1" id="TestRadio_1" name="TestRadio" type="radio" value="1" /><label for="TestRadio_1">Line 1</label>
// e.g. <input data-val="true" data-val-required="Option2" id="TestRadio_2" name="TestRadio" type="radio" value="2" /><label for="TestRadio_2">Line 2</label>
sb.AppendFormat("<div class=\"RadioButtonList\">{0}{1}</div>", radio, label);
}
}
return MvcHtmlString.Create(sb.ToString());
which is called as follows:
#Html.ValidationMessageFor(m => m.myProperty)
#Html.LabelFor(m => m.myProperty, new { #class = "editor-label control-label" })
<div class="editor-field controls radio">
#Html.RadioButtonForSelectList(
m => m.myProperty,
ListOfOptionsForRadioButton
)
</div>
The markup is for Bootstrap.

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.

Resources