Binding DropDownList in Mvc and Get Selected Value - c#

my Model is
public class ChildMenu
{
public string Name { get; set; }
public string Comments { get; set; }
public List<UlrikenModel.ulriken_tblChildMenu> FormDetails { get; set; }
public long pkChildMenuID { get; set; }
public long fkSubMenuID { get; set; }
[Required(ErrorMessage = "Requird")]
public string ChildManuName { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
public string Events { get; set; }
public IList<SelectListItem> Drp_Submenu { get; set; }
}
My Controller action is :
public ActionResult FillDeptName()
{
UlrikenEntities db1 = new UlrikenModel.UlrikenEntities();
List<SelectListItem> list = new List<SelectListItem>();
list.Add(new SelectListItem { Text = "-Please select-", Value = "Selects
items" });
var cat = (from c in db1.ulriken_tblSubMenu where c.fkMainMenuID == 1 &&
c.Status == true select new { c.pkSubMenuID,c.SubManuName }).ToArray();
for (int i = 0; i < cat.Length; i++)
{
list.Add(new SelectListItem
{
Text = cat[i].SubManuName,
Value = cat[i].pkSubMenuID.ToString(),
Selected = (cat[i].pkSubMenuID == 1)
});
}
ViewBag.list = list;
return View("ChildMenuOfSubMenu", ViewBag.list);
}
[HttpPost]
[ValidateInput(false)]
public ActionResult ChildMenuOfSubMenu(ChildMenu obj)
{
UlrikenEntities db = new UlrikenEntities();
ulriken_tblChildMenu objchild = new ulriken_tblChildMenu();
objchild.fkSubMenuID = obj.fkSubMenuID;
objchild.ChildMenuName = obj.ChildManuName;
objchild.cPageBody = obj.Name;
db.ulriken_tblChildMenu.Add(objchild);
db.SaveChanges();
return View("ChildMenuOfSubMenu");
}
and view is
#Html.DropDownListFor(m=>m.fkSubMenuID,
(IEnumerable<SelectListItem>)ViewBag.list,"Select" ,new { id = "ddlSubMenu" })
At start dropdown bind successfully but after saving data to database show an exception in
as "There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key
'fkSubMenuID'"
AnyBody guide me where am i doing wrong.

Move that code to the helper class:
public class ControllerHelper
{
public List<SelectListItem> FetchListItems()
{
List<SelectListItem> list = new List<SelectListItem>();
list.Add(new SelectListItem { Text = "-Please select-", Value = "Selects items" });
var cat = (from c in db1.ulriken_tblSubMenu where c.fkMainMenuID == 1 &&
c.Status == true select new { c.pkSubMenuID,c.SubManuName }).ToArray();
for (int i = 0; i < cat.Length; i++)
{
list.Add(new SelectListItem
{
Text = cat[i].SubManuName,
Value = cat[i].pkSubMenuID.ToString(),
Selected = (cat[i].pkSubMenuID == 1)
});
}
return list;
}
}
And then your controller should looks like:
public ActionResult FillDeptName()
{
UlrikenEntities db1 = new UlrikenModel.UlrikenEntities();
ViewBag.list = new ControllerHelper().FetchListItems();
return View("ChildMenuOfSubMenu", ViewBag.list);
}
[HttpPost]
[ValidateInput(false)]
public ActionResult ChildMenuOfSubMenu(ChildMenu obj)
{
UlrikenEntities db = new UlrikenEntities();
ulriken_tblChildMenu objchild = new ulriken_tblChildMenu();
objchild.fkSubMenuID = obj.fkSubMenuID;
objchild.ChildMenuName = obj.ChildManuName;
objchild.cPageBody = obj.Name;
db.ulriken_tblChildMenu.Add(objchild);
db.SaveChanges();
ViewBag.list = new ControllerHelper().FetchListItems();
return View("ChildMenuOfSubMenu");
}
Of course:
new ControllerHelper().FetchListItems();
should be a field in the controller class, for example:
private ControllerHelper controlerHelper;
You can use Interface instead of concerete implementation, if you use DI.
Regards

Related

Create a generic List<SelectListItem> function

I have two DbSets:
public DbSet<Reports.Models.Application> Application { get; set; }
public DbSet<Reports.Models.Category> Category { get; set; }
In the controller, I'm creating two List<SelectListItem>s:
var applications = _context.Application
.Select(listItem => new SelectListItem
{
Value = listItem.ID,
Text = listItem.Name
}
).ToList();
var categories = _context.Category
.Select(listItem => new SelectListItem
{
Value = listItem.ID,
Text = listItem.Name
}
).ToList();
I'd like to refactor this into a single, private method:
private List<SelectListItem> SelectList<T>(bool blankListItem = false)
{
var selectListItems = _context.<T> <------ doesn't compile
.Select(listItem => new SelectListItem
{
Value = listItem.ID,
Text = listItem.Name
}
).ToList();
if (blankListItem)
selectListItems.Insert(0, (new SelectListItem { Text = $"Choose {{T.ToString}}", Value = "" }));
return selectListItems;
}
And call it twice:
var applications = SelectList<Application>();
var categories = SelectList<Category>();
or
var applications = SelectList<Application>(true); // add "choose"
var categories = SelectList<Category>(true); // add "choose"
What's the right way to define the _context.<T> part? Perhaps this should be an extension method of the DbSet instead?
Maybe you can have your dbsets inherit a base class. which would be representing the generic type T.
Something like;
public class BaseClassForDbSets
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Application : BaseClassForDbSets
{
}
public class Category : BaseClassForDbSets
{
}
and then your private method;
private IEnumerable<SelectListItem> GetSelectList<T>(IEnumerable<T> dataSource, bool blankListItem = false) where T : BaseClassForDbSets
{
var selectListItems = dataSource
.Select(listItem => new SelectListItem
{
Value = listItem.Id.ToString(),
Text = listItem.Name
}
).ToList();
if (blankListItem)
selectListItems.Insert(0, (new SelectListItem { Text = $"Choose {nameof(T)}", Value = "" }));
return selectListItems;
}
Then you would call it like;
var applicationCollection = GetSelectList(_context.Application);
var categoryCollection = GetSelectList(_context.Category);
Do note - not tested
My solution uses a different approach, but same result.
Start with an interface:
public interface IBaseSelectItem
{
int Id { get; set; }
string Name { get; set; }
}
Have your entities (Application and Category) implement the interface:
public partial class Category : IBaseSelectItem
{
public int Id { get; set; }
public string Name { get; set; }
}
Create an extension on DbSet:
public static IList<SelectListItem> AsSelectList<T>(this DbSet<T> dbSet, bool useChooseValueOption) where T : class, IBaseSelectItem
{
var selectList = dbSet
.Select(c => new SelectListItem { Value = c.Id.ToString(), Text = c.Name })
.ToList();
if (useChooseValueOption)
selectList.Insert(0, new SelectListItem { Value = "0", Text = "-Choose Value-" });
return selectList;
}
Then use like this:
var categoriesSelectList = _dbContext.Categories.AsSelectList();

How can I add another parameter to a drop down box?

At the moment I have a drop down box which only displays a Suppliers Name with the value of the ID hidden behind it. I would also like to display the Suppliers account number next to the Supplier Name.
HTML:
#Html.DropDownListFor(
m => m.SupplierID,
new SelectList(Model.Suppliers, "SupplierID", "SupplierName"),
new { #id = "SuppNameDD", #class = "GRDropDown" }
)
Controller:
public ActionResult Index(string client) {
int clientID = clientRepo.GetClientIDByName(client);
DashboardViewModel model = new DashboardViewModel();
model.ClientID = clientID;
model.ClientName = client;
model.FinancialsAtAGlance = reportRepo.GetFinancialsAtAGlance(model.ClientID);
model.SupplierID = -1;
model.AccountNo = null;
model.Suppliers = supplierRepo.GetAllSuppliersByClient(clientID);
model.ReviewID = -1;
model.AccountNo = null;
model.Reviews = reviewRepo.GetAllReviewsByClientID(clientID);
return View(model);
}
ViewModel:
public class DashboardViewModel {
public int ClientID { get; set; }
public string ClientName { get; set; }
public IQueryable<FinancialsAtAGlanceModel> FinancialsAtAGlance { get; set; }
public Dictionary<string, Dictionary<string, decimal?>> Budgets { get; set; }
public class SelectReport {
public int ReportID { get; set; }
public string ReportType { get; set; }
public static IEnumerable<SelectReport> Reports = new List<SelectReport> {
new SelectReport {
ReportID = 1,
ReportType = "Claims By Supplier"
},
new SelectReport {
ReportID = 2,
ReportType = "Department breakdown"
},
new SelectReport {
ReportID = 3,
ReportType = "Reason Code breakdown"
},
new SelectReport {
ReportID = 4,
ReportType = "Monthly Debiting report"
}
};
}
public List<SelectReport> allReports { get; set; }
public int SupplierID { get; set; }
public IEnumerable<Supplier> Suppliers { get; set; }
public int ReviewID { get; set; }
public string AccountNo { get; set; }
public IEnumerable<Review> Reviews { get; set; }
}
How can add this is as the other value is a selected value and this is not what I want. It should be another datatext field.
If this display name is something that would be used multiple times, I would suggest adding a property to your Supplier class. Something like DisplayName:
public class Supplier
{
//...
public string SupplierName { get; set; }
public string AccountNumber { get; set; }
//...
public string DisplayName
{
get { return String.Format("{0} ({1})", SupplierName, AccountNumber); }
}
}
Then, you just need to change your drop down list to use DisplayName instead of SupplierName as the text field:
#Html.DropDownListFor(m => m.SupplierID, new SelectList(Model.Suppliers, "SupplierID", "DisplayName"), new { #id = "SuppNameDD", #class = "GRDropDown" })
EDIT:
There is another way to do this that can be done all in the view:
#Html.DropDownListFor(m => m.SupplierID, Model.Suppliers.Select(item => new SelectListItem
{
Value = item.SupplierID.ToString(),
Text = String.Format("{0} ({1})", item.SupplierName, item.AccountNumber.ToString()),
Selected = item.SupplierID == Model.SupplierID
}))
Probably you can achieve your desired output by 1.create a custom helper with with extension method which will return MvcHtmlString which will create your custom HTML for dropdown and call that method in your view.
Like Below
public static class CustomDropdown
{
public static string Dropdown(Priority priority)
{
StringBuilder sb=new StringBuilder ();
sb+="<Select id='drop'>";
for(int i=0;i<priority.name.length;i++)
{
sb+="<option id='dropop' value='"+priority.value[i]+"'title='"+priority.title[i]+"'>"+priority.name[i]+"</option>";
}
sb+="</select>";
return Convert.ToString(sb);
}
}
2.Bind the options of the given select with help of jquery like
var i=0;
$('.drpclass option').each(function(){
$(this).attr('title',Model.priority.title[i])
i++;
});

