I have an HTML dropdown list:
<select name="status">
<option value="close" >Close Task</option>
<option value="open" >Reopen Task</option>
</select>
I want to set the 'selected' option based on the 'Task.Completion' property in my view model:
public class TaskEditViewModel
{
public Task Task { get; set; }
public TaskComment TaskComment { get; set; }
}
So if Task.Completion is NULL, the 'close' option is selected, otherwise the 'open' option is selected.
How can I do this?
Your view model doesn't seem adapted to what you are trying to do in the view (which according to your question is show a dropdown list and preselect a value based on some property on your view model).
So a far more realistic view model would be this:
public class TaskEditViewModel
{
public string Completion { get; set; }
public IEnumerable<SelectListItem> Actions
{
get
{
return new[]
{
new SelectListItem { Value = "close", Text = "Close Task" },
new SelectListItem { Value = "open", Text = "Reopen Task" },
};
}
}
}
then you could have a controller action which will populate and pass this view model to the view:
public ActionResult Foo()
{
var model = new TaskEditViewModel();
// this will automatically preselect the second item in the list
model.Completion = "open";
return View(model);
}
and finally inside your strongly typed view you could use the DropDownListFor helper to render this dropdown:
#model TaskEditViewModel
#Html.DropDownListFor(x => x.Completion, Model.Actions)
Related
I'm currently trying to pass a object called DropDown from a View to a controller action using HTML.DropDownFor() and a form.
The object looks like this:
public class DropDown
{
public int id { get; set; }
public string value { get; set; }
}
The view Model looks like this:
public class GraphViewModel
{
public DropDown SelectedGraphTypeDropDown { get; set; }
public IEnumerable<DropDown> GraphTypeDropDowns { get; set; }
}
The controller action looks like this:
[HttpPost]
public string GetTestData(DropDown SelectedGraphTypeDropDown)
{
// use above object here
}
And the view like so:
#using (Html.BeginForm("GetTestData", "Graph", FormMethod.Post))
{
#Html.DropDownListFor(m => m.SelectedGraphTypeDropDown, new SelectList(Model.GraphTypeDropDowns, "id", "value"))
<input type="submit" />
}
Rendered HTML
What I expect to happen is the selected GraphType will be passed to the GetTestData action and resolved as a whole object called "SelectedGraphTypeDropDown".
I have debugged through it and it seems that the selected GraphType id (int) is passed to the controller but the whole object is not. I have also tried to pass each field of the selectedGraphTypeDropDown but this wont work as the fields are set after the page is rendered.
Also is there a way to pass the full viewModel to the controller?
Any advice would be apricated thanks!
Firstly,dropdown cannot pass a model,but you can add hidden input to bind value.Here is a demo:
view:
#using (Html.BeginForm("GetTestData", "Graph", FormMethod.Post))
{
#Html.DropDownListFor(m => m.SelectedGraphTypeDropDown.id, new SelectList(Model.GraphTypeDropDowns, "id", "value"))
<input id="value" name="SelectedGraphTypeDropDown.value" hidden/>
<input type="submit" />
}
js(js will bind selected value to hidden input):
$(function () {
$("#value").val($(this).find("option:selected").text());
})
$("#SelectedGraphTypeDropDown_id").change(function () {
$("#value").val($(this).find("option:selected").text());
})
result:
I'm using this Bootstrap Multiselect and my problem is that I cant get the selected values on HttpPost on ASP.Net MVC.
Problems Encountered:
after clicking save, Only the first selected value is the present on
the model. (SOLVED)
after clicking save, Only the first selected value is the present on
the dropdownlist.
Sample.chtml:
#model SampleProject.Models.SampleViewModel
#using (Html.BeginForm())
{
#Html.DropDownListFor(model => model.Selected, new SelectList(Model.List, "value", "text"), new { #class = "multiselect form-control", multiple = "multiple" })
<input type="submit" value="Save" />
}
Model:
public class SampleViewModel
{
public string[] Selected { get; set; }
public SelectList List { get; set; }
}
Controller:
public class DashboardController : Controller
{
public ActionResult Sample()
{
SampleViewModel model = new SampleViewModel();
model.List = new SelectList(new List<string>() { "1", "2", "3" });
return View(model);
}
[HttpPost]
public ActionResult Sample(SampleViewModel model)
{
model.List = new SelectList(new List<string>() { "1", "2", "3" });
return View(model);
}
}
Selection:
I cant get the selected values correctly on HttpPost
Code Behind/HttpPost: (Wrong)
After HttpPost: (Correct)
A <select multiple="multiple"> posts back an array of values (not a single value). You property Selected needs to be IEnumerable, for example
public string[] Selected { get; set; }
Side note: Since the text and value properties are the same, you can simplify you code by making the List property SelectList
public SelectList List { get; set; }
and then in the controller
model.List = new SelectList(new List<string>() { "1", "2", "3" })
(although its not clear why you would not use int)
Didn't see this answer anywhere, so to solve the issue with having only 1 item selected after the post back you need to use:
#Html.ListBoxFor(..
instead of #Html.DropDownListFor
I have a Razor page with a drop down list inside a form:
#using (Html.BeginForm("ProductsByOwners", "Report", FormMethod.Post, new { #id = "ProductsByOwners" }))
{
#Html.Label("Choose product owner: ")
#Html.DropDownList("OwnerList", (SelectList)ViewBag.OwnerList, new { #onchange = "this.form.submit();" })
}
The selected value of my SelectList is not being carried over to the DropDownList. I've debugged and stepped through the code and found that (SelectList)ViewBag.OwnerList evaluates properly and has the expected value selected, but the resulting HTML does not have any of the option tags selected.
Can anyone see what I'm doing wrong here?
UPDATED
Here is how the SelectList is created in my action:
ViewBag.OwnerList = new SelectList(ListUtils.ProductOwners(), "Key", "Value", values["OwnerList"]);
The result has the value indicated by values["OwnerList"] selected.
Thanks!
You are not using the DropDownList helper properly. In order to create a dropdownlist you need 2 things:
a scalar property to bind to the selected value when the form is submitted
a collection to bind the options to
In your example you have only one of those 2 things (the second). Your first argument is called OwnerList and you have ViewBag.OwnerList passed as second argument.
So:
#Html.DropDownList(
"SelectedOwnerId",
(SelectList)ViewBag.OwnerList,
new { #onchange = "this.form.submit();" }
)
Obviously I would recommend you using strongly typed views ans view models. And obviously get rid of the weakly typed ViewBag/ViewData/ViewCrap.
So start by designing a view model to meet the requirements of your view (which from what you have shown so far is to display a dropdownlist):
public class OwnerViewModel
{
[DisplayName("Choose product owner: ")]
public string SelectedOwnerId { get; set; }
public IEnumerable<SelectListItem> OwnerList { get; set; }
}
then a controller:
public class ReportController: Controller
{
public ActionResult ProductsByOwners()
{
var model = new OwnerViewModel
{
// preselect the second owner
SelectedOwnerId = "2",
// obviously those come from your database or something
OwnerList = new[]
{
new SelectListItem { Value = "1", Text = "owner 1" },
new SelectListItem { Value = "2", Text = "owner 2" },
new SelectListItem { Value = "3", Text = "owner 3" },
}
};
return View(model);
}
[HttpPost]
public ActionResult ProductsByOwners(OwnerViewModel model)
{
...
}
}
and you have a corresponding strongly typed view:
#model OwnerViewModel
#using (Html.BeginForm("ProductsByOwners", "Report", FormMethod.Post, new { id = "ProductsByOwners" }))
{
#Html.LabelFor(x => x.SelectedOwnerId)
#Html.DropDownListFor(
x => x.SelectedOwnerId,
Model.OwnerList,
new { onchange = "this.form.submit();" }
)
}
The most common reason the selected item is not selected in the DDL is you've named the selectlist the same as the model.
Strongly typed views are preferred, but it's fine to pass the SelectList in a Viewbag. See my tutorial Working with the DropDownList Box and jQuery and my blog Cascading DropDownList in ASP.Net MVC
I have created a partial view that displays a dropdownlist
html.DropDownListFor(m => m.SelectOption, Model.SelectOption)
I get an error of Object not reference to an instance....
If I put the code above into my view (aspx) it works fine no problem. But in the partial view I get the error.
The textbox controls in my partial view works fine using the same model. I just can't around the DropDownList.
You haven't actually shown how you are calling the partial view and whether your controller action has actually passed a model to this view.
Make sure that your controller has properly initialized the model. So if we suppose that you have the following model:
public class MyViewModel
{
public string SelectedOption { get; set; }
public IEnumerable<SelectListItem> SelectOptions { get; set; }
}
and the following controller action:
public ActionResult Foo()
{
var model = new MyViewModel();
model.SelectOptions = new[]
{
new SelectListItem { Value = "1", Text = "item 1" },
new SelectListItem { Value = "2", Text = "item 2" },
new SelectListItem { Value = "3", Text = "item 3" },
};
return View(model);
}
ten you could have a corresponding view which will call a partial:
#model MyViewModel
#Html.Partial("_MyPartial", Model)
and the _MyPartial.cshtml:
#model MyViewModel
#Html.DropDownListFor(x => x.SelectedOption, Model.SelectOptionOptions)
Notice how you need 2 properties on your view model in order to create a dropdown list => a scalar property (SelectedOption) that will be used to bind the selected value and a collection property that will contain the list of values you would like to display in the dropdown (SelectOptionOptions).
In your code you are using the same property for both which is wrong:
#Html.DropDownListFor(m => m.SelectOption, Model.SelectOption)
I'm having problems retrieving the values of a selectlist in my form collection. I've tried making a viewmodel with an attribute with the same name as the select list.
I'm honestly just realizing I REALLY don't understand how model binding works with selectlists. I've just been assuming that the following conventions apply:
Name the select list the same thing as the attribute on the model you want it to bind to.
Apart from that, I really don't get it. I've looked at several books on it and they're useless frankly.
How does a select list work with a) form collection and b) a particular model?
Here's an example:
Model:
public class MyViewModel
{
public string SelectedItemValue { get; set; }
public IEnumerable<SelectListItem> Items { get; set; }
}
Controller:
public class HomeController: Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
// TODO: Fetch those from a repository
Items = new SelectList(
new[]
{
new SelectListItem { Value = "1", Text = "Item 1" },
new SelectListItem { Value = "2", Text = "Item 2" },
new SelectListItem { Value = "3", Text = "Item 3" },
},
"Value",
"Text"
)
};
}
[HttpPost]
public ActionResult Index(string selectedItemValue)
{
// Here you get the selected value from the dropdown
return ...
}
}
View:
<% using (Html.BeginForm()) { %>
<%= Html.DropDownListFor(x => x.SelectedItemValue, Model.Items)
<input type="submit" value="OK" />
<% } %>