SelectList Default Value don't work - asp.net

today I'm having trouble with Default Value for a SelectList in ASP.NET.
here is how I do after trying lots of things I found in the Internet:
#{
IEnumerable<SelectListItem> secteurSelectList = from x in Model.secteurList select new SelectListItem {
Selected = (x.Id == this.GetSessionSecteurId()),
Text = x.Secteur,
Value = x.Id.ToString()
};
SelectList selectList = new SelectList(secteurSelectList, "Value", "Text", secteurSelectList.Where(x => x.Selected==true).FirstOrDefault().Value); }
#Html.DropDownListFor(m => m.secteur, selectList)
Here is the description of My entities:
In the ViewModel I use
public List<AuditSecteur> secteurList { get; set; }
Here is the AuditSecteur's object:
public class AuditSecteur
{
public int Id { get; set; }
public string Secteur { get; set; }
}
This is the result:
<select data-val="true" data-val-number="The field Secteur de l'audit must be a number." data-val-required="The Secteur de l'audit field is required." id="secteur" name="secteur">
<option value="1">option1</option>
<option value="2">option2</option>
<option value="3">option3</option>
</select>
SecteurSelectedList has one item at true for the selected:
SelectedList too:
Thanks to help me

The whole purpose of using the strongly typed helpers is to bind your model properties so in the case of
#Html.DropDownListFor(m => m.secteur, selectList)
if the value of secteur does not match the value of one of your options, then it wont be selected (actually because it cant find a match, the first option will be selected because something needs to be selected).
But there are numerous other issues with your code. First you creating IEnumerable<SelectListItem> (setting the Selected property is pointless since its ignored by the helper), then you create another IEnumerable<SelectListItem> (the SelectList) based on the first one in the next line (whats the point?). The value of the options generated are based on the ID property of AuditSecteur but then you bind to to the Secteur property so it would never post back a correct value anyway. Its not really clear how your using this (you have not included you model, controllers or view) but the correct approach would be something like
View model
public class SecteurVM
{
[Display(Name = "Secteur")]
[Required]
public int? SelectedSecteur { get; set; }
public SelectList SecteurList { get; set; }
}
Controller
public ActionResult Create()
{
List<AuditSecteur> secteurList = // get AuditSecteur items from the database
SecteurVM model = new SecteurVM();
model.SecteurList = new SelectList(secteurList, "ID", "Secteur");
model.SelectedSecteur = // set the default value you want selected here
return View(model)
}
[HttpPost]
public ActionResult Create(SecteurVM model)
{
// model.SelectedSecteur contains the ID of the selected item
}
View
#model SecteurVM
....
#Html.LabelFor(m => m.SelectedSecteur)
#Html.DropDownListFor(m => m.SelectedSecteur, Model.SecteurList, "--Please select--")
#Html.ValidationMessageFor(m => m.SelectedSecteur)
If the value of SelectedSecteur matches one of the ID properties of the items in the list, then that is the option that will be selected when you display the view.

you're binding DropDown to secteur property of the Model while Value propety of the dropdown is Id so dropdown won't find the corresponding value while making pre-selection.
here even if you have defined pre-selected item it will reset while rendering, so i would suggest bind you dropdown to Id instead of secteur.
#Html.DropDownListFor(m => m.Id, selectList)

Related

Bind Value from Dropdown List (Not Key) From Database