Creating Drop down List for Create Action

I have Problem Creating Drop down List in the view for Create Action. The view just show field for Student Number, Title and description and nothing for the Program and category Drop-down list. I am not sure how to create SelectList and pass it to the view. I don't know if did it right.
public class ServiceForm
{
[Required]
[Display(Name="Student Number")]
public int student_number { get; set; }
[Required]
[Display(Name="Program")]
public SelectList program { get; set; }
[Required]
[Display(Name = "Title")]
public string title { get; set; }
[Required]
[Display(Name = "Description")]
public string description { get; set; }
[Required]
[Display(Name = "Category")]
public SelectList category { get; set; }
}
public class Program
{
public int id { get; set; }
public string program_code { get; set; }
public string program_desc { get; set; }
}
public IEnumerable<ProgramList> GetAllPrograms()
{
var s = ds.programs.OrderBy(m => m.program_code);
return AutoMapper.Mapper.Map<IEnumerable<ProgramList>>(s);
}
private ServiceManager m = new ServiceManager();
private ProgramManager pm = new ProgramManager();
[HttpGet]
public ActionResult Create()
{
ServiceForm form = new ServiceForm();
form.program = new SelectList(pm.GetAllPrograms(), "id", "program_code");
List<SelectListItem> cat = new List<SelectListItem>();
cat.Add(new SelectListItem() { Text = "General", Value = "General", Selected = true });
cat.Add(new SelectListItem() { Text = "Grades", Value = "Grades", Selected = false });
cat.Add(new SelectListItem() { Text = "Time Table", Value = "TimeTable", Selected = false });
cat.Add(new SelectListItem() { Text = "Zenit Account", Value = "Zenit", Selected = false });
form.program = new SelectList(cat, cat.ElementAt(0));
return View(form);
}
[HttpPost]
public ActionResult Create(ServiceAdd newService)
{
if (!ModelState.IsValid)
{
var reform = AutoMapper.Mapper.Map<ServiceForm>(newService);
reform.program = new SelectList(pm.GetAllPrograms(), "id", "program_code");
List<SelectListItem> cat = new List<SelectListItem>();
cat.Add(new SelectListItem() { Text = "General", Value = "General", Selected = true });
cat.Add(new SelectListItem() { Text = "Grades", Value = "Grades", Selected = false });
cat.Add(new SelectListItem() { Text = "Time Table", Value = "TimeTable", Selected = false });
cat.Add(new SelectListItem() { Text = "Zenit Account", Value = "Zenit", Selected = false });
reform.program = new SelectList(cat, cat.ElementAt(0));
return View(reform);
}
return RedirectToAction("Create");
}
Model
public class ServiceForm
{
[Required]
[Display(Name="Student Number")]
public int student_number { get; set; }
[Required]
[Display(Name="Program")]
public SelectList Programs { get; set; }
public string SelectedProgram { get; set; }
[Required]
[Display(Name = "Title")]
public string title { get; set; }
[Required]
[Display(Name = "Description")]
public string description { get; set; }
[Required]
[Display(Name = "Category")]
public SelectList Categories{ get; set; }
public string SelectedCategory { get; set; }
}
Controller
[HttpGet]
public ActionResult Create()
{
ServiceForm form = new ServiceForm();
List<SelectListItem> cat = new List<SelectListItem>();
cat.Add(new SelectListItem { Text = "General", Value = "General", Selected = true });
cat.Add(new SelectListItem { Text = "Grades", Value = "Grades", Selected = false });
cat.Add(new SelectListItem { Text = "Time Table", Value = "TimeTable", Selected = false });
cat.Add(new SelectListItem { Text = "Zenit Account", Value = "Zenit", Selected = false });
form.Categories = cat;
//fill Programs property here...
return View(form);
}
View
#model ServiceForm
#using(Html.BeginForm(...))
{
#Html.LabelFor(m=>m.Programs)
#Html.DropDownFor(x => x.SelectedProgram , Model.Programs)
#Html.LabelFor(m=>m.Categories)
#Html.DropDownFor(x => x.SelectedCategory, Model.Categories)
}
You can do something like this in your Controller:
public ActionResult Create()
{
var data = new ServiceForm();
data.Categories = new SelectList({"1", "category1"}, {"2", "category2"});
return View(data);
}
[HttpPost]
public ActionResult Create(ServiceForm form)
{
// validate the input and save
}
and in your Razor view you have something like this:
#model ServiceForm
#using(Html.BeginForm())
{
#Html.DropDownFor(x => x.SelectedCategory, Model.Categories)
<!-- ... other fields and labels -->
}

