I am using mvc3 and I have a drop down list in my view.
#Html.DropDownListFor(m => m.State,
new SelectList(Model.StateList, "Value", "Text"))
Is there a way of setting the selected value in the View?
Extending on what Romias said, in your controller, set Model.State to whatever value you want. If you wanted 'WI', then Model.State should equal that.
Controller:
public ActionResult Index()
{
var m = new TestViewModel();
m.State = "WI";
return View(m);
}
View:
#Html.DropDownListFor(m => m.State, new SelectList(Model.StateList, "Value", "Text", Model.State))
Just do:
#Html.DropDownListFor(m => m.State, new SelectList(Model.StateList, "Value", "Text", Model.State))
Related
I am creating a ListBox in MVC:
#Html.ListBoxFor(model => model.SelectedItemIds, new SelectList(Model.Items, "Value", "Text"))
which works fine, I can see the ListBox appear in the view.
I want to add some kind of callback when a user clicks and selects an item in the list. How can I do this using MVC3?
You would probably be best served by adding an id parameter to your ListBox, and then doing whatever callback that you want by using jQuery. Your line of code would then be like this:
#Html.ListBoxFor(model => model.SelectedItemIds, new SelectList(Model.Items, "Value", "Text"), new {id = "MyListBox")
Afterwards you could easily hook up an event in jQuery as follows:
$('#MyListBox').change(function() { ...some function... } );
You can add javascript onChange handler with this overload:
#Html.ListBoxFor(model => model.SelectedItemIds, new SelectList(Model.Items, "Value", "Text"), new{onchange="onListBoxChanged(); return false;"})
where onListBoxChanged() is javascript function.
You can do something like this
#using(html.begainform( ........your action name........))
{
#Html.ListBoxFor(model => model.SelectedItemIds, new SelectList(Model.Items, "Value", "Text"))
}
& in jquery you can write something like this
$("<Id or class of your ListBox>").change(function() {
this.form.submit();
});
I'm using ASP.NET MVC 3, and just ran into a 'gotcha' using the DropDownListFor HTML Helper.
I do this in my Controller:
ViewBag.ShippingTypes = this.SelectListDataRepository.GetShippingTypes();
And the GetShippingTypes method:
public SelectList GetShippingTypes()
{
List<ShippingTypeDto> shippingTypes = this._orderService.GetShippingTypes();
return new SelectList(shippingTypes, "Id", "Name");
}
The reason I put it in the ViewBag and not in the model (I have strongly typed models for each view), is that I have a collection of items that renders using an EditorTemplate, which also needs to access the ShippingTypes select list.
Otherwise I need to loop through the entire collection, and assign a ShippingTypes property then.
So far so good.
In my view, I do this:
#Html.DropDownListFor(m => m.RequiredShippingTypeId, ViewBag.ShippingTypes as SelectList)
(RequiredShippingTypeId is of type Int32)
What happens is, that the value of RequiredShippingTypeId is not selected in the drop down.
I came across this: http://web.archive.org/web/20090628135923/http://blog.benhartonline.com/post/2008/11/24/ASPNET-MVC-SelectList-selectedValue-Gotcha.aspx
He suggests that MVC will lookup the selected value from ViewData, when the select list is from ViewData. I'm not sure this is the case anymore, since the blog post is old and he's talking about MVC 1 beta.
A workaround that solves this issue is this:
#Html.DropDownListFor(m => m.RequiredShippingTypeId, new SelectList(ViewBag.ShippingTypes as IEnumerable<SelectListItem>, "Value", "Text", Model.RequiredShippingTypeId.ToString()))
I tried not to ToString on RequiredShippingTypeId at the end, which gives me the same behavior as before: No item selected.
I'm thinking this is a datatype issue. Ultimately, the HTML helper is comparing strings (in the Select List) with the Int32 (from the RequiredShippingTypeId).
But why does it not work when putting the SelectList in the ViewBag -- when it works perfectly when adding it to a model, and doing this inside the view:
#Html.DropDownListFor(m => m.Product.RequiredShippingTypeId, Model.ShippingTypes)
The reason why this doesn't work is because of a limitation of the DropDownListFor helper: it is able to infer the selected value using the lambda expression passed as first argument only if this lambda expression is a simple property access expression. For example this doesn't work with array indexer access expressions which is your case because of the editor template.
You basically have (excluding the editor template):
#Html.DropDownListFor(
m => m.ShippingTypes[i].RequiredShippingTypeId,
ViewBag.ShippingTypes as IEnumerable<SelectListItem>
)
The following is not supported: m => m.ShippingTypes[i].RequiredShippingTypeId. It works only with simple property access expressions but not with indexed collection access.
The workaround you have found is the correct way to solve this problem, by explicitly passing the selected value when building the SelectList.
This might be silly, but does adding it to a variable in your view do anything?
var shippingTypes = ViewBag.ShippingTypes;
#Html.DropDownListFor(m => m.Product.RequiredShippingTypeId, shippingTypes)
you can create dynamic viewdata instead of viewbag for each dropdownlist field for complex type.
hope this will give you hint how to do that
#if (Model.Exchange != null)
{
for (int i = 0; i < Model.Exchange.Count; i++)
{
<tr>
#Html.HiddenFor(model => model.Exchange[i].companyExchangeDtlsId)
<td>
#Html.DropDownListFor(model => model.Exchange[i].categoryDetailsId, ViewData["Exchange" + i] as SelectList, " Select category", new { #id = "ddlexchange", #class = "form-control custom-form-control required" })
#Html.ValidationMessageFor(model => model.Exchange[i].categoryDetailsId, "", new { #class = "text-danger" })
</td>
<td>
#Html.TextAreaFor(model => model.Exchange[i].Address, new { #class = "form-control custom-form-control", #style = "margin:5px;display:inline" })
#Html.ValidationMessageFor(model => model.Exchange[i].Address, "", new { #class = "text-danger" })
</td>
</tr>
}
}
ViewModel CompanyDetail = companyDetailService.GetCompanyDetails(id);
if (CompanyDetail.Exchange != null)
for (int i = 0; i < CompanyDetail.Exchange.Count; i++)
{
ViewData["Exchange" + i]= new SelectList(companyDetailService.GetComapnyExchange(), "categoryDetailsId", "LOV", CompanyDetail.Exchange[i].categoryDetailsId);
}
I was just hit by this limitation and figured out a simple workaround. Just defined extension method that internally generates SelectList with correct selected item.
public static class HtmlHelperExtensions
{
public static MvcHtmlString DropDownListForEx<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
IEnumerable<SelectListItem> selectList,
object htmlAttributes = null)
{
var selectedValue = expression.Compile().Invoke(htmlHelper.ViewData.Model);
var selectListCopy = new SelectList(selectList.ToList(), nameof(SelectListItem.Value), nameof(SelectListItem.Text), selectedValue);
return htmlHelper.DropDownListFor(expression, selectListCopy, htmlAttributes);
}
}
The best thing is that this extension can be used the same way as original DropDownListFor:
#for(var i = 0; i < Model.Items.Count(); i++)
{
#Html.DropDownListForEx(x => x.Items[i].CountryId, Model.AllCountries)
}
There is an overloaded method for #html.DropdownList for to handle this.
There is an alternative to set the selected value on the HTML Dropdown List.
#Html.DropDownListFor(m => m.Section[b].State,
new SelectList(Model.StatesDropdown, "value", "text", Model.Section[b].State))
I was able to get the selected value from the model.
"value", "text", Model.Section[b].State this section the above syntax adds the selected attribute to the value loaded from the Controller
I am quite new to the HTML helper extensions in MVC, let alone in Razor, and I'm looking for a simple, neat way to display a dropdown list for the 12 months of the year, with the value as the number and the text the "MMM" representation of the date.
So the HTML at the end should be like:
<select>
<option value="1">Jan</option>
<option value="2">Feb</option>
<option value="3">Mar</option>
<!-- etc -->
</select>
Is it possible to do this entirely in the view? I need an answer that users the #Html.DropDownListFor() so I can take advantage of automatic model binding. I get close with the line of code below, but it doesn't have the distinct values.
#Html.DropDownListFor(model => Model.DobMonth, new SelectList(Enumerable.Range(1,12).Select(r => new DateTime(2000, r, 1).ToString("MMM"))), "- -")
For non-technical reasons, I can't use a jQuery datepicker.
You are almost there, the problem is that if you don't provide the dataValue and dataText parameters when creating the SelectList it will just call ToString on the items and use them as the option's text.
What you need is to return Text, Value pairs from your select:
#Html.DropDownListFor(model => Model.DobMonth, new SelectList(
Enumerable.Range(1, 12)
.Select(r => new
{
Text = new DateTime(2000, r, 1).ToString("MMM"),
Value = r.ToString()
}),
"Value", "Text", Model.DobMonth))
If you want to have an "empty" item you need to add it manually:
#Html.DropDownListFor(model => Model.DobMonth, new SelectList(
new [] { new { Text = "- -", Value = (string)null } }.Concat(
Enumerable.Range(1, 12)
.Select(r => new
{
Text = new DateTime(2000, r, 1).ToString("MMM"),
Value = r.ToString()
})),
"Value", "Text", Model.DobMonth))
I have 2 dropdownlists on the Index page, and I wish to pass the id's of the selected items to the Create Page, so that I can populate the 2 dropdownlists on the Create page the same as the Index page.
Can you please suggest how I can do this?
At the moment I have this in the Index View :-
#Html.ActionLink("Create New", "Create", new { LeagueId = "ddlLeagues" }, new { ClubId = "ddlClubs" })
And then in the Controller :-
public ActionResult Create(int LeagueId, int ClubId)
{
var _LeagueID = LeagueId;
var _ClubID = ClubId;
Any help is very much appreciated!
Thanks
You can do it as described in this post:
ActionLink routeValue from a TextBox
you basically need to wrap your dropdowns with a form that routes to the create function, and the submit will take care of passing those values to your controller because they will be in the form data:
#using(Html.BeginForm("Create", "Footballer", FormMethod.Get))
{
#Html.DropDownList("LeagueId", Model.Leagues)
#Html.DropDownList("ClubId", Model.Clubs)
<input type="submit" value="Create"/>
}
If you are using a strongly typed model that has Properties for LeagueId and ClubId then use:
#Html.DropDownListFor(m => m.LeagueId, Model.Leagues)
#Html.DropDownListFor(m => m.ClubId, Model.Clubs)
Model.Clubs and Model.League are the IEnumerables that you will use to populate your dropDowns ofcourse
in your controller make sure you have the following:
[HttpGet]
public ActionMethod Create(int LeagueId, int ClubId)
{
//return your Create View
}
[HttpPost]
public ActionMethod Create(FormCollection data)
{
//Perform the create here
}
You can add a route into the application RegisterRoutes :
routes.MapRoute(
"CreateFootBallerWith2ComboOptions",
"{controller}/{action}/{LeagueId}/{ClubId}",
new { controller = "Footballer", action = "Create", LeagueId = -1, ClubId = -1 } // Default Values
);
You can then use what Bassam suggest with the ActionLink which is a Html Helper.
#Html.ActionLink("Create New", "Create",
new { LeagueId = 1, ClubId = 213 });
or use directly from the browser using :
localhost:7246/Footballer/Create/1/5
I have an MVC3 drop down list that come from this code on the controller.
private SelectList progCodesList = new SelectList(new[] { "Description", "Requirements", "Development", "Testing", "Documentation" });
How can I fill the fields from a repository, to build the drop down dynamically?
Thanks.
Assuming you have the progCodes in a database table, with progCode having the text, and progCodeId with a unique id, then you can read the table into a list of SelectListItem as follows:
private DbContext _db = new DbContext();
var progCodesList = _db.progCodes.Select(x => new SelectListIem()
{
Text = x.progCode,
value = x.progCodeId
}).ToList();
You can then pass this List<SelectListItem> to your view either in a strongly-typed model, or using the ViewBag.
You need to pass the progCodesList to the ViewBag in your controller method using something like:
ViewBag.ProgCodeId = progCodesList;
Then in your view, you need to fill the drop down like this:
<div class="editor-label">
#Html.LabelFor(model => model.ProgCodeId, "ProgCode")
</div>
<div class="editor-field">
#Html.DropDownList("ProgCodeId", String.Empty)
#Html.ValidationMessageFor(model => model.ProgCodeId)
</div>