Two instances of DropDownListFor - c#

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/

Related

How to set the value of dropdown coming from model in ASP.NET MVC

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.

Why is my Html.DropDownListFor not displaying the model's value correctly?

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 change the options from a dropdownlist based on the selected value from another dropdownlist using ajax?

I'm using ajax to change the options from a dropdownlist with a change event after a user selects an option from a separate dropdownlist and it isn't changing the options at all. Here is my ajax code which seems to work fine.
$(document).ready(function () {
// if user changes paper type
$('#paperTypeJList').change(function () {
var modelData = {
paperType: $("#paperTypeJList").val(),
urgency: $("#urgencyJList").val(),
numOfPages: $("#numOfPagesJList").val()
};
$.ajax({
url: '#Url.Action("changeDropDownValues", "Home")',
type: "GET",
data: {paperType:modelData.paperType},
cache: false,
async: true,
success: function (response) {
alert("Success");
}
});
});
Here is the code for the method that I'm calling with the ajax code
public void changeDropDownValues(string paperType)
{
List<SelectListItem> urgencyList1 = new List<SelectListItem>();
urgencyList1.Add(new SelectListItem() { Text = "Select the Urgency", Value = "", Selected = true });
urgencyList1.Add(new SelectListItem() { Text = "60 Days", Value = "60", Selected = false });
urgencyList1.Add(new SelectListItem() { Text = "30 Days", Value = "30", Selected = false });
urgencyList1.Add(new SelectListItem() { Text = "20 Days", Value = "20", Selected = false });
urgencyList1.Add(new SelectListItem() { Text = "10 Days", Value = "10", Selected = false });
urgencyList1.Add(new SelectListItem() { Text = "7 Days", Value = "7", Selected = false });
urgencyList1.Add(new SelectListItem() { Text = "5 Days", Value = "5", Selected = false });
urgencyList1.Add(new SelectListItem() { Text = "4 Days", Value = "4", Selected = false });
urgencyList1.Add(new SelectListItem() { Text = "72 Hours", Value = "72", Selected = false });
urgencyList1.Add(new SelectListItem() { Text = "48 Hours", Value = "48", Selected = false });
urgencyList1.Add(new SelectListItem() { Text = "24 Hours", Value = "24", Selected = false });
urgencyList1.Add(new SelectListItem() { Text = "12 Hours", Value = "12", Selected = false });
urgencyList1.Add(new SelectListItem() { Text = "6 Hours", Value = "6", Selected = false });
urgencyList1.Add(new SelectListItem() { Text = "3 Hours", Value = "3", Selected = false });
List<SelectListItem> urgencyList2 = new List<SelectListItem>();
urgencyList2.Add(new SelectListItem() { Text = "Select the Urgency", Value = "", Selected = true });
urgencyList2.Add(new SelectListItem() { Text = "10 Days", Value = "10", Selected = false });
urgencyList2.Add(new SelectListItem() { Text = "7 Days", Value = "7", Selected = false });
urgencyList2.Add(new SelectListItem() { Text = "5 Days", Value = "5", Selected = false });
urgencyList2.Add(new SelectListItem() { Text = "4 Days", Value = "4", Selected = false });
urgencyList2.Add(new SelectListItem() { Text = "72 Hours", Value = "72", Selected = false });
urgencyList2.Add(new SelectListItem() { Text = "48 Hours", Value = "48", Selected = false });
urgencyList2.Add(new SelectListItem() { Text = "24 Hours", Value = "24", Selected = false });
urgencyList2.Add(new SelectListItem() { Text = "12 Hours", Value = "12", Selected = false });
urgencyList2.Add(new SelectListItem() { Text = "6 Hours", Value = "6", Selected = false });
urgencyList2.Add(new SelectListItem() { Text = "3 Hours", Value = "3", Selected = false });
switch (paperType)
{
case "Dissertation":
ViewBag.urgency = new SelectList(urgencyList1, "Value", "Text");
break;
case "Research Proposal":
ViewBag.urgency = new SelectList(urgencyList1, "Value", "Text");
break;
default:
ViewBag.urgency = new SelectList(urgencyList2, "Value", "Text");
break;
}
}
If you are using WebForms,then you should use Cascaded DropDownList of Asp.net AJAX Control Toolkit:
http://www.asp.net/AjaxLibrary/AjaxControlToolkitSampleSite/CascadingDropDown/CascadingDropDown.aspx
Here is a Tutorial
Updated:
if you are working in asp.net mvc, you can implement cascaded drop down list this way:
http://blogs.msdn.com/b/rickandy/archive/2012/01/09/cascasding-dropdownlist-in-asp-net-mvc.aspx

C# Linq List Compare and update lists

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;

Modify the MVC default behaviour of boolean types

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)
}

Categories