The ViewData item that has the key is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'

This is my model class:
public class EstimateModel:estimate
{
public string EstimateNo { get; set; }
//public SelectList Customer { get; set; }
//[DisplayName("Customer ID :")]
public int CustID { get; set; }
[DisplayName("Customer Name :")]
public string CustFname { get; set; }
[DisplayName("Company Name :")]
public string CompanyName { get; set; }
[DisplayName("Total:")]
public decimal total { get; set; }
[DisplayName("Tax1 :")]
public decimal tax1 { get; set; }
public decimal tax2 { get; set; }
public decimal tax3 { get; set; }
public decimal subtot { get; set; }
[DisplayName("Discount :")]
public decimal Discount { get; set; }
[DisplayName("GrandTotal:")]
public decimal grandtotal { get; set; }
public List<estimate> estimates { get; set; }
public EstimateModel()
{
estimates = new List<estimate>();
}
}
This is my controller code:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(EstimateModel employee)
{
//employee.Customer= new SelectList("CustID","CustFName");
DataTable dt = new DataTable();
//for (int i = 0; i < employee.estimates.Count; i++)
//{
// total = total + employee.estimates[i].Amount;
//} ViewBag.Message = total;
//Skill abc = new Skill();
var sys = db.EstimateMasters.Create();
// var user = db.Adils.Create();
sys.EstimateNo = employee.EstimateNo;
for(int i=0 ;i<employee.estimates.Count;i++)
{
sys.EstimateNo = employee.EstimateNo;
sys.CustID = employee.CustID;
sys.ProductName = employee.estimates[i].ProductName;
sys.Quantity = employee.estimates[i].Quantity;
sys.Price = employee.estimates[i].Price;
sys.Amount = employee.estimates[i].Amount;
sys.Total=employee.total;
sys.Tax1=employee.tax1;
sys.Tax2 = employee.tax2;
sys.Tax3 = employee.tax3;
sys.Discount = employee.Discount;
sys.SubTotal = employee.subtot;
sys.GrandTotal = employee.grandtotal;
db.EstimateMasters.Add(sys);
db.SaveChanges();
}
This is my view code:
<div> #Html.LabelFor(m =>m.CustID)
#Html.DropDownList("CustID", "---Select---")
</div>
</div>
<div>
#Html.LabelFor(m => m.CustFname)
#Html.TextBoxFor(m =>m.CustFname)
#Html.LabelFor(m=>m.CompanyName)
#Html.TextBoxFor(m =>m.CompanyName)
</div>
I am getting this error on DropDownList: The ViewData item that has the key 'CustID' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'. Can anyone help me?
You have to pass list to dropdown but here you are passing CustID and that is Integer. This is causing error.
Try following code:
1) Create a list with your items.
#{
List<SelectListItem> CustIDlistItems= new List<SelectListItem>();
CustIDlistItems.Add(new SelectListItem
{
Text = "text1",
Value = "value1"
});
CustIDlistItems.Add(new SelectListItem
{
Text = "text2",
Value = "value2",
Selected = true
});
CustIDlistItems.Add(new SelectListItem
{
Text = "text3",
Value = "value3"
});
}
2) Pass newly created list to view with list as a parameter.
#Html.DropDownListFor(model => model.Yourproperty, CustIDlistItems, "-- Select Status --")
Hope this will help you..!
EDIT :
You can utilize following example for creating dynamic list from database.
public IEnumerable<SelectListItem> GetTrainingSubjectsList(int selectedValue)
{
List<SelectListItem> TrainingSubjectsList = new List<SelectListItem>();
TrainingSubjectsList.Add(new SelectListItem() { Selected = true, Text = "Select Subject", Value = "" });
var TrainingSubjects = (from subjects in _context.TrainingDetails.Where(c => c.IsDeleted == false)
select subjects).ToList();
foreach (TrainingDetail TrainingDetail in TrainingSubjects)
{
SelectListItem Item = new SelectListItem();
Item.Text = TrainingDetail.Title;
Item.Value = TrainingDetail.TrainingDetailId.ToString();
if (selectedValue == TrainingDetail.TrainingDetailId)
{
Item.Selected = true;
}
TrainingSubjectsList.Add(Item);
}
return TrainingSubjectsList;
}

