MVC dropdownlist in View setting selected Value - asp.net-mvc

I'm trying to set the selected Value for a drop down list.
In Controller I have
ViewData["productType"] = new SelectList(myDropDownList);
And in the View:
<%= Html.DropDownList("productType", ViewData["productType"] as SelectList, "defaultValue")%>
So far So good, but the problem is that now I have "defaultValue" twice in my drop down list. so I have all my values in dropdownlist including the "defaultValue". but this code will add the "defaultValue" as the first element. and I see two samples of it.
I like to set the selected valiue to "defaultValue" without adding it twice.
I tried
ViewData["productType"] = new SelectList(myDropDownList, "defaultValue" );
but it didn't work.
Can anyone please tell me what to do?

You should not be using the same name as first argument for the dropdown as the second one. In your example you have used productType for storing both the selected value and the list of available values. In order to render a DropDown in ASP.NET MVC you need 2 properties:
<%= Html.DropDownList(
"selectedProductType",
ViewData["productType"] as SelectList,
"defaultValue"
) %>
and inside your controller action you could set those 2 properties:
ViewData["selectedProductType"] = "abc";
ViewData["productType"] = new SelectList(myDropDownList);
this assumes that you already have an element with value="abc" inside your dropdown list of product types. The value will then be automatically preselected.
I would recommend you an alternative approach though for rendering dropdown lists. It consists of getting rid of view data and introducing view models and using the strongly typed version of the helper:
public class ProductViewModel
{
public string SelectedProductType { get; set; }
public IEnumerable<SelectListItem> ProductTypes { get; set; }
}
then you will have a controller action that will populate this view model and pass it to the view:
public ActionResult SomeAction()
{
var model = new ProductViewModel();
// preselected an element with value = "type2"
model.SelectedProductType = "type2";
// bind the available product types
model.ProductTypes = new SelectList(
// Obviously those could come from a database or something
new[] {
new { Value = "type1", Text = "product type 1" },
new { Value = "type2", Text = "product type 2" },
new { Value = "type3", Text = "product type 3" },
new { Value = "type4", Text = "product type 4" },
},
"Value",
"Text"
);
// pass the view model to the view
return View(model);
}
and finally inside your strongly typed view:
<%= Html.DropDownListFor(
x => x.SelectedProductType,
Model.ProductTypes,
"defaultValue"
) %>

Related

Using Html.DropDownListFor as part of a paging solution in a razor view

I've spent hours on this, and I'm obviously missing something. Code extracts below are from a cut-down version of my actual app.
My viewmodel contains this:
public IEnumerable<SelectListItem> DisplayPageOptions { get; set; }
public string SelectedPageOption { get; set; }
private static SelectListItem item1 = new SelectListItem() { Text = "25", Value = "25" };
private static SelectListItem item2 = new SelectListItem() { Text = "50", Value = "50" };
private static SelectListItem item3 = new SelectListItem() { Text = "100", Value = "100" };
public SelectList selectList = new SelectList(new[] { item1, item2, item3 }, "Value", "Text", item1);
My razor view contains this:
#Html.DropDownListFor(m => m.SelectedPageOption, Model.DisplayPageOptions, "Pages to display", new { onchange = #"submit()" })
My controller contains this:
SymbolViewModel vm = SymbolViewModel.Instance;
if (vm.SelectedPageOption == null)
{
vm.SelectedPageOption = "25";
}
vm.DisplayPageOptions = vm.selectList;
SymbolDataService service = new();
vm.Load(service);
return View(vm);
My intention is that the user selects 25, 50, or 100 from the dropdown and a corresponding number of rows is displayed. My understanding is that the Html.DropDownListFor should bind to the SelectedPageOption property, which I would then use in the ViewModel to load the correct number of rows.
However, the change in dropdown value has no effect on the SelectedPageOption property, so the page is reloaded always with the original default '25' rows - taken from the value that is set in the controller. I have tried making SelectedPageOption an Int, having seen examples on the web. I hadn't wanted to do this originally because the SelectedListItem Values have to be strings. It makes no difference. I also tried not using a singleton pattern for the viewmodel - also no effect.
The binding is not completely ineffective. Whatever default value I set in the controller, this is the value that appears in the dropdown. But the binding does not work the other way. If anyone can cast some light on what's going on, I'd appreciate it.
EDIT: What I didn't originally point out, and what turned out to be relevant, is that my controller method containing the above code is asynchronous.
I finally worked out what was going on. Because my controller Index method is asynchronous, I need to await the model update before reloading my viewmodel. It seems obvious now!
SymbolViewModel vm = SymbolViewModel.Instance;
await TryUpdateModelAsync(vm);

