I'm having problems with the HtmlHelper, RadioButtonFor and an enum in my model. I have a strongly typed view, and I want the checkboxes to toggle my enum property.
Enum.cs
public enum Values{
Value1,
Value2
}
Model.cs
public class Model{
public Values MyProp{ get; set; }
;
View.cshtml
#Html.RadioButtonFor(model => model.MyPropi, Values.Values1)
Controller.cs
public ActionResult WizardFirstStep()
{
var model = new Model();
return View(model);
}
If I set the MyProperty value in the controller, the RadioButton is checked as expected. But after a post to the next wizard step, which gets the model as parameter, the property isn't set.
If it will help you to understand what I mean: If it would be C# and WPF I would use a IValueConverter.
btw: I use a HtmlHelper.ActionLink to get the model to the controller.
Thanks in advance
Try this, it should work as I have done the same thing before:
#Html.RadioButtonFor(model => model.MyProp, (int)Values.Values1, model.MyProp == Values.Values1)
Notice the cast to int, it ensures the correct value is used for html.
EDIT: Sorry, I think you also need the third parameter to ensure the correct radio button is set when loading the view.
I also assumed MyPropi was a typo and changed it to MyProp, please ensure this matches up correctly at your end
Sorry for any inconvenience. After posting here, I found the solution very quickly. My ActionLink was not submitting the #Html.BeginForm form. So i changed my radiobutton to:
#Html.RadioButtonFor(model => model.MyPropi, Values.Values1, new{ onClick = "this.form.submit();" })
which submits the correct value to my controller. For the moment this is okay. Maybe the ActionLink can post back the form data.
For Aspx pages:
<%:Html.RadioButtonFor(m => m.YourProp, Selected value of your enum like : demo1.enum1.value2)
Related
I have the following declaration in Razor:
#Html.DropDownList("SelectedRole", ViewBag.RolesEdit as List<SelectListItem>, ViewBag.CurrentUserRole as string, new { #class = "form-control" }), and it results in a drop-down that looks as follows on page load:
And when I click on the dropdown arrow, I see:
So basically, the User Role is duplicated. How can I change this so that instead of making a new duplicate element, it defaults to the element it is supposed to be? Basically, since ViewBag.RolesEdit is a list, and ViewBag.CurrentUserRole is guaranteed to have an element that is equal to exactly one item in the afformentioned list, how can I loop through the list to compare each other and set the default?
Thank You.
When using Html.DropDownList helper method, To set one option to be pre selected, you just need to set the value of that option to the the ViewBag dictionary with the same key used to generate the SELECT element.
#Html.DropDownList("SelectedRole", ViewBag.RolesEdit as List<SelectListItem>)
Assuming your action method is setting ViewBag.SelectedRole to the value of the option you want to select.
ViewBag.RolesEdit= new List<SelectListItem>{
new SelectListItem { Value="Administrator", Text="Administrator"},
new SelectListItem { Value="Employees", Text="Employees"},
new SelectListItem { Value="RegularUser", Text="Regular User"},
}
ViewBag.SelectedRole ="RegularUser";
return View();
If you prefer to use Html.DropDownListFor helper method with a strongly typed view and view model, you can follow this post
What is the best ways to bind #Html.DropDownListFor in ASP.NET MVC5?
I am going through this tutorial and am confused as to what he is refrencing with the first part of this statement, at first i thought it was the values in the promo code table but there is no model to build that table from. The tutorial link is as follows:http://www.asp.net/mvc/overview/older-versions/mvc-music-store/mvc-music-store-part-9
string.Equals(values["PromoCode"], PromoCode,
StringComparison.OrdinalIgnoreCase) == false
PromoCode is a constant
values["PromoCode"] is one of the posted values from the form : see in the view
You can access the FormCollection (values is a FormCollection, which stores all inputs from the form, and inherits from NameValueCollection) by its keys : the keys are the names of the inputs.
<div class="editor-field">
#Html.TextBox("PromoCode") // it's not a TextBoxFor
</div>
this will generate something like
<input type="text" name="PromoCode" id="PromoCode" />
It's not linked to anything in the model, indeed.
See the method signature:
public ActionResult AddressAndPayment(FormCollection values)
So it is a collection of all posted values.
See the signature of the method:
public ActionResult AddressAndPayment(FormCollection values) // <-- here
{
// ...
if (string.Equals(values["PromoCode"], PromoCode,
StringComparison.OrdinalIgnoreCase) == false)
{
// ...
}
// ...
}
the values is of type FormCollection, which means the data collection in the HTML <form> posted from browser, the MVC model-binding will gather form data into FormCollection instance (the values here), so you may get form data by code like values["PromoCode"], which is the same as Request.Form["PromoCode"] in classic asp/asp.net.
I am new to MVC and trying a test application to get my feet wet. Part of this application is to generate a form with a drop down box. I use the
#Html.DropDownListFor() to generate this, and on the create form the drop down works fine. But when I go to the edit form the model value is not passing to the drop down.
SelectList Item
public static string[] OnOffList()
{
var ret = new string[] { "On", "Off" };
return ret;
}
Form code
#Html.DropDownListFor(model => model.ServiceCondition, new SelectList(OnOffDropDownHelper.OnOffList()))
For this instance assume that model.ServiceCondition = "Off".
For some reason whenever I call this form the dropdown value is always "On", it seems to be completely ignoring the model value.
I have also tried this
#Html.DropDownListFor(model => model.ServiceCondition, new SelectList(OnOffDropDownHelper.OnOffList(), "Off"))
to mandate the "Off" value, but it is still coming up as "On" as the selected value in the drop down.
I would like to reiterate, I do know that the model value is "Off", and I created an identical "Create" form using the same #Html.DropDownListFor() and it was able to pass the value to the model just fine.
Like I said, I am new to MVC so any help would be greatly appreciated.
Thanks.
I think you have to set the IsSelected property. This always works for me:
First, just put a property in your model to tidy up the View code:
public List<SelectListItem> OnOffDDL
{
get
{
return OnOffDropDownHelper.OnOffList()
.Select(s => new SelectListItem
{
Text = s,
Value = s,
Selected = ServiceCondition == s
})
.ToList();
}
}
Then do:
#Html.DropDownListFor(model => model.ServiceCondition, model.OnOffDDL)
This may be a little overkill, but is helpful if your model could have different options based on the model itself (even though for now it is just On and Off). Like in the future if certain items could have a "Standby" mode, etc, where you would be getting the actual options from a database for that particular item.
Use a SelectList for the source, so your Model could have:
public List<SelectListItem> OnOffList{ get; set; }
Then populating the Model in your controller like:
model.OnOffList.Add(new SelectListItem()
{
Text = "On",
Value = "On"
});
...etc.
Then you can set the selected item like:
#Html.DropDownListFor(m => m.ServiceCondition, new SelectList(Model.OnOffList(), "Value", "Text", Model.ServiceCondition))
Turns out to be a rookie mistake on my part.
Who ever designed the databese had the field ServiceCondition as nchar(8) leaving white space at the end of the "on ", "Off " values.
A .Trim() in the field in question fixed the issue.
Thanks a ton for the help.
I have Gender attribute as tiny int in Db for employee. When user create new employee i want him to choose male/female (which is working properly) by clicking on radio button. Everything is working fine (create and edit) but i want to display in form (for index, details and delete) not 1 or 2, but male/female. there should be some if statement in view but i'm not sure where to put it or how to write correct one ...
any idea?
Thanks!
this is part of code from model:
This one is from details.cshtml:
If you want to avoid having extra properties on your model or adding stuff to your viewbag you can write it inline using razor syntax like below..
<div class="display-field">
#if (model.GENDER == 0){ #Html.Raw("Male") }
#else if (model.GENDER == 1){ #Html.Raw("Female") }
</div>
That's off the top of my head so you might need to check the exact syntax but i think that's close. It will also just dump "Male" or "Female" inside the div, you might want to put it in a label or p tag at least.
This however isn't the approach I would use in a production app, throughout the code i would use a gender enum to give meaning to your bit value and extend enum to include a description that you can parse for presentation purposes.
I think from what u have said u can write it inline using the razor syntax like below in ur details.cshtml
<div class="display-field">
#if(model.GENDER ==0)
{
<label>Male</label>
}
else if(model.Gender==1)
{
<label>Female</label>
}
</div>
I think this must be enough for displaying the Gender in details page.plz comment if u need any help
Use a condition ? true : false selector
int gender = 1; // assumed male
String genderDesc = (gender == 1) ? "Male" : "Female";
You Could Make this a Drop Down field? In your controller do:
ViewBag.Gender = new[]
{
new SelectListItem { Text = "Male", Value = "1" },
new SelectListItem { Text = "Female", Value = "2" }
}.WithEmpty();
The WithEmpty() will give you a blank option or without it will select the top one.
#Html.DropDownListFor(m=> m.Gender, (Ienumarable<SelectListItem>)ViewBag.Gender);
This way the user will see Male and Female but the value will be bound to your model using the value which is 1 or 2.
I'd advise that you create a ViewModel class to represent the Employee entity in a View-friendly format decoupled from your database model and present it in a strongly typed view so you can return it from the controller.
Hint: Have the Gender property represented as a string in the ViewModel and do the conversion from byte to the string representation in your controller
You may put the code in your controller as e.g:
public ActionResult EmployeeDetails(int id)
{
//retrieve the entity from the DB
//set other employee properties here.
//I'm assuming you have set males to 2 and females to 1
...
employeeViewObject.Gender = employeeObjectFromDB.Gender.Value==2?"Male":"Female";
return View(employeeObjectFromDB);
}
Your strongly typed view will not have trouble displaying the gender while saving you the dirt of mixing code and mark-up as:
<p>model.Gender</p>
or
Html.DisplayFor(model=>model.Gender)
I have 2 properties in my ViewModel
class ViewModel1
{
Dictonary<int, string> PossibleValues {get;set;}//key/value
int SelectedKey {get;set}
}
I want to edit this using a Html.DropDownListFor
I want to get MVC to auto serialize the data into/from the ViewModel so I can the following
public ActionResult Edit(ViewModel1 model) ...
What's the best way to accomplish this?
As womp said, a browser will only submit the selected value of a drop down list. This is easily bound by the default model binder, see below.
If you are not editing the PossibleValues list on the client then there is no need to submit them back. If you need to repopulate the list then do it server side in your post action by using the same method you originally populated the Dictionary with.
For example in you page:
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<ViewModel1>" %>
<!-- some html here -->
<%= Html.DropDownListFor(x => x.SelectedKey, new SelectList(Model.PossibleValues, "key", "value"))%>
In your controller
[AcceptVerbs(HttpVerbs.Get)]
public ViewResult Edit() {
var model = new ViewModel1 {
PossibleValues = GetDictionary() //populate your Dictionary here
};
return View(model);
}
[AcceptVerbs(HttpVerbs.Post)]
public ViewResult Edit(ViewModel1 model) { //default model binding
model.PossibleValues = GetDictionary(); //repopulate your Dictionary here
return View(model);
}
Where GetDictionary() is a method that returns your populated Dictionary object.
See this similar question for more details
I don't think you'll be able to construct a dictionary from a dropdownlist on a form. A dropdownlist will only post one value back, which you could set as your SelectedKey property, but you won't be able to reconstruct the PossibleValues dictionary from it.
In order to reconstruct a dictionary, you're going to need to have a form field for every entry in it. You could do something like this, generated with a foreach loop over your dictionary:
<input type="hidden" name="PossibleValues[0].Key" value="key0">
<input type="hidden" name="PossibleValues[0].Value" value="value0">
<input type="hidden" name="PossibleValues[1].Key" value="key1">
<input type="hidden" name="PossibleValues[1].Value" value="value1">
.
.
.
Ultimately I would question the need to repopulate the dictionary from the form. If they can only choose one value, why wouldn't the PossibleValues just be a lookup from somewhere outside your ViewModel (like in your repository?) Why store it with the ViewModel?
The solution is custom ModelBinding in ASP.NET MVC framework here are some examples..
stevesmithblog.com/blog/binding-in-asp-net-mvc
www.singingeels.com/Articles/Model_Binders_in_ASPNET_MVC.aspx
odetocode.com/Blogs/scott/archive/2009/04/27/12788.aspx
odetocode.com/Blogs/scott/archive/2009/05/05/12801.aspx
hope you find them useful...
Thanks