I'm newbie with ASP.Net MVC 5 and I'm having a problem understanding the dropdownlist.
I want show a form that binds a DTO object (because that form doesn't map one to one a database table). My form must show the following fields:
Name (edit box)
Address (edit box)
Type (dropdownlist that show always 3 fixed values: "Type1", "Type2" and "Type3"
How can I write my DTO object class and the two Create actions (the one that show the form and the other that handle the post)?
I found some solutions that use the enum in the DTO objects, others that use the viewbag in the create action (GET)...I'm confused!!!
Trick is to use SelectListItem and use DropDownFor.
Create a property on your view model like
public class ViewModel {
string SelectedItem { get; set; }
List<SelectListItem> Items { get; set; }
}
In your controller:
public ActionResult Edit() {
var items = new List<SelectListItem>() {
new SelectListItem() {Text = "Option1Text", Value = "Value1Text"},
new SelectListItem() {Text = "Option1Text", Value = "Value1Text"},
new SelectListItem() {Text = "Option1Text", Value = "Value1Text"}};
var model = new ViewModel() { Items = items };
return View(model);
};
In your view
#model ViewModel
#Html.DropDownFor(x => x.SelectedItem, Model.Items)
You can then get the selected value in your action:
[HttpPost]
public ActionResult Edit(ViewModel model) {
var whatWasSelected = model.SelectedItem; // This will be "OptionXValue"
// Do more things
}
You should also re-populate the select list items on whatever action responds to the form submission if you're going to re-render the view. This is because the collection of options are not transmitted over the original request and therefore ASP.NET MVC doesn't know how to rebuild the collection by itself. By doing this you'll avoid any nasty exceptions when trying to set the selected item in the collection of SelectListItem. Overall the responding action would look more like:
[HttpPost]
public ActionResult Edit(ViewModel model) {
var items = new List<SelectListItem>() {
new SelectListItem() {Text = "Option1Text", Value = "Value1Text"},
new SelectListItem() {Text = "Option1Text", Value = "Value1Text"},
new SelectListItem() {Text = "Option1Text", Value = "Value1Text"}};
model.Items = items;
var whatWasSelected = model.SelectedItem; // This will be "OptionXValue"
// Do more things
}
Related
Here is the Syntax of My Dropdown.
#Html.DropDownListFor(model => model.DealerIdRef, Model.Ddllist, " Select Dealer ", new { #class = "form-control"})
i want its default selected value and make it read-only so that user can not update selection. For this i'm using Jquery.
$('#DealerIdRef').val('#Session["MyID"]').trigger('change');
$("#DealerIdRef").attr('disabled', 'true');
this is setting the value and also exists in Console
At Controller it is still null
Edit
if i'm making some mistake then please help.
thanks in advance
Your javascript is setting the disabled attribute of the dropdownlist. Disabled form controls do not submit a value so the value of DealerIdRef in your model is its default (i.e. null because its int?).
If you want the value of the dropdownlist to be submitted, do not disabled it.
But based on i want its default selected value and make it read-only so that user can not update selection, then there is no point generating a dropdownlist, and in anycase, you set selected option by setting the value of the property your binding to. That is you set the value of DealerIdRef in the GET method before you pass the model to the view.
Since all you want is to display a value and have it posted back, then include a hidden input for the value and display the text
#Html.HiddenFor(m => m.DealerIdRef)
<div>...the txt you want to display...</div>
There is no point degrading performance by generating a SelectList and extra html when its not needed.
As a side note, your POST method would have throw this exception because you have not repopulated the SelectList in the POST method before you return the view.
I wrote a simple mock your question.
It can work. The simple code is on DropDownController
Here is the Source Code,I Upload to github.
ViewModel
public class DropDownViewModel
{
[Display(Name = "Dealer")]
public int? DealerIdRef { get; set; }
public IEnumerable<SelectListItem> Ddllist { get; set; }
}
Index View
Mock Your Submit action
#model Sample.Models.DropDownViewModel
#using (Html.BeginForm("ShowDDL", "DropDown", FormMethod.Post))
{
#Html.DropDownListFor(model => model.DealerIdRef, Model.Ddllist, " Select Dealer ", new { #class = "form-control" })
<button>Submit</button>
}
ShowDDL View
Show your select data.
#model Sample.Models.DropDownViewModel
<b>Your Select Value: </b> #Model.DealerIdRef
DropDownController
public ActionResult Index()
{
DropDownViewModel model = new DropDownViewModel()
{
Ddllist = GetDDL(),
DealerIdRef = 1
};
return View(model);
}
[HttpPost]
public ActionResult ShowDDL(DropDownViewModel viewModel)
{
return View(viewModel);
}
private IEnumerable<SelectListItem> GetDDL()
{
return new List<SelectListItem>()
{
new SelectListItem()
{
Text = "One",
Value = "1"
},
new SelectListItem()
{
Text = "Two",
Value = "2"
}
};
}
Using the following code i generate a select list in my controller and feed it into my view model.
var SelectListItems = om_repo.List().Select(x => {
var item = new SelectListItem();
item.Value = x.id.ToString();
item.Text = x.code;
return item;
});
createvm.allOccupations = new SelectList(SelectListItems);
Here is my view code
#Html.DropDownListFor(model => model.selectedOccupation, Model.allOccupations, "Choose one")
The output im getting is
<option>System.Web.Mvc.SelectListItem</option>
Why isnt it picking up the select list items Text and Values that are being fed. In my debugger i can see the values are set in the locals under text and value.
Because the DropDownlist doesn't want a SelectList; it wants an IEnumerable of SelectListItems.
Try just:
createvm.allOccupations = SelectListItems;
Model Class also needs to be:
public IEnumerable<SelectListItem> allOccupations { get; set; }
Not
public SelectList allOccupations { get; set; }
Scott Allen expanded on the problem here: https://odetocode.com/Blogs/scott/archive/2010/01/18/drop-down-lists-and-asp-net-mvc.aspx
I've been working for a while on this, I know how to resolve it using JQuery, but I need to solve this just using server side code, I'm in a Razor View
The thing is:
I have an #Html.DropDownlist that is showing some States from USA, and once clicked one of the States from the DropDownList then I want to show some cities that belong to the State selected using other DropDownList, I'm not sure how to get the value from the selected field just using Razor syntax and then show the cities that belong to the State in other DropDownList when one State is selected, I'm using a SelectList and I have an StateID to bind the cities... I'm showing all the States inside a DropDownList that is working.
Here is my code:
These are just two classes that I'm using to fill the SelectList with some properties:
public States(int id, string name, List<string> list)
{
StateID = id;
Name = name;
Cities = list;
}
public int StateID { get; set; }
public string Name { get; set; }
public List<string> Cities { get; set; }
}
public static class Fill
{
public static List<States> GiveMeStates()
{
List<States> li = new List<States>() {
new States(1, "Alabama",new List<string> {"Adamsville", "Addison", "Anderson","Anniston", "Arab" }),
new States(2,"Alaska", new List<string> {"Anchorage","Juneau","Fairbanks","Sitka"}),
new States(3,"Arizona", new List<string> { "Avondale", "Benson", "Besbee"})
};
return li;
}
}
And now this is my Razor View:
#using RazorMVC.Models;
#{
List<States> aux = Fill.GiveMeStates();
SelectList states = new SelectList(aux, "StateID", "Name");
}
<form>
#Html.DropDownList("ddlStates", states);
</form>
If you absolutely do not want to use javascript/jQuery, you may submit the form (with the selected state id) and get the states based on the posted state id and show that.
Assuming you want to show the cities for the selected state in the same view.
#{
var stateId = Request.QueryString["ddlStates"] as string;
List<States> aux = Fill.GiveMeStates();
SelectList states = new SelectList(aux, "StateID", "Name");
List<SelectListItem> cities = new List<SelectListItem>();
if (!String.IsNullOrEmpty(stateId))
{
var state = aux.FirstOrDefault(f => f.StateID == Convert.ToInt32(stateId));
if (state != null)
{
cities = state.Cities
.Select(x => new SelectListItem {Value = x, Text = x}).ToList();
}
}
}
<label>Select a state and hit submit </label>
#using (Html.BeginForm("Index", "Home", FormMethod.Get))
{
#Html.DropDownList("ddlStates", states)
<label>Cities < /label>
#Html.DropDownList("City", cities)
<input type="submit" />
}
I personally prefer to not put a lot of C# code in the razor views. I usually create a view model and use that to pass the values needed in the view. So most of the above code you see in the view goes in my action method.
If you prefer to use jQuery/javascript (Why not ?), You may listen to the change event of the the first dropdown ,get the selected option value and send that to server via an ajax call. Let your server action method returns the states in json format and your ajax metod's call back can parse the json data and update the cities dropdown. Here is a sample to start with
I am trying to get my head around drop down lists with MVC, which appears to be failing me. I've been tinkering with the code shown below but can't get it right.
What I am trying to achieve is simple - hard coding some drop down options in the controller, have them appear in the Razor rendered html and when an option is selected, that selected value is bound back to the string property in the model.
With the code below I can't access li from within the View.
I've seen other guides but I haven't been able to make it work, is binding model the best option for me, given what I'm trying to achieve, or would ViewBag etc be better?
Could someone show me where I'm going wrong please?
Model
public class ViewModel {
public string MyOption { get; set; } }
View
#model ViewModel
#Html.DropDownListFor(m => m.MyOption, li, "--Select--")
Controller
public ActionResult Index()
{
List<SelectListItem> li = new List<SelectListItem>();
li.Add(new SelectListItem { Text = "Option One", Value = "option1" });
li.Add(new SelectListItem { Text = "Option Two", Value = "option2" });
return View(li);
}
You need to pass MyOption to view if you want to use it. A valid option would be to creaete a view model class containing all information you need to handle on your view
ViewModel
public class ViewModel
{
public IList<SelectListItem> ItemList {get; set;}
public string MyOption { get; set; }
}
View
#Html.DropDownListFor(m => m.MyOption, Model.ItemList, "--Select--")
Controller
public ActionResult Index()
{
var li = new List<SelectListItem>();
li.Add(new SelectListItem { Text = "Option One", Value = "option1" });
li.Add(new SelectListItem { Text = "Option Two", Value = "option2" });
var viewModel = new ViewModel
{
ItemList = li,
MyOption = [here your code to fill this]
}
return View(viewModel);
}
you need to make sure you are declaring your model in the view in order to access any attributes or modifiers to that model
#model Namespacehere.Models.modelclassname
then you should be able to use something like
#Html.DropDownListFor(m => m.MyOption, model, "--Select--")
I am very new to MVC and trying to do a project. I have Product model which is created from database. It has the properties like below(I am now writing all properties.)
Product
-------
ID(int)
CODE(string)
CATEGORY_ID(int)
Categories
-------
ID(int)
CODE(string)
I created the Create ActionResult for Product. And since the CATEGORY_ID is integer in the database, Visual Studio created a textbox for CATEGORY_ID. I want it to be dropdownlist which will list all the categories from the Categories table.But when the user click the Save button, it will write integer value of the selected category to Product table.
How can I do that dropdownlist? How can I pass all the categories to the Product's Create ActionResult?
You want to use a ViewModel to shape your DB model to a presentation purpose.
In model class Product add following,
[NotMapped]
public SelectList Categories { get; set; }
in view add
#Html.DropDownListFor(model => model.CategoryID, Model.Categories, "--Select--", new { #id="drpCommodity"})
fill Categories in using following
public static SelectList GetDropDownList<T>(List<T> objects, string value, string text)
{
List<SelectListItem> items = new List<SelectListItem>();
//var defaultItem = new SelectListItem();
//defaultItem.Value = Convert.ToString(-1);
//defaultItem.Text = "--Select--";
//defaultItem.Selected = true;
//items.Add(defaultItem);
List<SelectListItem> lst = objects
.Select(x =>
new SelectListItem
{
Value = x.GetType().GetProperty(value).GetValue(x).ToString(),
Text = x.GetType().GetProperty(text).GetValue(x).ToString()
}).ToList();
items.AddRange(lst);
return new SelectList(items, "Value", "Text");
}