How to set string value in model using a dropdown?

I'm working with an ASP.NET mvc projekt and I'm familiar with the usual razor helpers #Html.TextBoxFor... etc. but I'm in the situation where I need to set a string value in the model using a dropdown list, the list always has the same twelve items in it and I just need to populate this list with those items and make sure it sets the field value in the model to the selected one.
I'm curious how I should go about doing this? I've looked at dropdown tutorials and I might be able to get a dropdown working but I'm not sure how to set the field value and I'm not sure where to store these twelve strings. I thought about hardcoding them instead of putting them in a db or something since it's so few but I'm open to better suggestions.
Any help is appreciated
UPDATE
This is my Razor code, I created a simple viewmodel which contains the list of items to display in the dropdown and including the model class I wanna use for this create view.
#Html.DropDownListFor(x => x.question.QuestionId, new SelectList(Model.AreasList), new { #class = "dropdown" })
This is my viewmodel
public class CreateQuestionViewModel
{
public Question question { get; set; }
public IEnumerable<String> AreasList = new List<String> { "Option 1", "Option 2" };
}
It works but I can't figure out why visual studio keeps throwing me a null reference and points at my razor code for the dropdown?
sure, so you need to set the model field based on the selected List Item when the user selects it, assuming that you have a static dropdown list:
//this is your view View1.chtml
#model Class1
<select id="list1" name="list1">
<option value="0">option1</option>
<option value="1">option2</option>
</select>
<script>
$(document.ready)(function(){
//set the list from model
var modelvalue = '#Html.Raw(Json.Encode(Model.ValueFromList))';
$(#list1).val(modelvalue);
});
//handle the change event of Dropdown list
$("#country").change(function()
{
var _selected = $("#list1").val();
var options =
{
type: "POST",
url: '#Url.Action("Action1","controller1")',
data: _selected + ,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
//set the returned value as the selected dropdownlist value
$(#list1).val(msg);
}
}
};
.ajax(options);
</script>
//this is the class that you want to set the value in (the Model)
Class1
{
public string ValueFromList {get;set;}
}
//then you need an action method ( in your Controller) that will update the Model with the new Value:
public Controller1
{
[HttpPost]
public JsonResult Action1(string value)
{
Class1 cl1=new Class1();
cl1.ValueFromList=value;
return Json(new {Success="true", cl1});
}

Cascading dripdown list in MVC4 Razor

I have 3 tables country , state , city .
I want cascading drop down list as usual.
How can i do that without using the LINQ.
I don't know that how to start. I want to do that using RAZOR. It is okay if it is in JQUERY or JSON.
How to start that.
Thanks in advance.
Can i do that using stored procedure.
tables are:-
user:
name
cityid
country:
id stateid name
state
stateid cityid name
city
cityid name .
i have tried nothing because i don't know where to start.
A general approach to creating cascading selects
Create a view model containing the properties you want to display, including properties for the country and state ID's and a SelectList for the Country options
In your view render selects using #HtmlDropDownFor() for the Country, Sate and Property ID's (the Country select will be populated; the others will be empty)
Using jQuery, in the Country change event, use an AJAX call to an action method which returns a list of States based on the selected Country (either return html to replace the City select, or return JSON to create a new set of option elements.
Repeat the above when a State is selected (to populate the City select)
No one here will provide you complete code like you are asking in your question but usage of dropdown i m explaining below :
Basic and cleanest way to make a dropdown in MVC is like :
Model :
public List<SelectListItem> ItemTypes { get; set; }
public int ItemVal { get; set; }
In your [HttpGet] Controller just bind `Model.ItemTypes` with values
View:
#Html.DropDownListFor(m => m.ItemVal , new SelectList(Model.ItemTypes , "Value", "Text"), " -----Select List----- ")
here in above example the 3rd overload of DropDownListFor() i.e. " -----Select List----- " will be the initial selected item of your dropdown with value equal to ' '.
At Controller during POST ItemVal will have selected dropdown value.
The above shown code is best and simplest way to bind Dropdownlist in MVC.
See this exmple. You'll have an idea. I'm just showing sample which is not tested.
public ActionResult Index()
{
var countries = new List<string> { "USA", "India" };
ViewBag.Countries = new SelectList(countries);
return View();
}
public ActionResult GetStates(string country)
{
//perform filter here based on country
return Json(new[] {
new { Id = 1, Value = "State 1" },
new { Id = 2, Value = "State 2" },
new { Id = 3, Value = "State 3" },
}, JsonRequestBehavior.AllowGet);
}
View Page
<div>Select country:</div>
<div>#Html.DropDownList("country",
ViewBag.Countries as SelectList,
"Please select",
new { id = "country" })
</div>
<div>Select state:</div>
<div>
<select id="state"></select>
</div>
On Country selection, do ajax call and get related states.
<script type="text/javascript">
$(function () {
$('#country').on('change', function () {
$.getJSON('#Url.Action("GetStates")', function (result) {
var ddl = $('#state');
ddl.empty();
$(result).each(function () {
$(document.createElement('option'))
.attr('value', this.Id)
.text(this.Value)
.appendTo(ddl);
});
});
});
})
</script>

How to remove model state error for dropdown with selected option label in mvc?

I am working on a MVC project.I have a view having a dropdownlist with an option label "Select Task".Now the integer property bound with this dropdown is not a required field.
But then too after I try to save, I get the dropdown having a red border showing that it is required. When I analysed, I found that the option label has value null.
Using firebug when I entered 0 for the value of option label, the view was saved with no model state error. Am I doing something wrong ? How to avoid it ?
View
#Html.DropDownListFor(model => model.projecttaskid, new SelectList((IList<SelectListItem>)ViewData["MyTasks"], "Value", "Text"),"Select Task", new { #class = "span2" })
Model public int projecttaskid { get; set; } Controller It doesn't reach the controller action.
projecttaskid is not nullable. Unless you provide a default value for the drop down list, the model will not bind properly, which is why you are getting validation error even though the model field is not marked as [required].
Edit: by default value I mean an item in the list with a value of 0, since the default value for projecttaskid is 0.
For instant, you use an overload of DropDownListFor with the optionLabel argument (your "Select Task" argument.
If no item is selected, this will be taken as the "selected option", and return a null value for model.projecttaskid.
The easiest way would be to add an element with a 0 value when you create your list (ViewData["MyTasks"])
With, for example :
Value = 0;
Text = "Select Task;
And use an overload of DropDownListFor without the optionLabel.
[By the way, usage of ViewModels instead of ViewData would be a good thing, but that's another problem]
*EDIT *
We do use some extension methods to manage these cases :
public static IEnumerable<SelectListItem> ToSelectListItem<T, TValue, TText>(
this IEnumerable<T> enumerable,
Func<T, TText> text,
Func<T, TValue> value)
{
return enumerable.Select(item => new SelectListItem
{
Text = text(item).ToString(),
Value = value(item).ToString()
}).AsEnumerable();
}
public static IEnumerable<SelectListItem> WithDefaultZeroValue(this IEnumerable<SelectListItem> selectListItems, string chooseText/* = ChooseText*/)
{
IList<SelectListItem> items = selectListItems.ToList();
items.Insert(0, new SelectListItem { Value = "0", Text = chooseText });
return items.AsEnumerable();
}
usage
var myList = mySourceForDropDown.ToSelectListItem(m => m.TextField, m => m.ValueField)
.WithDefaultZeroValue("SelectTask")
use this:
#Html.DropDownListFor(model => model.Type, new SelectList(Enum.GetNames(typeof(Enums.TenderType))), new Dictionary<string, object>() { { "data-val", "false" } })

Unable to save Enum values into entity field from DropDownList - EF Code First MVC3

I have a DropDownList that contains the correct items and values when the view is rendered but the selected value is not being saved within the designated entity field Garage. Currently the value being saved and returned is 0 (None) in both create or edit post methods. I'm sure this is something simple but I can't figure it out... Thanks in advance!
The Model Class:
public enum GarageType { None = 0, One = 1, Two = 2, Three = 3, Four = 4 }
public int Garage { get; set; }
[NotMapped]
public GarageType GarageEnumValue
{
get { return (GarageType)Garage; }
set{ Garage = (int)value; }
}
The Control Create and Edit methods both look like this:
var statuses = from Property.GarageType s in Enum.GetValues(typeof(Property.GarageType))
select new { ID = (int)s, Name = s.ToString() };
ViewBag.GarageId = new SelectList(statuses, "ID", "Name", statuses.FirstOrDefault().ID);
Last the View:
#Html.DropDownList("GarageId", String.Empty)
Use the following overload of DropDownList method
#Html.DropDownList("GarageEnumValue", (SelectList)ViewBag.GarageId, String.Empty)
If you have a strongly type model use
#Html.DropDownListFor(m => m.GarageEnumValue, (SelectList)ViewBag.GarageId, String.Empty)
The first argument in both cases should be the property that you are going to bind the list.

Resources