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'm trying to create drop down lists to set the values of elements in an array. I have this plain object to hold the details of a single room
public class RoomOccupants
{
public int adults { get; set; }
public int children { get; set; }
public int infants { get; set; }
}
And an array of these objects on my model to hold the information of all the rooms
public RoomOccupants[] rooms { get; set; }
In my razor template I'm creating the drop down lists like this
<label>Guests in Room 1</label><br />
<label>Adults</label>
#Html.DropDownListFor(model => model.rooms[0].adults, Model.passengerOptions, new { autocomplete = "off" })
<label>Children</label>
#Html.DropDownListFor(model => model.rooms[0].children, Model.passengerOptions, new { autocomplete = "off" })
<label>Infants</label>
#Html.DropDownListFor(model => model.rooms[0].infants, Model.passengerOptions, new { autocomplete = "off" })
The Model.passengerOptions is a list of SelectListItem for the integers 0 - 9, Which I'm using in several different drop downs. It's created in the constructor of the model like this.
passengerOptions = new List<SelectListItem>();
passengerOptions.Add(new SelectListItem() { Value = "0", Text = "0"});
passengerOptions.Add(new SelectListItem() { Value = "1", Text = "1" });
passengerOptions.Add(new SelectListItem() { Value = "2", Text = "2" });
passengerOptions.Add(new SelectListItem() { Value = "3", Text = "3" });
passengerOptions.Add(new SelectListItem() { Value = "4", Text = "4" });
passengerOptions.Add(new SelectListItem() { Value = "5", Text = "5" });
passengerOptions.Add(new SelectListItem() { Value = "6", Text = "6" });
passengerOptions.Add(new SelectListItem() { Value = "7", Text = "7" });
passengerOptions.Add(new SelectListItem() { Value = "8", Text = "8" });
passengerOptions.Add(new SelectListItem() { Value = "9", Text = "9" });
When I debug the code I can see that my model contains the correct values, but all the drop down lists always display 0.
I've created some drop downs that work fine on the same page using the same list of options, but they are not in arrays, so maybe that's it?
Don't know exactly that whether this is because of array,it may have.
Instead of that try, List ..This will work Correctly.
public List < SelectedListItem > rooms {get;set;} in model.
And you can directly use the property of model.
#Html.DropDownListFor(model => model.infants , Model.passengerOptions, new { autocomplete = "off" })
Thanks.
#Html.DropDownListFor(model => model.children , Model.passengerOptions, new { autocomplete = "off" })
#Html.DropDownListFor(model => model.adults, Model.passengerOptions, new { autocomplete = "off" })
Thank You. :)
How do I set the selected value on a select list.
For example, say i'm displaying an existing client and on the form it has a dropdown list for "Gender", I want "Male" to be selected (if that what was saved in the db) how do I do this?
When I'm building my model im doing something like
public ActionResult Edit(string id)
{
var client= _clientService.FindById(id);
var model = new ViewModels.Client()
{
GenderId= client.GenderId,
GenderList= CreateGenderList(GenderId)
};
}
private IEnumerable<SelectListItem> CreateGenderList(int gId)
{
var list = Enum.GetValues(typeof(DomainObjects.Client.GenderList))
.Cast<DomainObjects.Client.GenderList>()
.Select(v => new SelectListItem { Text = v.ToString(), Value = ((int)v).ToString() });
//Need to set the selected value, how?
return list.ToList();
}
Thank you in Advance.
You should make use of the additional SelectListItem.Selected property, and set this to true. For example:
var list = Enum.GetValues(typeof(DomainObjects.Client.GenderList))
.Cast<DomainObjects.Client.GenderList>()
.Select(v => new SelectListItem {
Text = v.ToString(),
Value = ((int)v).ToString()});
var maleGenderItem = list.Single(x => x.Text == "Male");
maleGenderItem.Selected = true;
This did it
var list = Enum.GetValues(typeof(DomainObjects.Client.GenderList))
.Cast<DomainObjects.Client.GenderList>()
.Select(v => new SelectListItem { Text = v.ToString(), Value = ((int)v).ToString(), Selected = gName.ToString() == ((int)v).ToString() });
return list.ToList();
I have 2 lists containing different types. One is a string[] and another is a List<SelectListItem>.
SelectListItem (it's in mvc):
public string Text {get;set;}
public string Value {get;set;}
public bool Selected {get;set;}
My string[] is just contains some text values.
What i'm trying to do is, get whatever is in the string[], then set "Selected = true" for whatever Value matches, and "Selected = false" for what doesnt match.
So lets say my string[] is:
Test1
Test2
Test3
And my List<SelectListItem> is:
new SelectListItem { Text = "Testing", Value = "Test1", Selected = false },
new SelectListItem { Text = "Testing", Value = "Test4", Selected = true }
In the above List<SelectListItem>, i have one match. So what i'd like to do, is set Selected = true for that particular entry so that i end up with:
new SelectListItem { Text = "Testing", Value = "Test1", Selected = true },
new SelectListItem { Text = "Testing", Value = "Test4", Selected = false }
How would I achieve this?
foreach(var i in selectListItemList)
i.Selected = stringArray.Contains(i.Value);
or using List.ForEach:
selectListItemList.ForEach(i => i.Selected = stringArray.Contains(i.Value));
How about
list.ForEach(x => x.Selected = stringarray.Contains(x.Value))
var items = SelectListItems.Where(p=>stringArray.Contains(p));;
foreach(var item in items)
item.Selected=true;
I have no idea how to work this out but my drop down list code looks as follows:
in the action:
DateTime[] allSundaysInMonth = GetDatesOfSundays(System.DateTime.Now);
DateTime[] allSundaysInLastMonth = GetDatesOfSundays(System.DateTime.Now.AddDays(-30));
List<SelectListItem> listOfSundays = new List<SelectListItem>();
foreach (DateTime dt in allSundaysInThisMonth)
{
listOfSundays.Add(new SelectListItem
{
Text = dt.Name,
Value = dt.Id.ToString(),
Selected = dt.CompanyId == Id
});
return listOfSundays;
}
I need to take the last two sundays af last month and all sundays of this month, but not future sundays, and build a list with all these sundays.
This is something i did while on a past project
public List<SelectListItem> CompanySelectList(List<Company> companyList, int selectedId = 0)
{
List<SelectListItem> listToReturn = new List<SelectListItem>();
foreach (Company c in companyList)
{
listToReturn.Add(new SelectListItem
{
Text = c.CompanyName,
Value = c.CompanyId.ToString(),
Selected = c.CompanyId == selectedId
});
}
return listToReturn;
}
just modify your T so it will return what you need.
You could look at the current date and start looping down, if the date then returned is a sunday set this value to be selected.