Creating Drop down List for Create Action - c#

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

Related

How to determine whether a model is valid?

I am having some trouble here. The situation is to update an existing record, at the same time, save a new row if there is no record by searching first the table.
When I am saving a new record, there is no problem. But when I'm trying to update an existing one, there are no changes. I tried to place some breakpoints specifically on the code that do the thing. It just ending up on the line if(!ModelState.IsValid).
Note:
Some of the lines are hard-coded for the sake of having some dummy data.
Function for retrieving some data from DB to pass to view model
[HttpGet]
public ActionResult CardNumberAssignment(string empId, int cardNumberId)
{
var getIdDetails = dbContext.CardNumberAssignments.Where(c => c.CardNumberId == cardNumberId && c.IsActive == true).SingleOrDefault();
if (cardNumberId == 0) //EMPLOYEE HAS NO CARD NUMBER YET
{
var viewModel = new CardNumberQRCodeVM
{
CardNumberId = 0,
CMId = empId,
OldQRCode = "No QR Code history",
OldReservedCardNumber = "No Card Number history",
NewReservedCardNumber = GetRandomCardNumber()
};
return View(viewModel);
}
else
{
if (getIdDetails.CMId != empId) //JUST CHECKING IF THE EMPLOYEE HAS THE CORRECT CARDNUMBERID FROM DB
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var empCardDetails = dbContext.CardNumberAssignments
.Include(c => c.ReservedCardNumber)
.Where(emp => emp.CMId == empId && emp.IsActive == true)
.Select(fields => new CardNumberQRCodeVM
{
CardNumberId = fields.CardNumberId,
CMId = empId,
OldQRCode = fields.QRCode,
IsActive = fields.IsActive,
OldReservedCardNumber = fields.ReservedCardNumber.CardNumber,
}).FirstOrDefault();
empCardDetails.NewReservedCardNumber = GetRandomCardNumber();
return View(empCardDetails);
}
}
Function for adding/editing record
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SaveIdInformation(CardNumberQRCodeVM vm)
{
if (!ModelState.IsValid)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
// JUST ADDING/EDITING SOME CARD NUMBERS....
else
{
if (vm.CardNumberId == 0) //INSERT A NEW ROW FOR NEW CARD NUMBER AND QR CODE
{
var newCardNumber = new ReservedCardNumber
{
CardNumber = vm.NewReservedCardNumber,
IsActive = true,
CreatedDate = DateTime.Now,
CreatedBy = "Paolo",
ModifiedDate = DateTime.Now,
ModifiedBy = "Paolo"
};
dbContext.ReservedCardNumbers.Add(newCardNumber);
var newIdInfo = new CardNumberAssignment
{
CardNumberId = newCardNumber.Id,
QRCode = vm.NewQRCode,
CMId = vm.CMId,
IsActive = true,
CreatedDate = DateTime.Now,
CreatedBy = "Paolo",
ModifiedDate = DateTime.Now,
ModifiedBy = "Paolo"
};
dbContext.CardNumberAssignments.Add(newIdInfo);
}
else // EDIT EXISTING
{
var getEmployeeIdInDb = dbContext.CardNumberAssignments.Single(e => e.Id == vm.CardNumberId);
getEmployeeIdInDb.ReservedCardNumber.CardNumber = vm.NewReservedCardNumber;
getEmployeeIdInDb.QRCode = vm.NewQRCode;
getEmployeeIdInDb.IsActive = true;
getEmployeeIdInDb.ModifiedDate = DateTime.Now;
getEmployeeIdInDb.ModifiedBy = "Paolo";
}
dbContext.SaveChanges();
}
return RedirectToAction("CMDetails", "Admin", new { #empId = vm.CMId });
}
View model
public class CardNumberQRCodeVM
{
public int CardNumberId { get; set; }
public string CMId { get; set; }
[Display(Name = "Existing QR Code")]
public string OldQRCode { get; set; }
[Required]
[Display(Name = "New QR Code")]
public string NewQRCode { get; set; }
[Display(Name = "Resigned Cast Member?")]
public bool IsActive { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
public string ModifiedBy { get; set; }
public DateTime ModifiedDate { get; set; }
public ReservedCardNumber ReservedCardNumber { get; set; }
[Display(Name = "Old Card Number")]
public string OldReservedCardNumber { get; set; }
[Display(Name = "New Card Number")]
public string NewReservedCardNumber { get; set; }
}

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

Binding DropDownList in Mvc and Get Selected Value

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

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

Html.ListBoxFor not selecting Items

Firstly I'm using MVC 2.0. I am having trouble getting a selection with a Multiselect listbox on the postback to my controller. Here is my Code:
Model
public class TestModel
{
public MultiSelectList AvailableTestTypes { get; set; }
public List<TestType> SelectedTestTypes { get; set; }
}
public class TestType
{
public long Id { get; set; }
public string Name { get; set; }
public bool isActive { get; set; }
}
Controller
public ActionResult Index(TestModel model)
{
if (model == null) model = new TestModel();
List<TestType> testList = new List<TestType>()
{
new TestType() { Id = 1, Name = "TESTING", isActive = true },
new TestType() { Id = 2, Name = "TESTING2", isActive = true },
new TestType() { Id = 3, Name = "TESTING3", isActive = true }
};
model.AvailableTestTypes = testList; //TODO: Fetch From Repository
return View(model);
}
[HttpPost]
public ActionResult PostForm(TestModel model)
{
List<long> act = model.SelectedTestTypes != null ? model.SelectedTestTypes.Select(x => x.Id).ToList() : new List<long>();
View
<%= Model != null && Model.AvailableTestTypes != null ?
Html.ListBoxFor(x => x.SelectedTestTypes,
new MultiSelectList(Model.AvailableTestTypes, "Id", "Name", Model.SelectedTestTypes),
new { #id = "testListboxId", #class = "blah", #title = "title" }) : null%>
After the Post to the Controller my Selected List count is 0 no matter how many I choose...
What am I getting wrong here?
I tried a few different solutions such as
Challenges with selecting values in ListBoxFor
but nothing worked :(
The difference between your script and the example in the other script, is the fact that you're trying to bind to a List, instead of a int[].
When you want to populate a Multiselect Listbox, you will have to set a DataValueField and a DataTextfield, otherwise no value is set.
model.AvailableTestTypes = new MultiSelectList(testList, "Id", "Name);
Then try using this class:
public class TestModel
{
public MultiSelectList AvailableTestTypes { get; set; }
public int[] SelectedTestTypes { get; set; }
}
In your PostForm action, you can use the Ids to retrieve the TestTypes.

Categories