Defining a select list through controller and view model - c#

I have a View Model that looks like this:
public class SomeViewModel
{
public SomeViewModel(IEnumerable<SelectListItem> orderTemplatesListItems)
{
OrderTemplateListItems = orderTemplatesListItems;
}
public IEnumerable<SelectListItem> OrderTemplateListItems { get; set; }
}
I then have an Action in my Controller that does this:
public ActionResult Index()
{
var items = _repository.GetTemplates();
var selectList = items.Select(i => new SelectListItem { Text = i.Name, Value = i.Id.ToString() }).ToList();
var viewModel = new SomeViewModel
{
OrderTemplateListItems = selectList
};
return View(viewModel);
}
Lastly my view:
#Html.DropDownListFor(n => n.OrderTemplateListItems, new SelectList(Model.OrderTemplateListItems, "value", "text"), "Please select an order template")
The code works fine and my select list populates wonderfully. Next thing I need to do is set the selected value that will come from a Session["orderTemplateId"] which is set when the user selects a particular option from the list.
Now after looking online the fourth parameter should allow me to set a selected value, so if I do this:
#Html.DropDownListFor(n => n.OrderTemplateListItems, new SelectList(Model.OrderTemplateListItems, "value", "text", 56), "Please select an order template")
56 is the Id of the item that I want selected, but to no avail. I then thought why not do it in the Controller?
As a final attempt I tried building up my select list items in my Controller and then passing the items into the View:
public ActionResult Index()
{
var items = _repository.GetTemplates();
var orderTemplatesList = new List<SelectListItem>();
foreach (var item in items)
{
if (Session["orderTemplateId"] != null)
{
if (item.Id.ToString() == Session["orderTemplateId"].ToString())
{
orderTemplatesList.Add(new SelectListItem { Text = item.Name, Value = item.Id.ToString(), Selected = true });
}
else
{
orderTemplatesList.Add(new SelectListItem { Text = item.Name, Value = item.Id.ToString() });
}
}
else
{
orderTemplatesList.Add(new SelectListItem { Text = item.Name, Value = item.Id.ToString() });
}
}
var viewModel = new SomeViewModel
{
OrderTemplateListItems = orderTemplatesList
};
return View(viewModel);
}
Leaving my View like so:
#Html.DropDownListFor(n => n.OrderTemplateListItems, new SelectList(Model.OrderTemplateListItems, "value", "text"), "Please select an order template")
Nothing!
Why isn't this working for me?

You say "56 is the Id of the item that I want selected, but to no avail"
Should the fourth parameter you refer to be a string, not an integer, like so:
#Html.DropDownListFor(n => n.OrderTemplateListItems, new SelectList(Model.OrderTemplateListItems, "value", "text", "56"), "Please select an order template")

Related

Asp.Net Mvc Selectpicker