How to create Object for Class in Asp.net MVC

I have class
public class TabMasterViewModel : ITabMasterModel
{
[ReadOnly(true)]
public int colID { get; set; }
[DisplayName("FirstName")]
public string FirstName { get; set; }
[DisplayName("LastName")]
public string LastName { get; set; }
}
Now i want to delete following three records from database
[HttpPost]
public ActionResult RemoveSelected(IList<TabMasterViewModel> TabMasters)
{
IList<TabMasterViewModel> TabMasters = new IList<TabMasterViewModel>; //this line is giving me an ERROR..
List<string> dinosaurs = new List<string>();
int[] colIDs = { 1034, 1035, 1036 };
foreach (int colid in colIDs)
{
//TabMasters.Add(new TabMasterViewModel { colID = colid });
TabMasterViewModel tvm = new TabMasterViewModel { colID = colid };
TabMasters.Add(tvm);
//_tabmasterService.Delete(tvm);
}
_tabmasterService.DeleteList(TabMasters);
//return View(_tabmasterService.GetAll(x => (x.colID == 1034 || x.colID == 1035 || x.colID == 1036)));
return RedirectToAction("Index");
}
but i am not abel to write proper for
IList<TabMasterViewModel> TabMasters = new IList<TabMasterViewModel>
IList<TabMasterViewModel> TabMasters = new List<TabMasterViewModel>();
IList<> is an interface and cannot be instantiated.

Categories