I have multiple dropdownlists which are rendered with a for loop and I'm having a problem getting them to post the selected value to the controller. In my query my selectlist is made like this:
model.CreateGroupForm.Genders = new List<SelectListItem>
{
new SelectListItem() {Text = "Either", Value = "Either"},
new SelectListItem() {Text = "Male", Value = "Male"},
new SelectListItem() {Text = "Female", Value = "Female"},
};
My first problem was even getting my dropdown to display the database value, even though I confirmed it was retrieving the correct value. It wouldn't work with this:
#for (var c = 0; c < Model.ExistingGroups.Count; c++)
{
#using (Html.BeginForm("EditGroup", "Group", new { id = Model.Id.StripCollectionName(), slug = Model.Slug, innerid = Model.ExistingGroups[c].Id }, FormMethod.Post, new { id = "editcommunityteamform" + c.ToString(CultureInfo.InvariantCulture), #class = "nomarginbottom" }))
{
...
#Html.DropDownListFor(x => x.ExistingGroups[c].Gender, Model.Createform.Genders)
<button type="submit" class="btn btn-primary" title="Update name and description of this group">Update</button>
}
}
After doing some digging on Stack, I discovered that each dropdown rendered needs it's own separate list. So I changed it to:
#Html.DropDownListFor(x => x.ExistingGroups[c].Gender,
new SelectList( Model.CreateGroupForm.Genders,"Value", "Text",Model.ExistingGroups[c].Gender))
This then correctly displays the queried value, however it just posts null to the controller when I submit the form. I'm having the same issue with a checkboxfor boolean within the for loop.
My ActionResult in the controller just expects a string value and looks like this:
public ActionResult EditGroup(EditGroupInput input)
{
var command = new EditGroupCommand(input.Gender);
....
My view model looks like this:
public IList<CommunityGroup> ExistingGroups { get; set; }
public CreateGroupInput CreateGroupForm { get; set; }
And then the above 2 classes have the properties mentioned in the code.
I've discovered the problem, which is that dropdownlistfor, checkboxlistfor etc do not like operating within a 'for' loop. I certainly don't have the technical know-how to understand why, but when I changed dropdownlistfor to dropdownlist it worked. So the solution looks like this:
#for (var c = 0; c < Model.ExistingGroups.Count; c++)
{
#using (Html.BeginForm("EditGroup", "Group", new { id = Model.Id.StripCollectionName(), slug = Model.Slug, innerid = Model.ExistingGroups[c].Id }, FormMethod.Post, new { id = "editcommunityteamform" + c.ToString(CultureInfo.InvariantCulture), #class = "nomarginbottom" }))
{
...
#Html.DropDownList("Gender", new SelectList(Model.CreateGroupForm.Genders, "Value", "Text", Model.ExistingGroups[c].Gender))
...
}
}
EditGroupInput should be a collection of ExistingGroups as controller action method are strongly binded with view.or use formcollection as parameter and see what are all the keys being posted from view to controller.
Related
I have a simple drop down list in Razor syntax:
#{
List<SelectListItem> listItems = new List<SelectListItem>();
listItems.Add(new SelectListItem { Text = "1 kg", Value = "1" });
listItems.Add(new SelectListItem { Text = "2 kg", Value = "2" });
listItems.Add(new SelectListItem { Text = "3 kg", Value = "3" });
listItems.Add(new SelectListItem { Text = "4 kg", Value = "4" });
listItems.Add(new SelectListItem { Text = "5 kg", Value = "5" });
}
#Html.DropDownList("Weight", (IEnumerable<SelectListItem>)listItems, new { #class = "form-control" })
#Html.Hidden("Weight", 0)
I also have a Controller action which gets the data from the form via FormCollection defined as:
[HttpPost]
public ActionResult AddProductsToCart(FormCollection collection /*int ?Id*/)
{
MyDBContext myDBContext = new MyDBContext();
var value = collection["Weight"];
}
But here I'm not able to get value of selected index in the Drop Down List in the collection upon submitting the form. Instead, I get 1, 1, 1 as the only single key in collection.
Any idea would be appreciated. :)
As I tried your code in ASP.NET MVC 4 application,
The HTML is having two same Id for two HTML controls as:
#Html.DropDownList("Weight", (IEnumerable<SelectListItem>)listItems, new { #class = "form-control" })
#Html.Hidden("Weight", 0)
So when you access the data from FormCollection class it finds the two Id on the HTML so it separates each control value by Comma , like [Not sure why]:
So If you want only one value from View for that particular control you can use one variable which is the same name as control name in the method like:
[HttpPost]
public ActionResult AddProductsToCart(/*Might be no need of this*/ FormCollection fc, string Weight)
{
var selectedValue = Weight;
return View();
}
thanks all for your kind response.
FormCollection was returning the values of all the dropdowns which was in view.
I'm having trouble getting the data from a DropDownListFor using a ViewBag list with my model. Here is my Controller code:
[HttpGet]
public ActionResult JoinTeam()
{
var TeamList = _db.TeamModels.ToList();
SelectList list = new SelectList(TeamList, "Id", "TeamName");
ViewBag.TeamList = list;
return View();
}
And the Razor view form looks like this:
#using (Html.BeginForm("JoinTeam", "Home", FormMethod.Post))
{
#Html.TextBoxFor(m => m.DisplayName, new { #class = "form-control form-control-lg", placeholder = "Enter your Battle Net ID" })
<br/>
#Html.DropDownListFor(m => m.TeamModel, (SelectList)ViewBag.TeamList, "- Select a Team to Join -", new { #class= "form-control form-control-lg" })
<br />
<button type="submit" class="btn btn-primary" style="width:100%;text-align:center;">Submit</button>
}
The TextBoxFor helper is returning the data correctly, but whatever option I have selected in the drop down does not get passed into my post method. Does anyone have any ideas?
The post action does work as it's getting the data from the model for the TextBoxFor help, but here's what it looks like:
[HttpPost]
public async Task<ActionResult> JoinTeam(GuardianModel model)
{
try
{
string BNETId = model.DisplayName.Replace("#", "%23");
long memberId = 0;
if (ModelState.IsValid)
{
Bungie.Responses.SearchPlayersResponse member = await service.SearchPlayers(MembershipType.Blizzard, BNETId);
memberId = member[0].MembershipId;
}
using (var context = new CoCodbEntities1())
{
var g = new GuardianModel
{
MembershipId = memberId.ToString(),
DisplayName = BNETId,
MembershipType = 4,
TeamID = model.TeamModel.Id
};
TempData["UserMessage"] = ViewBag.TeamList.Id;
return RedirectToAction("Success");
}
}
catch
{
}
return View();
}
These are the values getting passed into the Post action
From the screenshot you shared, it looks like TeamModel property is the virtual navigational property of type TeamModel. You should not bother about loading that. All you need to worry about loading the forign key property value (usually a simple type like an int or so.
Your SELECT element name should be TeamID. When the form is submitted, it will map the selected option value to the TeamID property value of your model which is the foreign key property.
#Html.DropDownListFor(m => m.TeamID, (SelectList)ViewBag.TeamList,
"- Select a Team to Join -", new { #class= "form-control form-control-lg" })
While this might fix the issue, It is a good idea to use a view model instead of using your entity class.
I found the issues I was having. All I needed to get passed into the post action was the Id of the TeamModel. So I changed this line:
#Html.DropDownListFor(m => m.TeamModel.Id, (SelectList)ViewBag.TeamList, "- Select a Team to Join -", new { #class= "form-control form-control-lg" })
I just added the Id and it seemed to work.
I am creating an web page in which have a Dropdownlist. I have to retrieve data for the drop_down_list from the database. Is there any way to get data from the database to the html view my html code:
<select name="drop down"><option value="1">#test.list[i]</option></select>
I got the database value to the list variable but I don't know how to pass the data to the html view. Please help me in this issue.Thanks
You need to create Select List of Items :
Your Action with List of Items in View Bag :
public ActionResult ActionName()
{
List<SelectListItem> Items = new List<SelectListItem>();
CustReportName.Add(new SelectListItem() { Text = "List1", Value = "1", Selected = false });
CustReportName.Add(new SelectListItem() { Text = "List2", Value = "2", Selected = true });
ViewBag.ListItems = Items;
return View("ViewName");
}
For Multiple values from database table:
public ActionResult ActionName()
{
IEnumerable<SelectListItem> ItemsList = from item in YourTableObject
select new SelectListItem
{
Value = Convert.ToString(item.Id),
Text = item.ItemName
};
ViewBag.ListItems = new SelectList(ItemsList, "Value", "Text");
return View("ViewName");
}
Your DropdownList On view :
#Html.DropDownListFor(model => model.ItemId, new SelectList(ViewBag.ItemList, "Value", "Text", 0), "-Select Item-", new { #class = "form-control", #id = "ItemId" })
Cheers !!
It is just a simple two step process:
Step1 :Action method code
public ActionResult Index()
{
ViewBag.users = db.users.ToList();
}
Step2: cshtml code
#Html.DropDownListFor(model => model.someId, new SelectList(ViewBag.users, "userId", "userName"), "Select users")
Note: with this, you can bind n number of data from the database to dropdownlist
Hope it was useful
Thanks
Karthik
Wrapping my head around MVC.
I have a list of items. I need to load the screen with some of these selected by default.
Loading the items is one thing, trying to select some by default isn't working for me.
Any idea where I am going wrong?
I know there are many answers to a similar question, though I can't seem to translate the answers to my needs.
Here is the code I have, and tried - i am also trying to understand the various options in the html helpers. Please take this into consideration when posting a solution.
This is the most recent iteration of my code; i have gone through a bunch....
In my Controller:
public ActionResult Index()
{
ViewBag.Statuses = AddStatuses();
return View();
}
private MultiSelectList AddStatuses()
{
string[] defaultSelected = { "Ready", "Done", "Error" };
List<SelectListItem> listItems = new List<SelectListItem>();
List<Status> s = allTypes.GetStatuses();
s.ForEach(status =>
{
listItems.Add(new SelectListItem()
{
Text = status.Name,
Value = status.ID.ToString(),
Selected = true,// defaultSelected.Contains(status.Name)
});
});
return new MultiSelectList(listItems, "Value", "Text");
}
In an attempt to test my defaultSelected.Contains, i just commented it out to select ALL as true... still didn't work...
I have tried these in my view
#Html.DropDownList("Statuses", null, null, new { #class = "form-control", multiple = true, id="queueStatuses" })
#Html.ListBox("Name", ViewBag.Statuses as MultiSelectList, new { #class = "form-control", id = "queueStatuses" })
#Html.ListBox("Statuses", null, new { #class = "form-control", id = "queueStatuses" })
I a) don't understand what i am doing and b) can't get it to work... :)
I am looking for:
You can use the ListBoxFor helper method along with the user of a view model to pass the items for your list box.
So create a new view model to transfer data from your action method to view
public class CreateIssue
{
public List<SelectListItem> Statuses { set;get;}
public int[] SelectedStatuses { set;get;}
}
Now in your GET action, create an object of this, load the Statuses collection and send it to the view. If you want to preselect some items, set the SelectedStatuses property.
public ActionResult Index()
{
var vm = new CreateIssue();
//Hard coded for demo. You may replace with values coming from db table.
vm.Statuses = new List<SelectListItem> {
new SelectListItem { Value="1", Text="Ready"},
new SelectListItem { Value="2", Text="Done"},
new SelectListItem { Value="3", Text="Building"},
new SelectListItem { Value="4", Text="Error"},
};
//For preselecting items, set it here
vm.SelectedStates=new int[] { 2,3};
return View(vm);
}
and your in your view, which is strongly typed to the view model, use the ListBoxFor helper method.
#model CreateIssue
#using (Html.BeginForm())
{
<label>Select many statuses</label>
#Html.ListBoxFor(m => m.SelectedStatuses, Model.Statuses)
<input type="submit"/>
}
Thank you #Shyju. I am sure your answer works.
As mentioned in my comments though, I don't want to go through the hoops of having a view model in this instance. I was looking for a simple way to implement this.
Seems all i needed to do was change my MultiSelectList and pass in an array of selected 'value's.
This fixes my issue:
private MultiSelectList AddStatuses()
{
string[] defaultSelected = { "3", "5", "6" };
List<SelectListItem> allItems = new List<SelectListItem>();
List<Status> s = allTypes.GetStatuses();
s.ForEach(status =>
{
allItems.Add(new SelectListItem()
{
Text = status.Name,
Value = status.ID.ToString(),
});
});
return new MultiSelectList(allItems, "Value", "Text", defaultSelected);
}
And my ListBox is the same. Went with this one in the end:
#Html.ListBox("status", (IEnumerable<SelectListItem>)ViewBag.Statuses, new { #class = "form-control" })
I have come across a problem. I am currently attempting to make a users page in which some of the dropdowns are variable and determined by their 'access level'. I then want to save the data from the view into a list and then handle it in the 'Post' controller method. I found this link about a possible solution (Assign selectlist to dynamically created dropdown in MVC) but I am still running into problems.
Here is my controller code I am using to set up the data that needs to generate the dropdowns:
var permData = db.LabPermissions.Where(x => x.AccessLevel == 1).ToList();
//sets up generic dropdown data used for all dropdowns
ViewBag.DropDownData = new List<SelectListItem>
{
new SelectListItem{ Value = "0",Text = "No"},
new SelectListItem{ Value = "1",Text = "Yes"},
};
ViewModel obj = new ViewModel();
obj.DataFromController = permData;
//other viewmodel data
return("MyView",obj);
I then pass the data to my view which looks like this (this is also how the stack overflow link set up the view)
#for(int i = 0; i < Model.DataFromController.Count(); i++)
{
<div class="row">
<div class="col-md-2">
<b>#Html.DisplayFor(m => m.DataFromController[i].Lab.LabName)</b>
</div>
<div class="col-md-2">
#Html.DropDownListFor(m => m.DataFromController[i].Assigner, (SelectList)ViewBag.DropDownData, "Select One")
</div>
<div class="col-md-8">
</div>
</div>
}
After I get this set up, and run the application, this is the error I receive:
Additional information: Cannot convert type 'System.Collections.Generic.List<System.Web.Mvc.SelectListItem>' to 'System.Web.Mvc.SelectList'
And the error is placed on my #Html.DropDownListFor line of code in my view.
Thank you for any help!
Try creating a new selectlist instead and put your selectlistitems in it.
#Html.DropDownListFor(m => m.DataFromController[i].Assigner,
new SelectList(ViewBag.DropDownData, "Value", "Text", "Select One")
Or, since you got a ViewModel you can add a public property that can hold your selectlistitems.
public class ViewModel
{
public IEnumerable<SelectListItem> DropDownData { get; set; }
}
Controller:
var permData = db.LabPermissions.Where(x => x.AccessLevel == 1).ToList();
var vm = new ViewModel();
var list = new List<SelectListItem>
{
new SelectListItem{ Value = "-1", Text = "Select One", Selected = true},
new SelectListItem{ Value = "0",Text = "No"},
new SelectListItem{ Value = "1",Text = "Yes"}
};
vm.DropDownData = list;
vm.DataFromController = permData;
return View(vm);
View:
#model YourNameSpace.Models.ViewModel
#for(int i = 0; i < Model.DataFromController.Count(); i++){
#Html.DropDownListFor(m => m.DataFromController[i].Assigner, Model.DropDownData)
}
I believe that you're trying to cast SelectListItem to SelectList and that is the reason why you're getting that error. I've done the same feature as a part of my project and I'm taking the values for the dropdownlist from the database.
and for displaying, here is my code(modified a bit based on your model variables
My Controller method
public ActionResult GetDropDownList()
{
List<SelectListItem> dropDownList= new List<SelectListItem>();
using (var context = new assessmentEntities())
{
//getting data from the DB
var result = context.getDataFromDB().toList();
foreach (var item in result)
{
dropDownList.Add(new SelectListItem() { Text = item.Variable1, Value = item.Variable2});
}
ViewBag.DropDownData = dropDownList;
}
return View();
}`
Here is my View
#Html.DropDownListFor(m => m.DataFromController[i].Assigner,, new SelectList(ViewBag.DropDownData, "Value", "Text")
Hope so this works for you