I am stuck at "how to set value in the dropdown to the value that is set in the model.
I am adding what I have till now and what I have tried.
So, I have a PaymentFormMV Model and it has another Model in it which is PaymentCCMV
public class PaymentFormMV
{
public PaymentCCMV CreditDetails { get; set; }
public string ModelPropertyPrefixName
{
get
{
return this.ModelPropertyPrefix.Replace("_", ".");
}
}
}
public class PaymentCCMV
{
[Display(Name = "Expiration Date")]
public int ExpirationMonth { get; set; }
}
cshtml file takes data from PaymentFormMV
<div class="form-group">
#Html.LabelFor(model => model.CreditDetails.ExpirationMonth, htmlAttributes: new { #class = "control-label col-md-2 required" })
<div class="col-md-10">
#Html.DropDownList(Model.ModelPropertyPrefixName + "CreditDetails.ExpirationMonth", Helpers.PossibleMonths,
new { id = Model.ModelPropertyPrefix + "CreditDetails_ExpirationMonth", #class = "form-control", style = "width:70px;" })
</div>
</div>
Helpers.PossibleMonths: displays all the months
public static ICollection<SelectListItem> PossibleMonths
{
get
{
return new List<SelectListItem>()
{
new SelectListItem() { Text = "1 - Jan", Value = "1" },
new SelectListItem() { Text = "2 - Feb", Value = "2" },
new SelectListItem() { Text = "3 - Mar", Value = "3" },
new SelectListItem() { Text = "4 - Apr", Value = "4" },
new SelectListItem() { Text = "5 - May", Value = "5" },
new SelectListItem() { Text = "6 - Jun", Value = "6" },
new SelectListItem() { Text = "7 - Jul", Value = "7" },
new SelectListItem() { Text = "8 - Aug", Value = "8" },
new SelectListItem() { Text = "9 - Sep", Value = "9" },
new SelectListItem() { Text = "10 - Oct", Value = "10" },
new SelectListItem() { Text = "11 - Nov", Value = "11" },
new SelectListItem() { Text = "12 - Dec", Value = "12" },
};
}
}
Points:
I am getting integer value model.CreditDetails.ExpirationMonth = 2 (as per DB)
But I don't know how to set it to the drop down. So when the screen loads I want that value to be tied to the dropdown. Please guide me. SO, if the value is 2 I should get something like 2 - Feb in the Dropdown UI as mentioned in the Helper Method. I am a beginner so I might not be following the best practice so bear with me on this.
HTML GENERATED:
I second #Vivien's response, but I would recommend to use the overload that takes the selected value (See MSDN:), which you can then set. To then allow passing in the default, I would also recommend using a static method, and allowing the month to be passed in:
public static SelectList PossibleMonths(string defaultValue)
{
return new SelectList(List<SelectListItem>()
{
new SelectListItem() { Text = "1 - Jan", Value = "1" },
new SelectListItem() { Text = "2 - Feb", Value = "2" },
new SelectListItem() { Text = "3 - Mar", Value = "3" },
new SelectListItem() { Text = "4 - Apr", Value = "4" },
new SelectListItem() { Text = "5 - May", Value = "5" },
new SelectListItem() { Text = "6 - Jun", Value = "6" },
new SelectListItem() { Text = "7 - Jul", Value = "7" },
new SelectListItem() { Text = "8 - Aug", Value = "8" },
new SelectListItem() { Text = "9 - Sep", Value = "9" },
new SelectListItem() { Text = "10 - Oct", Value = "10" },
new SelectListItem() { Text = "11 - Nov", Value = "11" },
new SelectListItem() { Text = "12 - Dec", Value = "12" },
}, "Value", "Text", defaultValue);
}
EDIT: Your dropdown could would then look like
#Html.DropDownList(Model.ModelPropertyPrefixName + "CreditDetails.ExpirationMonth", Helpers.PossibleMonths(Model.CreditDetails.ExpirationMonth),
new { id = Model.ModelPropertyPrefix + "CreditDetails_ExpirationMonth", #class = "form-control", style = "width:70px;" })
That assumes the CreditDetails object is always not null, otherwise null checking is a must.
EDIT: I was incorrect, apparently Html.DropDownList doesn't support SelectList, so I reverted back to the original approach with a twist for setting the selected value (note same drop down code above for this to work).
public static IEnumerable<SelectListItem> PossibleMonths(string defaultValue)
{
if (defaultValue == null)
defaultValue = "";
return new List<SelectListItem>()
{
new SelectListItem() { Text = "1 - Jan", Value = "1", Selected = (defaultValue == "1") },
new SelectListItem() { Text = "2 - Feb", Value = "2", Selected = (defaultValue == "2") },
new SelectListItem() { Text = "3 - Mar", Value = "3", Selected = (defaultValue == "3") },
new SelectListItem() { Text = "4 - Apr", Value = "4", Selected = (defaultValue == "4") },
new SelectListItem() { Text = "5 - May", Value = "5", Selected = (defaultValue == "5") },
new SelectListItem() { Text = "6 - Jun", Value = "6", Selected = (defaultValue == "6") },
new SelectListItem() { Text = "7 - Jul", Value = "7", Selected = (defaultValue == "7") },
new SelectListItem() { Text = "8 - Aug", Value = "8", Selected = (defaultValue == "8") },
new SelectListItem() { Text = "9 - Sep", Value = "9", Selected = (defaultValue == "9") },
new SelectListItem() { Text = "10 - Oct", Value = "10", Selected = (defaultValue == "10") },
new SelectListItem() { Text = "11 - Nov", Value = "11", Selected = (defaultValue == "11") },
new SelectListItem() { Text = "12 - Dec", Value = "12", Selected = (defaultValue == "12") },
};
}
The DropDownList() (and the preferred DropDownListFor() methods work by binding to the value of your property. In your case, you want to bind to the ExpirationMonth property, the code in your view should be
#Html.DropDownList("CreditDetails.ExpirationMonth", Helpers.PossibleMonths, new { #class = "form-control", style = "width:70px;" }
or better
#Html.DropDownListFor(m => m.CreditDetails.ExpirationMonth, Helpers.PossibleMonths, new { #class = "form-control", style = "width:70px;" }
and if you have set the value of ExpirationMonth to say 3 in the GET method and pass the model to the view, then the 3rd option ("Mar") will be selected.
It is not clear what your ModelPropertyPrefix and ModelPropertyPrefixName properties return, however they are not required, and should not be used when in the view (the HtmlHelper methods will always generate the correct name attributes necessary for 2-way model binding).
Note also that it is a common misconception to believe that the Selected property of SelectListItem needs to be set when generating the SelectList. When binding to a model property, the DropDownList() and DropDownListFor() methods internally generate their own IEnumerable<SelectListItem> and set the Selected property based on the value of the property (any attempt to set it yourself is ignored). The only time the Selected property is respected is when you use DropDownList("xxx", ...) and xxx is not a property or the model.
As a side note, your code in the static method could be just
public static IEnumerable<SelectListItem> PossibleMonths()
{
return Enumerable.Range(1, 12).Select(x => new SelectListItem()
{
Value = x.ToString(),
Text = System.Globalization.CultureInfo.CurrentCulture.DateTimeForm‌at.GetMonthName(x)
});
}
and your view models should not contain properties which are data models when editing data. PaymentFormMV should contain public int ExpirationMonth { get; set; } (and other properties of PaymentCCMV you need), not public PaymentCCMV CreditDetails { get; set; }
Based on your edit showing the image of the html, your generating a name attribute which does not relate to your PaymentFormMV model that is being used in the view (it does not have a property named PaymentInfo) and therefore your not correctly binding to the model, and the correct option will not be selected.
From the comments in chat, you need to change the view to use #model MoveInMV and then the method will be
#Html.DropDownListFor(m => m.PaymentInfo.CreditDetails.ExpirationMonth, Helpers.PossibleMonths, ...)
to give correct 2-way model binding.
I have defined two field properties in the model : public bool? Afield { get; set; }, public bool? Bfield { get; set; }.
In my view I used Razor to used dropdownlistfor to defined possible values for Afield and Bfield. The question is how I can display some values in Bfield when certain value is chosen in Afield dropdownlist:
For example: If Afield is A, then Bfield will only display and allow to choose 1,2,3 for possible options. When Afield is B,then Bfield will only display and allow 3,4...
Code in the view:
Afield:
#Html.DropDownListFor(Model => Model.Afield, new[] {
new SelectListItem() {Text = "A",
Value = bool.TrueString},
new SelectListItem() {Text = "B",
Value = bool.TrueString},
new SelectListItem() {Text = "C",
Value = bool.TrueString}
}, "Choose Afield")
Bfield
#Html.DropDownListFor(Model => Model.Bfield, new[] {
new SelectListItem() {Text = "1",
Value = bool.TrueString},
new SelectListItem() {Text = "2",
Value = bool.TrueString},
new SelectListItem() {Text = "3",
Value = bool.TrueString}
}, "Choose Bfield")
etc.
If it needs to be handled any other way, please suggest.
You have to use ajax for this kind of behaviour.
Check this article: http://www.c-sharpcorner.com/UploadFile/4d9083/creating-simple-cascading-dropdownlist-in-mvc-4-using-razor/
var option = cod.Select(coursesDetail => coursesDetail.Course_Date == c ?
new SelectListItem()
{
Text = coursesDetail.Course_Date,
Value = coursesDetail.Course_Date,
Selected = true
}:
new SelectListItem()
{
Text = coursesDetail.Course_Date,
Value = coursesDetail.Course_Date
}).ToList();
I am passing a list to my view , the code above works perfectly fine and selects an option by default if the conditions are met. However, if I make the following change:
new SelectListItem()
{
Text = coursesDetail.Course_Date,
Value = coursesDetail.Course_Desc_ID.ToString(),
Selected = true
}:
new SelectListItem()
{
Text = coursesDetail.Course_Date,
Value = coursesDetail.Course_Desc_ID.ToString()
}).ToList();
where Course_Desc_ID is an id , selected = true stops working.
Where am I making a mistake ?
I am using MVC4 to build up this project, and I'm having a bit of a hard time figuring out how to take the pre-populated html part that has a date of birth in it, and check it against the current days date to see if the person is above 18 or below 18. Depending on their age, i have a database that has a list of validation options for a drop down list that will display certain things depending on the age. If they are above 18, it will display 3 different results, if below 18, only 1 option will be available. I have tried a couple different ways, one of which worked fine by putting it in the View. But, I want to have this part running from the controller, I just want the logic separate from the ui. Here is the method that I'm working on for it, any help would be great! I've commented out an option or two that I've tried and hasn't worked.
public void SetupValidationList(DateTime? dateOfBirth = null)
{
var vtList = MetadataManager.GetValidationTypes().Where(x => x.DisplayInAdminTool).Select(x => x);
// populate drop down for Validation Method/TypeID
List<SelectListItem> items = vtList.Select(vtitem => new SelectListItem
{
Text = vtitem.DisplayName,
Value = vtitem.ID.ToString()
}).ToList();
items.Insert(0, new SelectListItem { Text = String.Empty, Value = String.Empty });
// If minor then only validation option is face to face minor
// If adult then remove face to face minor validation option
if (dateOfBirth.HasValue)
{
//List<SelectListItem> validationList = new List<SelectListItem>();
if (dateOfBirth >= DateTime.Now.AddYears(-18))
{
vtList(new SelectListItem { Text = "Patient Face to Face Minor" });
}
else
{
items.Add(new SelectListItem { Text = "Patient Face to Face" });
items.Add(new SelectListItem { Text = "Patient Phone" });
items.Add(new SelectListItem { Text = "Patient Notary" });
}
//if (Model.DateOfBirth >= DateTime.Now.AddYears(-18))
//{
// validationList.Add(allValidationList.FirstOrDefault(s => s.Text.Contains("Minor")));
//}
//else
//{
// validationList.AddRange(allValidationList.Where(s => !s.Text.Contains("Minor")));
//}
}
ViewData["ValidationList"] = items;
}
This should work to my mind.
public List<SelectListItem> GetSelectList(DateTime? dateOfBirth)
{
var vtList = MetadataManager.GetValidationTypes().Where(x => x.DisplayInAdminTool).Select(x => x);
List<SelectListItem> myList = new List<SelectListItem>();
var items = (from n in vtList
select new SelectListItem
{
Text = vtitem.DisplayName,
Value = vtitem.ID.ToString()
}).ToList();
foreach( var item in items)
myList.Add(item);
//I don't know, why you need this empty item:
myList.Add(new SelectListItem() { Text = String.Empty, Value = String.Empty });
if (dateOfBirth.HasValue)
{
if (dateOfBirth >= DateTime.Now.AddYears(-18))
{
myList.Add(new SelectListItem() { Text = "Patient Face to Face Minor" });
}
else
{
myList.Add(new SelectListItem() { Text = "Patient Face to Face" });
myList.Add(new SelectListItem() { Text = "Patient Phone" });
myList.Add(new SelectListItem() { Text = "Patient Notary" });
}
return myList; //or ViewBag.list = myList, if void()
}
I defined this editorTemplate to modify the behaviour of a boolean type, my problem is when the type is nullable I want to create a combo to change the default values, to what I want, but I don't know how to select the value that come's from the model.
For example if the value is true I want the dropdownlist selected with SI value and false with NO. Now, I know that I can get the value of the model like this Model.Value but i don't know how to pass to the seleclist depending of the model. Here's my editorTemplate
#model Nullable<bool>
#{
var listItems = new[]{
new SelectListItem { Value = "null", Text = "Sin Valor" },
new SelectListItem { Value = "true", Text = "Si" },
new SelectListItem { Value = "false", Text = "No"}
};
}
#if (ViewData.ModelMetadata.IsNullableValueType)
{
#Html.DropDownList("", listItems)
}
else
{
#Html.CheckBox("", ViewData.Model.Value)
}
You can set this on the SelectListItem: http://msdn.microsoft.com/en-us/library/system.web.mvc.selectlistitem%28v=VS.100%29.aspx
#model Nullable<bool>
#{
var listItems = new[]{
new SelectListItem { Value = "null", Text = "Sin Valor", Selected = !Model.HasValue },
new SelectListItem { Value = "true", Text = "Si", Selected = Model.HasValue && Model.Value },
new SelectListItem { Value = "false", Text = "No", Selected = Model.HasValue && !Model.Value}
};
}
#if (ViewData.ModelMetadata.IsNullableValueType)
{
#Html.DropDownList("", listItems)
}
else
{
#Html.CheckBox("", ViewData.Model.Value)
}