I am trying to implement a DropDownList Multi Select using Bootstrap Selectpicker for selecting Schools in my application.
I am not very familiar with MVC and JQuery since i have been using webforms for a long time, so i am learning from internet to accomplish.
Here is the scenario:
on my layout, there is a DropDownList:
#*DropDownList Select School*#
#Html.DropDownList("Schools", null, null, new { id = "MultiSelect", #class = "selectpicker form-control", multiple = "", title = "School" })
The code to fill the DropDownList:
public ActionResult Class()
{
IEnumerable<SelectListItem> ListClasses = db.scasy_class
.OrderBy(a => a.class_name)
.Select(c => new SelectListItem
{
Value = c.id.ToString(),
Text = c.class_name,
Selected = false
});
ViewBag.Class = ListClasses.ToList();
ClassViewModel classViewModel = new ClassViewModel()
{
SelectOptions = ListClasses
};
return View(classViewModel);
}
On layout, when the user selects some schools, using the dropdownlist,
$('#MultiSelect').on('change', function () {
$.each($("#MultiSelect option"), function () {
$.post("/Setup/Student/SetSchool/", { school: $(this).val(), selected: $(this).prop('selected') });
});
});
and the controller;
public ActionResult SetSchool(int school, bool selected)
{
ArrayList school_nos = Session["Schools"] as ArrayList;
if (selected)
{
if (!school_nos.Contains(school))
{
school_nos.Add(school);
}
}
else
{
if (school_nos.Contains(school))
{
school_nos.Remove(school);
}
}
Session["Schools"] = school_nos;
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
it is working as it is expected until here.
For the next reload, i am trying to fill the dropdownlist with the same data but show previously selected schools with tick, using Session values, since i will need this information on many other pages.
$(document).ready(function () {
$.getJSON("/Setup/Student/GetSchool/",
function (data) {
var myData = [];
$.each(data, function (index, item) {
if (item.Selected == true) {
myData.push(item.Value);
}
});
//alert(myData);
$('#MultiSelect').selectpicker('val', myData);
});
});
and the controller;
public JsonResult GetSchool()
{
IEnumerable<SelectListItem> ListSchools = db.scasy_school
.OrderBy(a => a.name)
.Select(a => new SelectListItem { Value = a.id.ToString(), Text = a.name});
ArrayList school_nos = Session["Schools"] as ArrayList;
List<SelectListItem> ListSchoolsUpdated = new List<SelectListItem>();
foreach (var item in ListSchools)
{
SelectListItem selListItem;
if (school_nos.Contains(item.Value.ToString()))
{
selListItem = new SelectListItem() { Value = item.Value.ToString(), Text = item.Text, Selected = true };
}
else
{
selListItem = new SelectListItem() { Value = item.Value.ToString(), Text = item.Text, Selected = false };
}
ListSchoolsUpdated.Add(selListItem);
}
return Json(ListSchoolsUpdated, JsonRequestBehavior.AllowGet);
}
Code throws no error, but i cannot have the dropdownlist with selected items shown.
Declare a model class for your page
public class ClassViewModel {
public List<int> SelectedSchools {get; set;}
public List<SelectListItem> Schools {get; set;}
}
Set Selected Schools in your controller action.
Set Your View Model
#model ClassViewModel
Then in your view use this code to show dropdownlist
#Html.ListBoxFor(m=> m.SelectedSchools , Model.Schools, new {id = "MultiSelect", #class = "selectpicker form-control", title = "School" })

MVC dropdownlist required field validation not working

I am new to MVC, as part of my work i need to validate drop down list with required field validation, i tried in below way but Validation not working,
When i click on submit button without selecting a dropdown menu Validation is not working.
Model:
[Required(ErrorMessage = "*Required")]
[Display(Name = "Environment")]
public int? Environment { set; get; }
Controller:
List<SelectListItem> environmentlist = new List<SelectListItem>();
environmentlist.Add(new SelectListItem { Text = "SIT", Value = "1" });
environmentlist.Add(new SelectListItem { Text = "UAT", Value = "2" });
environmentlist.Add(new SelectListItem { Text = "PROD", Value = "3" });
ViewBag.EnvironmentList = environmentlist;
View:
#Html.DropDownListFor(model => model.Environment,(IEnumerable<SelectListItem>)ViewBag.EnvironmentList, String.Empty)
#Html.ValidationMessageFor(model => model.Environment)
This can be help in your code,
Public ActionResult yourMethod()
{
if (ModelState.IsValid)
{
// Your code
}
else
{
return View("Same View");
}
}
Learn more about ModelState.IsValid.
Try the following
#Html.DropDownListFor(model => model.Environment,(IEnumerable<SelectListItem>)ViewBag.EnvironmentList, new {required = "required"})

Html.Dropdownlistfor selected value is not working

I can't get the selected value to work with HTML.dropwdownlistfor
Here is what I have trying to get to work, ALL DATA IS THERE, the select statement finds the selected item, the ienumerable of SelectListItems has an item that has the "select = true" I'm not sure where I'm going wrong.
MODEL:
[SitecoreIgnore]
public virtual IEnumerable<Sitecore.Data.Items.Item> List_Location { get; set; }
public virtual Sitecore.Data.Items.Item Location { get; set; }
[SitecoreIgnore]
public virtual string Location_Model { get; set; }
HELPER METHOD:
public static IEnumerable<SelectListItem> SelectListConstructor(Item selectedItem, IEnumerable<Item> options)
{
IEnumerable<SelectListItem> listings = from o in options
select new SelectListItem
{
Selected = (selectedItem.ID == o.ID),
Text = o.DisplayName,
Value = o.ID.ToString()
};
return listings;
}
Controller: (The casting works fine, data is there)
[HttpPost]
public ActionResult CreateAdStep(Classified model)
{
if(ModelState.IsValid)
{
return RedirectToAction("PreviewAd", model);
}
var allerrrors = ModelState.Values.SelectMany(v => v.Errors);
return View(Sitecore.Context.Database.GetItem("{69040A7B-5444-4ECF-A081-C4A3B26876B5}").GlassCast<Classified>());
}
[HttpGet]
public ActionResult CreateAdStep()
{
var trial = Sitecore.Context.Database.GetItem("{69040A7B-5444-4ECF-A081-C4A3B26876B5}").GlassCast<Classified>();
return View(trial);
}
CSHTML LINE ATTEMPTS:
1)
#{ var emo = CalCPA.Source.Models.Utility.Utility.SelectListConstructor(Model.Location, Model.List_Location);
var emo2 = emo.Where(i=> i.Selected == true).FirstOrDefault();
}
#Html.DropDownListFor(m => m.Location_Model, new SelectList(emo, "Value", "Text", emo2.Value))
2)
#{ var emo = CalCPA.Source.Models.Utility.Utility.SelectListConstructor(Model.Location, Model.List_Location);
var emo2 = emo.Where(i=> i.Selected == true).FirstOrDefault();
}
#Html.DropDownListFor(m => m.Location_Model, new SelectList(emo, "Value", "Text", emo2))
3)
#{ var emo = CalCPA.Source.Models.Utility.Utility.SelectListConstructor(Model.Location, Model.List_Location);
var emo2 = emo.Where(i=> i.Selected == true).FirstOrDefault();
}
#Html.DropDownListFor(m => m.Location_Model, emo)
Thanks for any insight/help!!!
If your going to use DropDownListFor you need to set the selected value in the model first.
In your action (or model builder):
model.Location_Model = "my selected value";
Then your view:
#Html.DropDownListFor(m => m.Location_Model, new SelectList(emo, "Value", "Text"))

