How am I able to select multiple items in a Listbox that will be passed to the controller's Post model parameter?
I'm able to physically select multiple via holding CTRL, but when I submit, I get the validation error message, "The field TagId must be a number." It only submits with one item selected.
Create View Form showing multiple items selected
The List Box
#Html.ListBoxFor(model => model.allTags[0].TagId, new SelectList(Model.allTags, "TagId", "Name"), new { #class = "form-control", #Id = "SelectTags", #style = "width:200px;height:300px;" })
The controller Post method
[HttpPost]
public ActionResult Create(CreateRecipe model)
{
try
{
// TODO: Add insert logic here
return RedirectToAction("ViewRecipes");
}
catch
{
return View();
}
}
Thank you
You can try the following code to select multiple items from ListBoxFor and pass it to controller Post method.
Controller:
public class TestController : Controller
{
// GET: Test
public ActionResult Index()
{
var model = new UserModel
{
SelectedTeaIds = new[] { 3 },
TeaList = GetAllTeaTypes()
};
return View(model);
}
[HttpPost]
public ActionResult Index(UserModel model)
{
model.TeaList = GetAllTeaTypes();
if (model.SelectedTeaIds != null)
{
List<SelectListItem> selectedItems = model.TeaList.Where(p => model.SelectedTeaIds.Contains(int.Parse(p.Value))).ToList();
foreach (var Tea in selectedItems)
{
Tea.Selected = true;
ViewBag.Message += Tea.Text + " | ";
}
}
return View(model);
}
public List<SelectListItem> GetAllTeaTypes()
{
List<SelectListItem> items = new List<SelectListItem>();
items.Add(new SelectListItem { Text = "General Tea", Value = "1" });
items.Add(new SelectListItem { Text = "Coffee", Value = "2" });
items.Add(new SelectListItem { Text = "Green Tea", Value = "3" });
items.Add(new SelectListItem { Text = "Black Tea", Value = "4" });
return items;
}
}
Model:
public class UserModel
{
public int[] SelectedTeaIds { get; set; }
public IEnumerable<SelectListItem> TeaList { get; set; }
}
Index.cshtml:
#using WebApplication1.Models
#using System
#model UserModel
#{
ViewBag.Title = "Index";
}
<b>Select Tea Type: </b>
<br />
#using (Html.BeginForm("Index", "Test", FormMethod.Post))
{
<b>Select Tea Type: </b>
<br />
#Html.ListBoxFor(x => x.SelectedTeaIds, Model.TeaList, new { style = "width:200px" })
<br />
<input type="submit" value="submit" />
}
<h4>You Selected</h4>
<b style="color:red">Tea Type: #ViewBag.Message</b>
Result:
My drop-down can show up but it is always empty.
I've tried using a ViewBag, a DropDownList, and List but none of these will populate the drop down for me.
Model
public IEnumerable<SelectListItem> AccountTypeECheck { get; set; }
Controller
ViewBag.AccountTypeECheck = new List<SelectListItem>() {
new SelectListItem() {
Value = "creditCard",
Text = "creditCard"
}
};
View
#Html.DropDownList(
"value",
(IEnumerable<SelectListItem>) ViewBag.AccountTypeECheck,
null,
new { #class ="form-control" }
)
Try this:
Controller:
var selectListItems = new List<SelectListItem>() { new SelectListItem() { Value = "creditCard", Text = "creditCard" } };
ViewBag.AccountTypeECheck = new SelectList(selectListItems, "Value", "Text");
View:
#Html.DropDownList("AccountTypeECheck", null, new { #class ="form-control" })
Use the ViewBag's property name (in your example AccountTypeECheck) as name parameter for DropDownList.
Reference: Using the DropDownList Helper with ASP.NET MVC
Your missing a model member, try this:
Model:
public IEnumerable<SelectListItem> AccountTypeECheck { get; set; }
public string AccountType {get;set;}
Action Method:
var model = new Model();
model.AccountTypeECheck = new List<SelectListItem>() {
new SelectListItem() {
Value = "creditCard",
Text = "creditCard"
}
};
return View(model);
View:
#model Model
#Html.DropDownListFor(x => x.AccountType, Model.AccountTypeECheck)
Hey I have tried following to set the selected value for dropdownlist.
In My controller:
u.Roles = new List<AspNetRole>();
foreach (var role in db.AspNetRoles)
{
u.Roles.Add(role);
}
And in my View:
#Html.DropDownList(Model.role.Id, new SelectList(Model.Roles, "Id", "Name"), htmlAttributes: new { #class = "form-control"})
But still not working, I did not got the selected value. When debugging I can see that Model.role.Id contains the selected value.
Note also that the Id is of type string, because it is hashed.
What I am doing wrong?
There are few ways of display DropDownList in MVC. I like the following approach.
Note: You need a collection of SelectListItem in model.
Model
public class MyModel
{
public int SelectedId { get; set; }
public IList<SelectListItem> AllItems { get; set; }
public MyModel()
{
AllItems = new List<SelectListItem>();
}
}
Controller
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyModel();
model.AllItems = new List<SelectListItem>
{
new SelectListItem { Text = "One", Value = "1"},
// *** Option two is selected by default ***
new SelectListItem { Text = "Two", Value = "2", Selected = true},
new SelectListItem { Text = "Three", Value = "3"}
};
return View(model);
}
[HttpPost]
public ActionResult Index(MyModel model)
{
// Get the selected value
int id = model.SelectedId;
return View();
}
}
View
#model DemoMvc.Controllers.MyModel
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
#Html.DropDownListFor(x => x.SelectedId, Model.AllItems)
<input type="submit" value="Submit" />
}
I have dropdownlist, which I have filled from database. Now I need to get the selected value in Controller do some manipulation. But not getting the idea. Code which I have tried.
Model
public class MobileViewModel
{
public List<tbInsertMobile> MobileList;
public SelectList Vendor { get; set; }
}
Controller
public ActionResult ShowAllMobileDetails()
{
MobileViewModel MV = new MobileViewModel();
MV.MobileList = db.Usp_InsertUpdateDelete(null, "", "", null, "", 4, MergeOption.AppendOnly).ToList();
MV.Vendor = new SelectList(db.Usp_VendorList(), "VendorId", "VendorName");
return View(MV);
}
[HttpPost]
public ActionResult ShowAllMobileDetails(MobileViewModel MV)
{
string strDDLValue = ""; // Here i need the dropdownlist value
return View(MV);
}
View
<table>
<tr>
<td>Mobile Manufacured</td>
<td>#Html.DropDownList("ddlVendor", Model.Vendor, "Select Manufacurer") </td>
</tr>
<tr>
<td>
</td>
<td>
<input id="Submit1" type="submit" value="search" />
</td>
</tr>
</table>
1st Approach (via Request or FormCollection):
You can read it from Request using Request.Form , your dropdown name is ddlVendor so pass ddlVendor key in the formCollection to get its value that is posted by form:
string strDDLValue = Request.Form["ddlVendor"].ToString();
or Use FormCollection:
[HttpPost]
public ActionResult ShowAllMobileDetails(MobileViewModel MV,FormCollection form)
{
string strDDLValue = form["ddlVendor"].ToString();
return View(MV);
}
2nd Approach (Via Model):
If you want with Model binding then add a property in Model:
public class MobileViewModel
{
public List<tbInsertMobile> MobileList;
public SelectList Vendor { get; set; }
public string SelectedVendor {get;set;}
}
and in View:
#Html.DropDownListFor(m=>m.SelectedVendor , Model.Vendor, "Select Manufacurer")
and in Action:
[HttpPost]
public ActionResult ShowAllMobileDetails(MobileViewModel MV)
{
string SelectedValue = MV.SelectedVendor;
return View(MV);
}
UPDATE:
If you want to post the text of selected item as well, you have to add a hidden field and on drop down selection change set selected item text in the hidden field:
public class MobileViewModel
{
public List<tbInsertMobile> MobileList;
public SelectList Vendor { get; set; }
public string SelectVendor {get;set;}
public string SelectedvendorText { get; set; }
}
use jquery to set hidden field:
<script type="text/javascript">
$(function(){
$("#SelectedVendor").on("change", function {
$("#SelectedvendorText").val($(this).text());
});
});
</script>
#Html.DropDownListFor(m=>m.SelectedVendor , Model.Vendor, "Select Manufacurer")
#Html.HiddenFor(m=>m.SelectedvendorText)
Model
Very basic model with Gender field. GetGenderSelectItems() returns select items needed to populate DropDownList.
public enum Gender
{
Male, Female
}
public class MyModel
{
public Gender Gender { get; set; }
public static IEnumerable<SelectListItem> GetGenderSelectItems()
{
yield return new SelectListItem { Text = "Male", Value = "Male" };
yield return new SelectListItem { Text = "Female", Value = "Female" };
}
}
View
Please make sure you wrapped your #Html.DropDownListFor in a form tag.
#model MyModel
#using (Html.BeginForm("MyController", "MyAction", FormMethod.Post)
{
#Html.DropDownListFor(m => m.Gender, MyModel.GetGenderSelectItems())
<input type="submit" value="Send" />
}
Controller
Your .cshtml Razor view name should be the same as controller action name and folder name should match controller name e.g Views\MyController\MyAction.cshtml.
public class MyController : Controller
{
public ActionResult MyAction()
{
// shows your form when you load the page
return View();
}
[HttpPost]
public ActionResult MyAction(MyModel model)
{
// the value is received in the controller.
var selectedGender = model.Gender;
return View(model);
}
}
Going further
Now let's make it strongly-typed and enum independent:
var genderSelectItems = Enum.GetValues(typeof(Gender))
.Cast<string>()
.Select(genderString => new SelectListItem
{
Text = genderString,
Value = genderString,
}).AsEnumerable();
MVC 5/6/Razor Pages
I think the best way is with strongly typed model, because Viewbags are being aboused too much already :)
MVC 5 example
Your Get Action
public async Task<ActionResult> Register()
{
var model = new RegistrationViewModel
{
Roles = GetRoles()
};
return View(model);
}
Your View Model
public class RegistrationViewModel
{
public string Name { get; set; }
public int? RoleId { get; set; }
public List<SelectListItem> Roles { get; set; }
}
Your View
<div class="form-group">
#Html.LabelFor(model => model.RoleId, htmlAttributes: new { #class = "col-form-label" })
<div class="col-form-txt">
#Html.DropDownListFor(model => model.RoleId, Model.Roles, "--Select Role--", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.RoleId, "", new { #class = "text-danger" })
</div>
</div>
Your Post Action
[HttpPost, ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegistrationViewModel model)
{
if (ModelState.IsValid)
{
var _roleId = model.RoleId,
MVC 6 It'll be a little different
Get Action
public async Task<ActionResult> Register()
{
var _roles = new List<SelectListItem>();
_roles.Add(new SelectListItem
{
Text = "Select",
Value = ""
});
foreach (var role in GetRoles())
{
_roles.Add(new SelectListItem
{
Text = z.Name,
Value = z.Id
});
}
var model = new RegistrationViewModel
{
Roles = _roles
};
return View(model);
}
Your View Model will be same as MVC 5
Your View will be like
<select asp-for="RoleId" asp-items="Model.Roles"></select>
Post will also be same
Razor Pages
Your Page Model
[BindProperty]
public int User User { get; set; } = 1;
public List<SelectListItem> Roles { get; set; }
public void OnGet()
{
Roles = new List<SelectListItem> {
new SelectListItem { Value = "1", Text = "X" },
new SelectListItem { Value = "2", Text = "Y" },
new SelectListItem { Value = "3", Text = "Z" },
};
}
<select asp-for="User" asp-items="Model.Roles">
<option value="">Select Role</option>
</select>
I hope it may help someone :)
If you want to use #Html.DropDownList , follow.
Controller:
var categoryList = context.Categories.Select(c => c.CategoryName).ToList();
ViewBag.CategoryList = categoryList;
View:
#Html.DropDownList("Category", new SelectList(ViewBag.CategoryList), "Choose Category", new { #class = "form-control" })
$("#Category").on("change", function () {
var q = $("#Category").val();
console.log("val = " + q);
});
If you're looking for something lightweight, I'd append a parameter to your action.
[HttpPost]
public ActionResult ShowAllMobileDetails(MobileViewModel MV, string ddlVendor)
{
string strDDLValue = ddlVendor; // Of course, this becomes silly.
return View(MV);
}
What's happening in your code now, is you're passing the first string argument of "ddlVendor" to Html.DropDownList, and that's telling the MVC framework to create a <select> element with a name of "ddlVendor." When the user submits the form client-side, then, it will contain a value to that key.
When MVC tries to parse that request into MV, it's going to look for MobileList and Vendor and not find either, so it's not going to be populated. By adding this parameter, or using FormCollection as another answer has suggested, you're asking MVC to specifically look for a form element with that name, so it should then populate the parameter value with the posted value.
Use SelectList to bind #HtmlDropdownListFor and specify selectedValue parameter in it.
http://msdn.microsoft.com/en-us/library/dd492553(v=vs.108).aspx
Example : you can do like this for getting venderid
#Html.DropDownListFor(m => m.VendorId,Model.Vendor)
public class MobileViewModel
{
public List<tbInsertMobile> MobileList;
public SelectList Vendor { get; set; }
public int VenderID{get;set;}
}
[HttpPost]
public ActionResult Action(MobileViewModel model)
{
var Id = model.VenderID;
I was having the same issue in asp.NET razor C#
I had a ComboBox filled with titles from an EventMessage, and I wanted to show the Content of this message with its selected value to show it in a label or TextField or any other Control...
My ComboBox was filled like this:
#Html.DropDownList("EventBerichten", new SelectList(ViewBag.EventBerichten, "EventBerichtenID", "Titel"), new { #class = "form-control", onchange = "$(this.form).submit();" })
In my EventController I had a function to go to the page, in which I wanted to show my ComboBox (which is of a different model type, so I had to use a partial view)?
The function to get from index to page in which to load the partial view:
public ActionResult EventDetail(int id)
{
Event eventOrg = db.Event.Include(s => s.Files).SingleOrDefault(s => s.EventID == id);
// EventOrg eventOrg = db.EventOrgs.Find(id);
if (eventOrg == null)
{
return HttpNotFound();
}
ViewBag.EventBerichten = GetEventBerichtenLijst(id);
ViewBag.eventOrg = eventOrg;
return View(eventOrg);
}
The function for the partial view is here:
public PartialViewResult InhoudByIdPartial(int id)
{
return PartialView(
db.EventBericht.Where(r => r.EventID == id).ToList());
}
The function to fill EventBerichten:
public List<EventBerichten> GetEventBerichtenLijst(int id)
{
var eventLijst = db.EventBericht.ToList();
var berLijst = new List<EventBerichten>();
foreach (var ber in eventLijst)
{
if (ber.EventID == id )
{
berLijst.Add(ber);
}
}
return berLijst;
}
The partialView Model looks like this:
#model IEnumerable<STUVF_back_end.Models.EventBerichten>
<table>
<tr>
<th>
EventID
</th>
<th>
Titel
</th>
<th>
Inhoud
</th>
<th>
BerichtDatum
</th>
<th>
BerichtTijd
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.EventID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Titel)
</td>
<td>
#Html.DisplayFor(modelItem => item.Inhoud)
</td>
<td>
#Html.DisplayFor(modelItem => item.BerichtDatum)
</td>
<td>
#Html.DisplayFor(modelItem => item.BerichtTijd)
</td>
</tr>
}
</table>
VIEUW: This is the script used to get my output in the view
<script type="text/javascript">
$(document).ready(function () {
$("#EventBerichten").change(function () {
$("#log").ajaxError(function (event, jqxhr, settings, exception) {
alert(exception);
});
var BerichtSelected = $("select option:selected").first().text();
$.get('#Url.Action("InhoudByIdPartial")',
{ EventBerichtID: BerichtSelected }, function (data) {
$("#target").html(data);
});
});
});
</script>
#{
Html.RenderAction("InhoudByIdPartial", Model.EventID);
}
<fieldset>
<legend>Berichten over dit Evenement</legend>
<div>
#Html.DropDownList("EventBerichten", new SelectList(ViewBag.EventBerichten, "EventBerichtenID", "Titel"), new { #class = "form-control", onchange = "$(this.form).submit();" })
</div>
<br />
<div id="target">
</div>
<div id="log">
</div>
</fieldset>
Thanks - this helped me to understand better ansd solve a problem I had.
The JQuery provided to get the text of selectedItem did NOT wwork for me
I changed it to
$(function () {
$("#SelectedVender").on("change", function () {
$("#SelectedvendorText").val($(**"#SelectedVender option:selected"**).text());
});
});
Simple solution not sure if this has been suggested or not. This also may not work for some things. That being said this is the simple solution below.
new SelectListItem { Value = "1", Text = "Waiting Invoices", Selected = true}
List<SelectListItem> InvoiceStatusDD = new List<SelectListItem>();
InvoiceStatusDD.Add(new SelectListItem { Value = "0", Text = "All Invoices" });
InvoiceStatusDD.Add(new SelectListItem { Value = "1", Text = "Waiting Invoices", Selected = true});
InvoiceStatusDD.Add(new SelectListItem { Value = "7", Text = "Client Approved Invoices" });
#Html.DropDownList("InvoiceStatus", InvoiceStatusDD)
You can also do something like this for a database driven select list. you will need to set selected in your controller
#Html.DropDownList("ApprovalProfile", (IEnumerable<SelectListItem>)ViewData["ApprovalProfiles"], "All Employees")
Something like this but better solutions exist this is just one method.
foreach (CountryModel item in CountryModel.GetCountryList())
{
if (item.CountryPhoneCode.Trim() != "974")
{
countries.Add(new SelectListItem { Text = item.CountryName + " +(" + item.CountryPhoneCode + ")", Value = item.CountryPhoneCode });
}
else {
countries.Add(new SelectListItem { Text = item.CountryName + " +(" + item.CountryPhoneCode + ")", Value = item.CountryPhoneCode,Selected=true });
}
}
I have got a drop downlist that, and i need to set the selected value in a view ,later on when the user selected any item in drop down list , i need to pass that one to model.. I am binding dropdown list in controller like this way ..
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index()
{
var itemsforDropdown = new List<SelectListItem> {
new SelectListItem{ Text = "Amount" , Value = "Amount"},
new SelectListItem{Text= "Pound", Value ="Pound"},
new SelectListItem {Text ="Percent", Value ="Percent"}
};
ViewBag.ItemsforDrop = itemsforDropdown;
//ViewData["listitem"] = itemsforDropdown;
return View("DdlCrossFields");
}
and I have got a property in my model like this...
public class CrossFieldValidation
{
[ValueMustbeInRange]
public string DDlList1
{ get; set; }
public string SelectedValue
{ get; set; }
// [Required(ErrorMessage = "Quantity is required")]
[Display(Name = "Quantity:")]
public string TxtCrossField
{ get; set; }
}
and this is my view ...
#using (Html.BeginForm("PostValues", "CrossFieldsTxtboxes"))
{
#Html.ValidationSummary(true)
<div class ="editor-field">
#Html.TextBoxFor(m => m.TxtCrossField)
#Html.ValidationMessageFor(m=>m.TxtCrossField)
</div>
#Html.DropDownList("ItemsforDrop", ViewBag.ItemsforDrop as SelectList,"Select A state", new {id= "State"})
//here i need to get the selected value and i need to pass the this on to model fro future purpose "
<input id="PostValues" type="Submit" value="PostValues" />
}
would any one pls help on this ...
many thanks.....
I'm finding it hard to figure out exactly what you are trying to achieve here but I would set up the page like below.
This way, the CrossFieldValidation is sent to the PostValues with the selected value in the list
Model
public class CrossFieldValidation
{
[ValueMustbeInRange]
public string DDlList1
{ get; set; }
/* add the items list into the model */
public IEnumerable<SelectListItem> Items
{ get; set; }
public string SelectedValue
{ get; set; }
[Display(Name = "Quantity:")]
public string TxtCrossField
{ get; set; }
}
Controller
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index()
{
var model = new CrossFieldValidation {
Items = new [] {
new SelectListItem{ Text = "Amount" , Value = "Amount"},
new SelectListItem{Text= "Pound", Value ="Pound"},
new SelectListItem {Text ="Percent", Value ="Percent"}
}
};
return View(model);
}
View
#model CrossFieldValidation
#using (Html.BeginForm("PostValues", "CrossFieldsTxtboxes"))
{
#Html.ValidationSummary(true)
<div class ="editor-field">
#Html.TextBoxFor(m => m.TxtCrossField)
#Html.ValidationMessageFor(m=>m.TxtCrossField)
</div>
#Html.DropDownListFor(m=>m.SelectedValue, new SelectList(Model.Items, "Value", "Text"))
<input id="PostValues" type="Submit" value="PostValues" />
}
In your controller [HttpPost] action add below.
string selectedVal = Request.Form["ItemsforDrop"].ToString();