I am trying to bind a value from my dropdown list from a database to another database table, not the key. Currently, it is binding the key. The dropdown list displays the values choices. Not sure how to change the value that gets stored in the database table (when the form is submitted) from the key to the value.
Example:
I am using dbo.ResCategory to get values to populate my dropdown list. dbo.ResCategory contains these values:
Key
Description
1
Assisted Living
2
Independent Living
3
Indepdent/Assisted Living
Right now, when I submit the form that contains this dropdown list, even though I select 'Assisted Living' the value being stored in the table is '1' and not 'Assisted Living'.
Here is my Select code from my form Create.cshtml:
<select asp-for="InfoSite.ResType" id="Select1" class="form-select" asp-items="#(new SelectList(Model.DisplayResCatData,"ID", "Description"))"><option value="" selected disabled>---Select Residence Type---</option></select>
And here is my code from Create.cshtml.cs:
public IEnumerable<ResCategory> DisplayResCatData { get; set; }
public async Task OnGet()
{
DisplayResCatData = await _db.ResCategory.ToListAsync();
}
public async Task<IActionResult> OnPost()
{
await _db.InfoSite.AddAsync(InfoSite);
await _db.SaveChangesAsync();
TempData["success"] = "Site Information added successfully.";
return RedirectToPage("Index");
}
}
And from my InfoSite.cs model:
public class InfoSite
{
[Key]
public int ID { get; set; }
[Required]
public string Name { get; set; }
[Display(Name = "Office Type")]
public string? Specialty { get; set; }
[Display(Name = "Res Type")]
public string? ResType { get; set; }
[Display(Name = "Res Sub Type")]
public string? ResSubType { get; set; }
I'm guessing it's just one small change, but haven't found anything on it when Googling for an answer.
If anyone has any ideas, I could sure use the help. This has been posted for awhile and no takers. If it can't be done, please let me know that. Thanks!
New knowledge. I did not know what the values in the SelectList constructor did. Finally, found a site that explained the difference.
SYNTAX:
public SelectList (System.Collections.IEnumerable items, string dataValueField, string dataTextField);
dataValueField = the value that will be binded in your database
dataTextField = the value that will be displayed in the dropdown list.
Therefore:
<select asp-for="InfoSite.ResType" id="Select1" class="form-select" asp-items="#(new SelectList(Model.DisplayResCatData,"ID", "Description"))"><option value="" selected disabled>---Select Residence Type---</option></select>
Should be:
<select asp-for="InfoSite.ResType" id="Select1" class="form-select" asp-items="#(new SelectList(Model.DisplayResCatData,"Description", "Description"))"><option value="" selected disabled>---Select Residence Type---</option></select>
Yes, it was something very simple, but a show stopper if you didn't know it.

ASP.NET MVC ListBox does not show the selected list items

I am in a big trouble. I read 4 stackoverflow question and one blogpost. I have tried 5 different approach to view the selected items in a multiple selectlist.
I have no success.
The multiple selectlist is generated, but it does not select the items. I have no more idea.
Model:
public class EditableModel
{
public IList<Company> SelectedCompanies { get; set; }
public IList<SelectListItem> SelectListCompanies { get; set; }
}
Controller:
public ActionResult Edit(int id)
{
var service = _serviceDAL.GetEditableModel(id);
if (service!= null)
{
service.SelectListCompanies = GetSelectListCompanies(service.SelectedCompanies);
return View(service);
}
}
private IList<SelectListItem> GetSelectListCompanies(IList<Company> selectedCompanies)
{
List<SelectListItem> items = new List<SelectListItem>();
foreach (Companycompany in _companyService.GetCompanies())
{
items.Add(new SelectListItem
{
Value = company.CompanyId.ToString(),
Text = company.Name,
Selected = selectedCompanies.Any(x => x.CompanyId == company.CompanyId)
});
}
return items;
}
View
#Html.ListBox("SelectedCompanies", Model.SelectListCompanies, Model.SelectedCompanies.Select(x => x.CompanyId.ToString()) )
And nothing. The items in the select list is not selected...
I have tried this Multiselect, the same result, or this one as the current solution.
You cannot bind a <select multiple> to a collection of complex objects. It binds to, and posts back an array of simple values (the values of the selected options).
Your SelectedCompanies property needs to be IEnumerable<int> (assuming the CompanyId of Company is also int). Note also the Selected property of SelectListItem is ignored when binding to a property.
Your also using the same collection for the selected Companies and the list of all Companies which makes no sense. Your SelectListCompanies should be generated from your table of Company.
Model
public class MyViewModel
{
public IEnumerable<int> SelectedCompanies { get; set; }
public IEnumerable<SelectListItem> SelectListCompanies { get; set; }
}
Base on your current code for EditableModel, your code should be
public ActionResult Edit(int id)
{
var service = _serviceDAL.GetEditableModel(id);
....
MyViewModel model = new MyViewModel
{
SelectedCompanies = service.SelectedCompanies.Select(x => x.CompanyId),
SelectListCompanies = GetSelectListCompanies()
};
return View(model);
private IEnumerable<SelectListItem> GetSelectListCompanies()
{
var all companies = ... // call method to get all Companies
return companies.Select(x => new SelectListItem
{
Value = x.CompanyId.ToString(),
Text = x.Name
});
}
However, it look like you should be modifying your EditableModel and the GetEditableModel() code to return the correct data in the first place.

How to tie a data model to multiple groups of radio buttons?

I need to present to the user a list of yes/no type questions. Here are my models:
class QuestionModel {
public String ID {get; set;}
public String Title {get; set; }
public bool Value {get; set; }
}
class QuestionsModel {
List<QuestionModel> Questions {get; set}
}
In my Razor code, I might be able to do something like:
#foreach(var item in Model.Questions) {
#Html.Label(item.Title);
#Html.RadioButton(item.ID, "Yes");
#Html.RadioButton(item.ID, "No");
}
However, I don't see how the Value field in QuestionModel will get populated based on what the user has selected. Please help. Regards.
Firstly you need to use a for loop or an EditorTemplate for generating a collection otherwise the controls will not be named correctly and cannot be bound on post back
#model QuestionsModel
#(using Html.BeginForm())
{
for (int i = 0; i < Model.Questions.Count; i++)
{
string yes = i + "Yes";
string no = i + "No";
#Html.HiddenFor(m => m.Questions[i].ID)
#Html.DisplayFor(m => m.Questions[i].Title) // assuming you don't want to edit this
#Html.RadioButtonFor(m => m.Questions[i].Value, true, new { id = #yes })
<label for="#yes">Yes</label>
#Html.RadioButtonFor(m => m.Questions[i].Value, false, new { id = #no })
<label for="#no">No</label>
}
<input type="submit" value="Save" />
}

Html.Dropdownlist selected value is not posted back to the Controller from view

I am trying to have a dropdownlist on Create.chtml where a user can select a 'NAME' from the dropdownlist and the corresponding value (ID) should be sent back to controller to add it to the database table.
What is working: I can see the dropdownlist with NAMES on the Create.chtml view page
What is NOT working: when a NAME is selected from the dropdownlist in the view, its value (ID) is not passed to Controller
Please see the code below to identify where I might be doing it wrong.
Controller:
//
// GET: /OrganizationCodes/Create
public ActionResult Create()
{
var orgzList = (from x in db.TABLE_ORGANIZATIONS
select new TABLE_ORGANIZATIONSDTO
{
ID = x.ID,
NAME = x.NAME
}).OrderBy(w => w.NAME).ToList();
ViewBag.orgz = new SelectList(orgzList, "ID", "NAME");
return View();
}
public class TABLE_ORGANIZATIONSDTO
{
public string NAME { get; set; }
public int ID { get; set; }
}
//
// POST: /OrganizationCodes/Create
[HttpPost]
public ActionResult Create(TABLE_CODES dp)
{
try
{
using (var db = new IngestEntities())
{
TABLE_CODES codes_temp = new TABLE_CODES();
ViewBag.orgz = codes_temp;
db.AddToTABLE_CODES(dp);
db.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
===================================================================================
View: 'Create.chtml'
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<div class="editor-field">
#Html.DropDownList("orgz", (SelectList)ViewBag.orgz)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Edit 1:
Edit 2:
I am trying to have a view with a dropdownlist of NAMES with value as ID from table 'TABLE_ORGANIZATIONS' which should be added to table 'TABLE_CODES' -> 'MANAGER' column as a number
On your action Create, [HttpPost] version, in which variable are you expecting to see the value of your selected name?
You've named your <select> element with id = "orgz", but you don't have a parameter to your action method named "orgz".
Edit:
When you do:
#Html.DropDownList("orgz", (SelectList)ViewBag.orgz)
You're going to end up with HTML like this:
<select id="orgz" name="orgz">...</select>
When the form is posted back to the controller action, it will try to find a variable called "orgz" that it will put the selected item from your <select> element into. You are missing this.
Try changing your [HttpPost] version of Create to include an "orgz" variable:
public ActionResult Create(TABLE_CODES dp, int orgz)
{
// orgz will contain the ID of the selected item
}
Then your variable "orgz" will contain the ID of the selected item from your drop down list.

How to create a radiobutton group using an editor template in Razor

I have the following model
public class FilterSetting
{
public FilterType Type { get; set; }
public ShowOption Option { get; set; }
public bool IsMultiple { get; set; }
public List<int> SelectedValues { get; set; }
public List<SelectListItem> Values { get; set; }
public int RowCount { get; set; }
}
public enum ShowOption
{
Common,
Also,
All
}
I want to create a radio button group for the ShowOption enum, but I want to display that group using an editor template because I have another model that creates a list of FilterSetting and it will display about 7 FilterSettings each of one must have a group of 3 radio buttons for the ShowOption property.
The problem is when razor is rendering the radio buttons from the editor template it uses the same name for every radio button (name="filter.Option") and I don't know how to set the value.
This is my editor template
#model Models.FilterSetting
#Html.RadioButtonFor(f => f.Option, "Common", new { id = ""+ Model.Type })
#Html.Label(""+Model.Type, "Show only common assets")
<br />
#Html.RadioButtonFor(f => f.Option, "Also", new { id = "" + Model.Type })
#Html.Label(""+Model.Type, "Also show assets matching the values selected below")
<br />
#Html.RadioButtonFor(f => f.Option, "All", new { id = "" + Model.Type })
#Html.Label(""+Model.Type, "Show all assets")
<br />
#if (Model.IsMultiple)
{
#Html.ListBoxFor(f => f.SelectedValues, Model.Values)
}
else
{
#Html.DropDownListFor(f => f.SelectedValues, Model.Values, new { size = "4" })
}
I tried passing the name on the htmlAttributes object but it doesn't work.
EDIT:
Apparently the issue is the way I am calling the editor.
I'm calling it in this way
#foreach (var filter in Model.FilterSettings)
{
....
#Html.EditorFor(f => filter)
}
And when I call it like this
#Html.EditorFor(f => f.filterSettings)
The radio buttons work properly. What's happening when I do the for each?
Thanks for all the help!
When you call the Editor/EditorFor for a collection Razor will keep track of the names and ids generated and so you will get the names generated as for ex. Addresses[0].Line1, Addresses[1].Line1...
But when you iterate the collection yourself and call the editor for the each model razor don't keeps the track for the names and ids (how should it be? is that won't be more complicated?) and it's thinks as a new control going to be rendered in the page.
Usually I use an #Html.HiddenFor(x=>x.id) and #Html.HiddenFor(x=>x.name), try this

Resources