How can I get my MultiSelectList to bind to my data model?

I have a many to many relationship between cars and many other tables. In my view I want to be able to have a multiselect list for items such as lights. I've tried many different formats I can't seem to get the list to set selected items.My preferred way to do it would be #Html.ListBoxFor(model => model.enitity.relatedentity, Model.SomeSelectListItemList) , but I can not seem to get list to set selected items in the view.
Below is my code I was testing with
I use Asp.net MVC5, C# and entity framework 6.
This is my controller action
// GET: Car/Edit/
[Authorize(Roles = "Ecar")]
public ActionResult Edit(int id)
{
CarsEditViewModel carEditViewModel = new CarsEditViewModel();
carEditViewModel.Cars = unitOfWorkcar.CarRepository.FindIncluding(id);
IList<Approval> approvalList = unitOfWorkcar.ApprovalRepository.All.ToList();
IList<Connector> connectorList = unitOfWorkcar.ConnectorRepository.All.ToList();
IList<InputVoltage> inputVoltagesList = unitOfWorkcar.InputVoltageRepository.All.ToList();
carEditViewModel.ApprovalList = from c in approvalList select new SelectListItem { Text = c.Name, Value = c.Id.ToString(), Selected = true};
carEditViewModel.Categories = new MultiSelectList(carEditViewModel.ApprovalList, "Value", "Text", "Selected");
// ,carEditViewModel.ApprovalList.Select(c => c.Text),carEditViewModel.ApprovalList.Select(c => c.Selected)
//carEditViewModel.ApprovalList = from c in approvalList select new MultiSelectList( //{ Selected = (carEditViewModel.Cars.Approvals.Any(app => app.Id == c.Id)) , Text = c.Name, Value = c.Id.ToString() };
// carEditViewModel.ConnectorList = from c in connectorList select new SelectListItem { Selected = true, Text = c.Name, Value = c.Id.ToString() };
carEditViewModel.InputVoltageList = from c in inputVoltagesList select new SelectListItem { Text = c.Name, Value = c.Id.ToString() };
return View(carEditViewModel);
}
Here is my view
#model NewBobPortal.ViewModels.CarsEditViewModel
#using (Html.BeginForm())
{
#* #Html.ListBoxFor("SelectedApprovals",model => model., new { #class = "multiselect" })*#
#*#Html.ListBoxFor(model => model.Cars.Approvals, Model.ApprovalList)
#Html.ListBoxFor(model => model.Cars.Connectors,Model.ConnectorList, new {Multiple = "multiple"})
#Html.ListBoxFor(model => model.ConnectorList, Model.ConnectorList)*#
#*#Html.ListBox("test",Model.Cars.InputVoltages, Model.InputVoltageList)*#
#Html.DropDownList("somethingelse", new MultiSelectList(Model.InputVoltageList, "Value", "Text", Model.InputVoltageList.Select(c => c.Value)), new { multiple = "multiple" })
#Html.DropDownListFor(model => model.Cars.InputVoltages , new MultiSelectList(Model.LensColorList, "Value", "Text", Model.LensColorList.Select(c => c.Value)), new { multiple = "multiple" })
#Html.ListBoxFor(m => m.Cars.Approvals, Model.Categories)
<p>
<input type="submit" value="Save" />
</p>
}
This is my viewmodel
using NewBobPortal.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace NewBobPortal.ViewModels
{
public class CarsEditViewModel
{
public Car Cars { get; set; }
public IEnumerable<SelectListItem> ApprovalList { get; set; }
public IEnumerable<MultiSelectList> ConnectorList { get; set; }
public IEnumerable<SelectListItem> InputVoltageList { get; set; }
public MultiSelectList Categories { get; set; }
public IEnumerable<Approval> SelectedCategories { get; set; }
}
}
The biggest problem with posting values for a many-to-many relationship is that there's no direct field to bind to on your model. This is where view models become very handy, which you're already using, but not quite in the right way for this.
First you need your SelectList, which can actually just be an IEnumerable<SelectListItem>. This will contain all available options, which is easy enough. So in your view model:
public IEnumerable<SelectListItem> CategoryChoices { get; set; }
And in your action:
carEditViewModel.CategoryChoices = approvalList.Select(m => new SelectListItem {
Text = c.Name,
Value = c.Id.ToString()
});
Notice that I'm not setting Selected: we'll let the HtmlHelper handle that. I'm also not dealing with a MultiSelectList yet either.
Now, you'll also need something to post back to, since your values will be ids, we'll use a List<int>, so in your view model:
private List<int> selectedCategories;
public List<int> SelectedCategories
{
get
{
if (selectCategories == null)
{
selectedCategories = Categories.Select(m => m.Id).ToList();
}
return selectedCategories;
}
set { selectedCategories = value; }
}
There's a bit going on here. The set method of the property is simple: when we get a posted value back, just set selectedCategories to that. The get is a bit more complicated: here we need to condense down your list of category objects (called Categories here because I don't know where this is actually coming from) into a simple list of ids for those categories.
Now, in your view:
#Html.ListBoxFor(m => m.SelectedCategories, Model.CategoryChoices)
That's all you need. You're using a ListBox control so it's already a multiple select list. And, by binding it to the list of all currently selected ids, it knows which items to select automatically in the list of SelectListItems it gets from Model.CategoryChoices.
In your post action, you then need to translate these ids into their associated objects:
var newCategories = repository.Categories.Where(m => carEditViewModel.SelectedCategories.Contains(m.Id));
Then, you can set your model's categories to this new list manually:
car.Categories = newCategories;

