I am using this code to input values from a database table to a dropdown list:
<div class="editor-field">
#Html.DropDownListFor(model => model.TourImageID, new SelectList(Model.Images, "ImageID", "Filename", Model.TourImageID))
</div>
What i am trying to do is add an item to the top of the list, that is not present in the database table.
Something like DROPDOWN LIST VALUES = (DEFAULT-ITEM) + (DATABASE-TABLE-ITEMS)
is that possible? if so, how?
If your Model.Images is of type SelectList, you can do something like this in your controller:
var query = UnitOfWork.GlobalImageLibraryRepository.Images.Select(x => new { x.ImageID, x.Filename });
viewModel.Images = new SelectList(query.AsEnumerable(), "ImageID", "Filename");
viewModel.Images.Insert(0, new SelectListItem { Value = "0", Text = "--Select--" });
I've assumed that you have a method in your GlobalImageLibraryRepository class that returns IQueryable<Images> like this:
public IQueryable<Images> Images { get { return dbcontext.Images; } }
So after all that, your view will look like this:
<div class="editor-field">
#Html.DropDownListFor(model => model.TourImageID, (SelectList)Model.Images, Model.TourImageID))
</div>
Related
In my main page I have Dropdownlist of Cars. And it works fine.
And When I select one car from Dropdownlist I want to get back all car modells who belongs to the selected Car from Dropdownlist in the same view, let say under Dropdownlist. DropDownlist with Cars and Models of the selected cars in the same View (in Main view). I tried with PartialView but I'am not so good when it comes PartielView and html code
This is my action to get CarModels, and I think this must be as PartialView
[HttpGet]
public ActionResult GetCarModel(int? carId)
{
List<CarModelVW> listOfCarModel;
using (Db db = new Db())
{
listOfCarModel = db.CarModel.ToArray()
.Where(x => carId == null || carId == 0 || x.carId == carId)
.Select(x => new CarModelVW(x))
.ToList();
}
return View(listOfCarModel);
}
In my Main View with DropDownlist
<div class="form-group">
<label class="control-label col-md-2" for="HasSidebar"> Car </label>
<div class="col-md-10">
#Html.DropDownListFor(model => model.CarId, Model.Cars, "---Select car---", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.CarId, "", new { #class = "text-danger" })
</div>
</div>
And here below Dropdownlist I want to get all carmodels of selected car
But I think I have to create <div> </div> with Id or span .. but I'am not sure how to do here.
And here is javascript I'am trying to use
$("#CarId").change(function () {
var carId = $(this).val();
if (carId) {
window.location = "/an/GetCarModel?carId=" + carId;
}
return false;
});
How do I get this action GetCarModel below Dropdownlist view? Thank you in advance.
Just like Roman said, instead of navigating to the url, you should send an ajax call to the control.
First of all, add an id to your dropdownlist.
Secondly, in the Onchange function add an ajax call to get cars:
var dropdownval = $("#//Id of dropdown").val();
var json = '{Id: ' + dropdownval + '}';
$.ajax({
url:'#Url.Action("GetCarModel", "//The controller")',
type:'POST',
data: json,
contentType:'Application/json',
success:function(result){
//Do whatever
}
})
You can then do whatever with the result you pass back to the ajax call
If you want to view results on the same page then you need to use Ajax.
add this div tag Main view where you want to display results:
<div id="carmodels"></div>
Change your jquery function as below:
$("#CarId").change(function () {
var carId = $(this).val();
if (carId)
{
$.get("/an/GetCarModel?carId=" + carId, function(data){
$("#carmodels").html(data);
});
}
});
I'm displaying a dropdown list for countries, which is populated from a database call in the controller. On page load I would like the selected value to default to 'United States'. How do I do this?
Code from view:
<div class="form-group">
#Html.LabelFor(m => m.Country)
#Html.DropDownListFor(m => m.Country, new SelectList(Model.CountriesDDL, "CountryCode", "Country"), "--Select--", new { #class = "form-control" })
</div>
In your GET action, you can set the value of Country property to the CountryCode of United states (or whatever country you want to set as default) of your view model
public ActionResult Show()
{
var vm = new YourViewModel();
vm.CountriesDDL = GetCountriesFromSomeWhere();
vm.Country="United States";
return View(vm);
}
Assuming Country is of type string
I'm trying to create an Item edit screen where the user can set a property of the Item, the ItemType. Ideally, when the user returns to the screen, the dropdown would display the ItemType already associated with the Item.
As it is, regardless of what the item.ItemType is, the dropdown will not reflect that in the dropdown. Is there a way around this?
For reference, my code at the moment is:
<div class="form-group">
#Html.LabelFor(model => model.ItemType, new { #class = "control-label col-xs-4" })
<div class="col-xs-8">
#Html.DropDownListFor(model => model.ItemType, (SelectList)ViewBag.ItemType, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ItemType, String.Empty, new { #class = "text-danger" })
</div>
</div>
The ViewBag is set with the following:
var ItemType = Enum.GetValues(typeof(ItemType));
ViewBag.ItemType = new SelectList(ItemType);
If you're using ASP.NET MVC 5, try just using the EnumHelper.GetSelectList method. Then you don't need ViewBag.ItemType.
#Html.DropDownListFor(model => model.ItemType, EnumHelper.GetSelectList(typeof(ItemType)), new { #class = "form-control" })
If not, you might need to specify the data value and data text fields of the select list.
var itemTypes = (from ItemType i in Enum.GetValues(typeof(ItemType))
select new SelectListItem { Text = i.ToString(), Value = i.ToString() }).ToList();
ViewBag.ItemType = itemTypes;
Then since it's an IEnumerable<SelectListItem> you'll need to change your cast.
#Html.DropDownListFor(model => model.ItemType, (IEnumerable<SelectListItem>)ViewBag.ItemType, new { #class = "form-control" })
Eventually I found a fix - manual creation of the list.
<select class="form-control valid" data-val="true"
data-val-required="The Item Type field is required." id="ItemType" name="ItemType"
aria-required="true" aria-invalid="false" aria-describedby="ItemType-error">
#foreach(var item in (IEnumerable<SelectListItem>)ViewBag.ItemType)
{
<option value="#item.Value" #(item.Selected ? "selected" : "")>#item.Text</option>
}
</select>
Try to keep as much of the logic outside of the View and in the Controller.
I saw in your self answer that it looks like you have an enum selected from wihin your controller.
I have a DropDownList in one of my apps that contains a list of Enums. It also has a default value selected, but also has specific enums available to the user. The default selection can be set from within the controller.
This example is based on what my needs were, so you'll need to adapt to your case.
In the controller:
public ActionResult Index()
{
ViewBag.NominationStatuses = GetStatusSelectListForProcessView(status)
}
private SelectList GetStatusSelectListForProcessView(string status)
{
var statuses = new List<NominationStatus>(); //NominationStatus is Enum
statuses.Add(NominationStatus.NotQualified);
statuses.Add(NominationStatus.Sanitized);
statuses.Add(NominationStatus.Eligible);
statuses.Add(NominationStatus.Awarded);
var statusesSelectList = statuses
.Select(s => new SelectListItem
{
Value = s.ToString(),
Text = s.ToString()
});
return new SelectList(statusesSelectList, "Value", "Text", status);
}
In the view:
#Html.DropDownList("Status", (SelectList)ViewBag.NominationStatuses)
This approach will automatically set the default item to the enum that was selected in the controller.
I'm new to MVC and JavaScript and I have a question about DropDownList.
I Build a program of "Car Renting" and I have a View that allow adding new Car to the inventory.
The view include 2 dropdownlists (see below):
<div class="editor-field">
#Html.DropDownList("ManufacturerId", string.Empty)
#Html.ValidationMessageFor(model => model.ManufacturerId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ModelId)
</div>
<div class="editor-field">
#Html.DropDownList("ModelId", string.Empty)
#Html.ValidationMessageFor(model => model.ModelId)
</div>
I want that when user select a manufacturer for example (Alfa Romeo) the "model" list box will display only "Alfa Mito" models and not the full list...
My Controller function send to the view the Model List using ViewBag see below:
public ActionResult AddNewCar()
{
ViewBag.ManufacturerId = new SelectList(db.Manufacturers, "ManufacturerId", "ManufacturerName");
ViewBag.ModelId = new SelectList(db.Models, "ModelId", "ModelName");
ViewBag.BranchId = new SelectList(db.Branchs, "BranchId", "BranchName");
return View();
}
Please advice.
Thanks,
Almog
call below action method from jquery on dropdown change event.
public List<carmodels> PopulateState(int manufacturerId)
{
var carmodelsObj = (from st in dc.Carmodels
where st.manufacturerId.Equals(manufacturerId)
select st).ToList();
return (carmodelsObj);
}
You need to repopulate/populate your ModelId dropdown on every time when your first dropdown changes (using jquery). Do following:
Get the ManufactureId from first dropdown on change event. and place an ajax call to repopulate your second dropdown.
$("#ManufactureId").change(function() {
var manufacturerId = manufacturer$('#ManufacturerId').val();
$.ajax({url: "~/Car/GetCarsByManufacturer", success: function(result){
//re populate your second dropdown here
//hint: you may use response.id for value
}});
});
Create a function in your controller that returns Car Models, based on selected. (call this function in previous step using ajax).
public List<carmodels> GetCarsByManufacturer(int manufacturerId)
{
var carmodelsObj = (from st in dc.Carmodels
where st.manufacturerId.Equals(manufacturerId)
select st).ToList();
return (carmodelsObj);
}
I'm having the same issue as this here I believe, but the workaround is not working for me.
My issue is that I have a child collection of models inside my main view's ViewModel. They contain data to be displayed in two fields, a dropdownlist and a password field. Each dropdownlist selection must be unique. Everything is saving and being sent to the view properly, however the dropdownlist are not binding to the selected values when the view is called but the password field is. They all default to the first selection, even though the property they are suppose to bind to is unique and only one can be the first value. Any help or insight is appreciated. Thanks.
Here is the part in my view where the issue is occurring. I have commented out my efforts and tried the above link's workaround to no avail:
#functions {
private IEnumerable<SelectListItem> Mark(IEnumerable<SelectListItem> items, object Id)
{
foreach (var item in items)
if (string.CompareOrdinal(item.Value, Convert.ToString(Id)) == 0)
item.Selected = true;
return items;
}
}
#for (int j = 0; j < Model.PasswordResetQuestionUserAnswers.Count(); j++)
{
#Html.Hidden("PasswordResetQuestionUserAnswers.Index", j)
#Html.HiddenFor(p => Model.PasswordResetQuestionUserAnswers[j].Id)
#Html.HiddenFor(p => Model.PasswordResetQuestionUserAnswers[j].UserId)
<div class="form-group">
<label class="col-md-2 control-label">Password Reset Question #(j+1)</label>
<div class="col-md-6">
#*#Html.DropDownList("PasswordResetQuestionUserAnswers[" + j + "].PasswordResetQuestionId", Model.PasswordResetQuestionList, new { #class = "form-control passwordQuestion" })*#
#*#Html.DropDownListFor(x => Model.PasswordResetQuestionUserAnswers[j].PasswordResetQuestionId, Model.PasswordResetQuestionList, new { #class = "form-control passwordQuestion" })*#
#Html.DropDownListFor(x => Model.PasswordResetQuestionUserAnswers[j].PasswordResetQuestionId, Mark(Model.PasswordResetQuestionList, Model.PasswordResetQuestionUserAnswers[j].PasswordResetQuestionId))
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Password Reset Answer #(j+1)</label>
<div class="col-md-6">
#Html.Password("PasswordResetQuestionUserAnswers[" + j + "].Answer", Model.PasswordResetQuestionUserAnswers[j].Answer, new { #class = "form-control passwordQuestionUserAnswer" })
#*#Html.PasswordFor(x => Model.PasswordResetQuestionUserAnswers[j].Answer, new { #class = "form-control passwordQuestionUserAnswer" })*#
</div>
</div>
}
I just had this same problem. This syntax works for me:
#Html.DropDownListFor(x => x.ChildCollection[i].ChildID, new SelectList(ViewBag.ChildCollectionSelect as SelectList, "Value", "Text", Model.ChildCollection[i].ChildID))
Define the SelectList as new, then specifically set the selected value from the model.
This is an adaption to the example of above, for what worked for me in a similar scenario, where itm represents the child object in the collection. I'm not exactly sure what all is going on in that example -- too many "Questions", "Users", and "Answers", but say if you wanted a dropdown of users and it to be filled with the particular one that had been assigned to that child item:
foreach (var itm in Model.PasswordResetQuestionUserAnswers)
{
#Html.DropDownListFor(modelItem => itm.UserId,
new SelectList( (IEnumerable<SelectListItem>)ViewData["users"], "Value", "Text", itm.UserId),
htmlAttributes: new { #class = "form-control" }
)
}
Where you'd fill ViewData["users"] like this in the Controller method that renders the view:
var usersList = GetUsersList();
ViewData["users"] = usersList;
and have these supporting functions:
private static SelectListItem[] _UsersList;
/// <summary>
/// Returns a static category list that is cached
/// </summary>
/// <returns></returns>
public SelectListItem[] GetUsersList()
{
if (_UsersList == null)
{
var users = repository.GetAllUsers().Select(a => new SelectListItem()
{
Text = a.USER_NAME,
Value = a.USER_ID.ToString()
}).ToList();
users.Insert(0, new SelectListItem() { Value = "0", Text = "-- Please select your user --" });
_UsersList = users.ToArray();
}
// Have to create new instances via projection
// to avoid ModelBinding updates to affect this
// globally
return _UsersList
.Select(d => new SelectListItem()
{
Value = d.Value,
Text = d.Text
})
.ToArray();
}
Repository.cs
My Repository function GetAllUsers() for the function, above:
Model1 db = new Model1(); // Entity Framework context
// Users
public IList<USERS> GetAllUsers()
{
return db.USERS.OrderBy(e => e.USER_ID).ToList();
}
Users.cs
public partial class USERS
{
[Key]
public int USER_ID { get; set; }
[Required]
[StringLength(30)]
public string USER_NAME { get; set; }
}
Edit
After re-reading the question, it seems it was about posting password reset questions.
foreach (var itm in Model.PasswordResetQuestionUserAnswers)
{
#Html.DropDownListFor(modelItem => itm.PasswordResetQuestionId,
new SelectList( (IEnumerable<SelectListItem>)ViewData["pwordResetQuestions"], "Value", "Text", itm.PasswordResetQuestionId),
htmlAttributes: new { #class = "form-control" }
)
}
And you'd have to have a ViewData["pwordResetQuestions"] filled like this in the controller method that renders that view:
var questionsList = GetQuestionsList();
ViewData["questions"] = questionsList;
and these supporting functions/objects:
private SelectListItem[] _QuestionsList;
public SelectListItem[] GetQuestionsList()
{
if (_QuestionsList == null)
{
var questions = PasswordResetQuestionUserAnswers.Select(a => new SelectListItem()
{
Text = a.Answer, //? I didn't see a "PasswordResetQuestionText" call in your example, so...
Value = a.PasswordResetQuestionId.ToString()
}).ToList();
questions.Insert(1, new SelectListItem() { Value = "1", Text = "Mother's Maiden Name" });
questions.Insert(2, new SelectListItem() { Value = "2", Text = "Elementary school attended" });
_QuestionsList = questions.ToArray();
}
// Have to create new instances via projection
// to avoid ModelBinding updates to affect this
// globally
return _QuestionsList
.Select(d => new SelectListItem()
{
Value = d.Value,
Text = d.Text
})
.ToArray();
}
I hard-coded some questions in there - I kinda doubt you'd have a table for them, usually companies only have less than 10. But you could always do that database call like I did for the Users table if they were using a database table - which is why I left that example there.
I was having the same issue and fighting with it. The examples above got me over the hump, but I was able to simplify using the code the way you have it, with one modification:
Original Code
#Html.DropDownListFor(x => Model.PasswordResetQuestionUserAnswers[j].PasswordResetQuestionId, Model.PasswordResetQuestionList, new { #class = "form-control passwordQuestion" })
Update Code: (Wrap it with a new SelectList)
#Html.DropDownListFor(x => Model.PasswordResetQuestionUserAnswers[j].PasswordResetQuestionId, new SelectList(Model.PasswordResetQuestionList, "Value", "Text", Model.PasswordResetQuestionUserAnswers[j].PasswordResetQuestionId, new { #class = "form-control passwordQuestion" })
This eliminates the need for the ViewBag or ViewData.