Getting Multiple Selected Values in Html.DropDownlistFor

#Html.DropDownListFor(m => m.branch, CommonMethod.getBranch("",Model.branch), "--Select--", new { #multiple = "multiple" })
#Html.DropDownListFor(m => m.division, CommonMethod.getDivision(Model.branch,Model.division), "--Select--", new { #multiple = "multiple" })
I have two instances of DropDownListFor. I want to set selected as true for those which have previously stored values for Model.branch and Model.division. These are string arrays of stored ids
class CommonMethod
{
public static List<SelectListItem> getDivision(string [] branchid , string [] selected)
{
DBEntities db = new DBEntities();
List<SelectListItem> division = new List<SelectListItem>();
foreach (var b in branchid)
{
var bid = Convert.ToByte(b);
var div = (from d in db.Divisions where d.BranchID == bid select d).ToList();
foreach (var d in div)
{
division.Add(new SelectListItem { Selected = selected.Contains(d.DivisionID.ToString()), Text = d.Description, Value = d.DivisionID.ToString() });
}
}
}
return division;
}
}
The returned value of division is selected as true for the selected item in the model, but on view side it is not selected.
Use a ListBoxFor instead of DropDownListFor:
#Html.ListBoxFor(m => m.branch, CommonMethod.getBranch("", Model.branch), "--Select--")
#Html.ListBoxFor(m => m.division, CommonMethod.getDivision(Model.branch, Model.division), "--Select--")
The branch and division properties must obviously be collections that will contain the selected values.
And a full example of the proper way to build a multiple select dropdown using a view model:
public class MyViewModel
{
public int[] SelectedValues { get; set; }
public IEnumerable<SelectListItem> Values { get; set; }
}
that would be populated in the controller:
public ActionResult Index()
{
var model = new MyViewModel();
// preselect items with values 2 and 4
model.SelectedValues = new[] { 2, 4 };
// the list of available values
model.Values = new[]
{
new SelectListItem { Value = "1", Text = "item 1" },
new SelectListItem { Value = "2", Text = "item 2" },
new SelectListItem { Value = "3", Text = "item 3" },
new SelectListItem { Value = "4", Text = "item 4" },
};
return View(model);
}
and in the view:
#model MyViewModel
...
#Html.ListBoxFor(x => x.SelectedValues, Model.Values)
It is the HTML helper that will automatically preselect the items whose values match those of the SelectedValues property.
For me it works also for #Html.DropDownListFor:
Model:
public class MyViewModel
{
public int[] SelectedValues { get; set; }
public IEnumerable<SelectListItem> Values { get; set; }
}
Controller:
public ActionResult Index()
{
var model = new MyViewModel();
// the list of available values
model.Values = new[]
{
new SelectListItem { Value = "2", Text = "2", Selected = true },
new SelectListItem { Value = "3", Text = "3", Selected = true },
new SelectListItem { Value = "6", Text = "6", Selected = true }
};
return View(model);
}
Razor:
#Html.DropDownListFor(m => m.SelectedValues, Model.Values, new { multiple = "true" })
Submitted SelectedValues in controller looks like:
Though quite old thread but posting this answer after following other answers here, which unfortunately didn't work for me. So, for those who might have stumbled here recently or in near future, Below is what has worked for me.
This is what helped me
The catch for me was MultiSelectList class and I was using SelectList.
Don't know situation in 2012 or 2015. but, now both these helper methods #Html.DropDownListFor and #Html.ListBoxFor helper methods accept IEnumerable<SelectListItem> so you can not pass any random IEnumerable object and expect these helper methods to do the job.
These helper methods now also accept the object of SelectList and MultiSelectList classes in which you can pass the selected values directly while creating there objects.
For example see below code how i created my multi select drop down list.
#Html.DropDownListFor(model => #Model.arrSelectUsers, new MultiSelectList(Model.ListofUsersDTO, "Value", "Text", #Model.arrSelectUsers),
new
{
id = "_ddlUserList",
#class = "form-control multiselect-dropdown",
multiple = "true",
data_placeholder = "Select Users"
})

Categories

Resources