ASP.NET mvc : populate (bind data) in listbox - c#

I need to populate two listboxes with data from a database.
But I need to display two listboxes in one view, so I created a ListBoxModel class.
public class ListboxModel
{
public ListBox LB1 { get; set; }
public ListBox LB2 { get; set; }
}
And in my Controller:
public ActionResult IndexStudents(Docent docent, int lessonid, int classid)
{
var MyListBox = new ListboxModel
{
LB1 = new ListBox(docent.ReturnStudentsNormal(lessonid, classid),
LB2 = new ListBox(docent.ReturnStudentsNoClass(lessonid, classid)
};
return View(MyListBox);
}
But this code does not work, how can I bind the data to the listboxes?
So I'd like to use 2 models, one for each listbox... one with normal students and one with students who are not subscribed for lessons.
How could I do that?
And what code do I have to write in my view?
Something like:
<div class="editor-field">
<%: Html.ListBox("IndexStudentsNormal", Model.LB1) %>
<div class="editor-field">
<%: Html.ListBox("IndexStudentsNoClass", Model.LB2) %>
The listbox has to be a listbox with multiple colums so that it can contain the name, sirname, class, teacher of the student.
Student is an object, I'd like to display student.Name, student.Sirname, student.Class, and so on in that listbox.
So can I use an object in a ListBox, or do I have to convert everything to strings?
How can I do that?
Thanks in advance!

The model shouldn't contain a ListBox, it should just contain the lists of students. The trick is to keep the Model as simple as possible, it should really only be a bunch of property getters and setters. The view is responsible for binding a Model's properties to HTML elements.
Model:
public class StudentModel
{
public IList<string> NormalStudents {get;set;}
public IList<string> NoClassStudents {get;set;}
}
Controller:
public ActionResult IndexStudents(Docent docent, int lessonid, int classid)
{
var studentModel = new ListboxModel
{
NormalStudents = docent.ReturnStudentsNormal(lessonid, classid),
NoClassStudents = docent.ReturnStudentsNoClass(lessonid, classid)
};
return View(studentModel);
}
View:
<div class="editor-field">
<%: Html.ListBox("IndexStudentsNormal", Model.NormalStudents) %>
</div>
<div class="editor-field">
<%: Html.ListBox("IndexStudentsNoClass", Model.NoClassStudents) %>
</div>

Based on Jason's answer, the first line in your view should include:
<%# Inherits="System.Web.Mvc.ViewPage<StudentModel>" %>
This tells your view that "Model" is of type StudentModel. If there's other bits in this first line (Title, Language, MasterPageFile, etc), they're fine to stay there.
-- edit: add longish comments --
The thing to remember is that a SelectListItem has three required parts: Value, Text, and Selected. Value is the key, so something like StudentId or DocentId. Text is displayed in the list, so something like StudentName or DocentName. Selected indicates whether this item is selected in the list, typically false.
Right now it looks like you have methods that only return a list of the student names (Docent.ReturnStudentsNormal() and Docent.ReturnStudentsNoClass()). I would have these methods return a list of key-value pairs, key being StudentId and value being StudentName.
Then you can change your model class to be
public class StudentModel
{
List<SelectListItem> NormalStudents;
List<SelectListItem> StudentsNoClass;
}
and in your controller
public ActionResult IndexStudents(Docent docent, int lessonId, int classId)
{
var studentModel = new StudentModel();
var normalStudents = docent.ReturnStudentsNormal(lessonId, classId);
foreach (var student in normalStudents)
{
studentModel.NormalStudents.Add(new SelectListItem() {Value = student.Key, Text = student.Value});
}
var studentsNoClass = docent.ReturnStudentsNormal(lessonId, classId);
foreach (var student in studentsNoClass)
{
studentModel.StudentsNoClass.Add(new SelectListItem() {Value = student.Key, Text = student.Value});
}
return View(studentModel);
}
Now you'll be able to use these properties on your model directly for Html.ListBox().

Related

How to pass the value to drop down fields in edit mode in MVC4?

Hi i have three Fields in my view.That three fields are drop down. I want to pass the value to these fields when edit button is clicked. That is the values need to pass to that drop down fields. My view is mentioned below
In my view i have many drop downs but once i know how to pass the value to one drop down means i will do for another drop downs.
For Edit i create one view in sql and connect that view as EDMX file in my application.In this view(table) i have all fields which is in Visitors Form. That view name is View_VisitorsForm.
My Model(VisitorsViewModel)
public Nullable<System.DateTime> Date { get; set; }
public System.Guid VisitingID { get; set; }
public Nullable<System.Guid> EmployeeID { get; set; }
public string EmployeeName { get; set; }
public string Description { get; set; }
My Edit Code
public ActionResult Edit(Guid ?id)
{
WafeERPNEWEntities db = new WafeERPNEWEntities();
SelectList typelist = new SelectList(db.Employees.ToList(), "EmployeeID", "DisplayName", db.Employees);
ViewData["EmployeeName"] = typelist;
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
VisitorsViewModel ObjVisitorsviewModel = new VisitorsViewModel();
View_VisitorsForm visit = db.View_VisitorsForm.Find(id);
visit.VisitingID = ObjVisitorsviewModel.VisitingID;
visit.VisitingDate = ObjVisitorsviewModel.Date;
visit.Description = ObjVisitorsviewModel.Description;
if (ObjVisitorsviewModel == null)
{
return HttpNotFound();
}
return View(ObjVisitorsviewModel);
}
My View Code
#Html.LabelFor(model => model.Date)
#Html.EditorFor(model => model.Date)
#Html.ValidationMessageFor(model => model.Date)
#Html.LabelFor(model => model.VisitingID)
#Html.EditorFor(model => model.VisitingID)
#Html.ValidationMessageFor(model => model.VisitingID)
#Html.LabelFor(model => model.EmployeeName)
#Html.DropDownList("EmployeeID", (IEnumerable<SelectListItem>)ViewData["EmployeeName"])
#Html.ValidationMessageFor(model => model.EmployeeName)
Now when i click the edit button it pass the value to this line
View_VisitorsForm visit = db.View_VisitorsForm.Find(id);
and also it getting visit.visitingID. But it is not getting the value in viewmodel .so the value will be empty in view.All values are empty VisitingID, Description, Date Fields are empty and in Employee drop down it won't show the value which i passed to this field it shows the first value in dropdown. so please any one tell me how to solve this issue. Actually I try to explain my issue as per my level best and if you didn't understand my issue or any one need my full code or need more code tell me . i ready to update my code again. but i need solution.
Advance Thanks..
use:
#Html.DropDownListFor(model => model.EmployeeID,(IEnumerable<SelectListItem>)ViewData["EmployeeName"])
The important part being "DropDownListFor". You are using "DropDownList".
Use the DropDownListFor helper method.
#Html.DropDownListFor(model => model.EmployeeID,
(IEnumerable<SelectListItem>)ViewData["EmployeeName"])
Now in your GET action, you need to set the EmployeeID property value of your view model.
public ActionResult Edit(int id)
{
var objVisitorsviewModel = new VisitorsViewModel();
// I am hard coding to 25.
// You may replace it with a valid Employee Id from your db table for the record
ObjVisitorsviewModel.EmployeeID= 25;
return View(objVisitorsviewModel);
}
A more clean solution is to not use ViewData to transfer the data you need to render the dropdown option. You can make your code more strongly typed by simply adding a new property to your view model
public class VisitorsViewModel
{
public List<SelectListItem> Employees { set;get;}
public Guid? EmployeeID { get; set; }
// Your existing properties goes here
}
Now in your GET action(create/edit), Instead of storing the data in ViewData, we will load to the Empenter code hereloyees property.
public ActionResult Edit(int id)
{
var vm = new VisitorsViewModel();
vm.Employees = db.Employees.Select(s=> new SelectListItem {
Value=s.EmployeId.ToString(), Text=s.DisplayName }).ToList();
return View(vm);
}
And in your view, we will use the DropDownListFor helper method with the Employees property
#model VisitorsViewModel
#using(Html.BeginForm())
{
#Html.DropDownListFor(s=>s.EmployeeID,Model.Employees,"Select")
}
You are using a DropDownList(...) instead of a DropDownListFor(...)
Your Model
You must add a SelectList:
public SelectList Employees { get; set }
Your Edit
You must get your employees list and add it to your model:
// Get employees list from the database
var employees = db.Employee.Select(x => x.Id, x.Name).Tolist();
// Put the employees in a SelectList
var selectList = new SelectList(employees .Select(x => new { value = x.Id, text = x.Name }), "value", "text");}).ToList();
// Pass the list to your ViewModel
ObjVisitorsviewModel.Employees = selectList;
Your View
Finally, change your DropDownListFor line for this:
#Html.DropDownListFor(model => model.EmployeeID,
model.Employees)
By using DropDownList(...), your object data is not bound to the DropDown. You must manage its selected value manually.

Making multiple models cast an ID using Entity Framework

I am new to using the Entity Framework. I have added my Model, and I need to use two my models/tables in one View Page. So to do that I added this to my AccountViewModels.cs page:
public class category_menuitem
{
public Category Category { get; set; }
public MenuItem MenuItem { get; set; }
}
I am trying to use Values from those two Models/Tables.
My View Page:
using System.Data.SqlClient
#model IEnumerable<YourGoGetterV1.Models.category_menuitem>
#{
ViewBag.Title = "Show Menu" - ViewBag.restaurant_id;
}
<h2>ShowMenu</h2>
<div class="jumbotron">
#foreach (var item in Model)
{
<div><strong>#Html.DisplayFor(item1 => item.Category.Name)</strong>
<div>#Html.DisplayFor(item1 => item.Category.Description)</div>
#{
using (var context = new YourGoGetterContext())
{
SqlParameter sa = new SqlParameter("#p0", ViewBag.restaurant_id);
var menu_items = context.MenuItems.SqlQuery("Select * FROM MenuItems where restaurant_id = #p0", sa).ToList();
var test = "DID IT WORK??";
}
}
</div>
}
</div>
Controller:
public ActionResult ShowMenu(string id, int restaurant_id)
{
ViewBag.Id = id;
ViewBag.restaurant_id = restaurant_id;
return View(Models.category_menuitem.ToList((object(id)));
}
I want to cast the ID, so that it creates a different URL for something that passes in a different ID. But I'm having two problems.
1) I can't even put in the Models.Category_menuitem.ToList() because "No overload for method 'ToList' takes 1 arguments"
2)The Models.Category_menuitem does not contain a definition for ToList.
What do I do?
I think you should do it different. The model should contain the data you use in the view. So do your db requests in the model and give the model to the view to display the data in it. Don't do SQL requests in the view. You also should write classnames always in capital letters because of C# naming conventions.
If I understand it right you want to display a menubar or something like that with categories and each category has many menuitems?
Just create a model menuitems like this:
public class MenuItems {
public List<Category> Categories{get;set;}
}
and a model Category like this:
public class Category {
public string CategoryName {get;set;}
public List<MenuItem> MenuItems {get;set;}
}
Fill the models with data and give the MenuItems Model to the view. In the view you can do something like:
#foreach (var category in Model.Categories)
{
foreach (var menuItem in category.MenuItems)
{
}
}
I hope this helps ;)
To this part of your code:
var menu_items = context.MenuItems.SqlQuery("Select * FROM MenuItems where restaurant_id = #p0", sa).ToList();
I am not sure what you wanna do. You are querying the db for data which should be already in the model or am I wrong? But if you want to use EF you would write:
var items = context.Menuitems.Where(m => m.restaurant_id == id).ToList();

How to send non model fields back to action form view

I have a view that has a model with a list of items I build as check box values. How can I post those values back to the action with the model? The problem is that there is not a concrete amount f check boxes, and they are sometimes unknown what the value will be. There could be 2 or there could be 15 depending on the user. but are built from the model's list values. Thanks in advance
You can use editor templates.
Assume, your view/page is to assign courses to students. So you will have a viewmodel like this
public class AssignCourseVM
{
public int StudentID { set;get;}
public string StudentName { set;get;}
public List<CourseRegistration> Courses { set;get;}
public AssignCourseVM()
{
Courses =new List<CourseRegistration>();
}
}
public class CourseRegistration
{
public int CourseID { set;get;}
public string CourseName { set;get;}
public bool IsRegistered { set;get;}
}
Now in your GET action, You will create an object of your viewmodel and send to the view
public ActionResult Registration()
{
var vm = new AssignCourseVM();
//Student Info is hard coded. You may get it from db
vm.StudentID = 1;
vm.StudentName = "Scott";
vm.Courses = GetCourseRegistations();
return View(vm);
}
public List<CourseRegistration> GetCourseRegistations()
{
var list = new List<CourseRegistration>();
//Hard coded for demo. You may load this list from DB
list.Add(new CourseRegistration { CourseID = 1, CourseName = "EN" });
list.Add(new CourseRegistration { CourseID = 2, CourseName = "GE" });
return list;
}
Now Let's create an Editor Template, Go to The View/YourControllerName and Create a Folder called EditorTemplates and Create a new View there with the same name as of the Property type (CourseRegistration.cshtml).
Now inside this new file, paste this content
#model ReplaceYourProjectNameSpaceHere.ViewModels.CourseRegistration
<div>
#Model.CourseName : #Html.CheckBoxFor(s=>s.IsRegistered)
#Html.HiddenFor(s => s.CourseID)
</div>
Now in our main view (Registration.cshtml) which is strongly typed to our AssignCourseVM class, we will use Html.EditorFor helper method.
#model ReplaceYourProjectNameSpaceHere.ViewModels.AssignCourseVM
<h2>Registration</h2>
#using(Html.BeginForm())
{
<h4>#Model.StudentName</h4>
#Html.EditorFor(s=>s.Courses)
#Html.HiddenFor(s=>s.StudentID)
<input type="submit" />
}
Now when user posts the form, You can inspect the posted viewmodel's course property to see which items are checked or not.
[HttpPost]
public ActionResult Registration(AssignCourseVM model)
{
//to do :save and redirect
return RedirectToAction("RegistrationSuccessfull");
}

How to add values to dropdown in MVC3?

I want to add a dropdownlist in my form, with 2 values userid and username in my dropdownlist, and also I want to get the value selected by the user when I click the button. I'm new to MVC and so far, I have not worked on dropdownlist, tried few samples but nothing seems to be working the way I want.
I'll jump lots of MVC3 concepts. If you're really new to ASP.NET MVC, you should take a look at some tutorials.
This code should help you:
VIEW
#using (Html.BeginForm("ACTION NAME", "CONTROLLER NAME"))
{
<select name="select">
<option value="username" selected>User name</option>
<option value="userid">User id</option>
</select>
<input type="submit" />
}
ACTION
[HttpPost]
public ActionResult ACTIONNAME(string select)
{
//...
}
Please, note:
ACTION NAME and CONTROLLER NAME at the BeginForm helper. You will have to modify this at your code
The select name ("select") and the name of the argument at the action ("select"). This is not a coincidence, it's a convention. MVC uses the name attr to bind data
The selected attribute at the option will make it the default option
Regards
See one of the ways you can do it is send the list in a model property as the binding and for the value you can bind it to another property like :
public class YourModel
{
public List<UserList> OptionList { get; set; }
public String YourValue{get;set;}
}
public class UserList
{
public String UserName{get;set;}
public String UserId{get;set;}
}
#Html.DropDownListFor(model => model.YourValue, Model.OptionList, "")
In the helper there are overided options which are used to specify the value and text.
And Remember :
This is StackOverflow.
Even the Not working example which you have tried are important for the ones who try to help you since they are spending their precious bandwidths for u.
You don't need create a new model class for each view, just put this on controller:
ViewBag.FieldName = new SelectList(new List<SelectListItem>() {
new SelectListItem { Value = "userid", Text = "User ID" },
new SelectListItem { Value = "username", Text = "User name" }
});
And this on view:
#Html.DropDownList("FieldName")
You need to create a collection of SelectListItem like:
IEnumerable<SelectListItem> selectList =
from c in areaListResponse.Item
select new SelectListItem
{
Text = c.AreaName,
Value = c.Id.ToString()
};
Pass this selectList to your view:
return View(selectList);
In your cshtml:
#model IEnumerable<SelectListItem>
#Html.DropDownListFor(m => m.RequestAreaName, Model)
If you need complecated object, you may need a wrapper class like:
public class RaiseRequestModelWrapper
{
public IEnumerable<SelectListItem> GetModel { get; set; }
public RaiseRequestModel PostModel { get; set; }
}

How can I get multiple selections from ASP.NET CheckBoxs

This seems like it should be prettty easy - but I just can't get it to work!
I have an enum in my model, which I want to display as a list of checkboxes. The user can select multiple checkboxes, and I want to save this in the database.
So the enum is like so (approx 20 elements unabridged):
public enum ReferrerType
{
[Description("No Data")]
NoData = 9999,
[Description("Father or Mother")]
Parents = 1,
[Description("Brother or Sister")]
Sibling = 2,
[Description("Other")]
Other = 10
}
Whereby the Description is what is shown on the UI, and the numeric value is what is to be saved in the database. The numbers have to remain as listed, as they go directly into a stats package.
I then defined a Referrer class:
public class Referrer
{
public virtual Guid Id { get; private set; }
public virtual ReferrerType{ get; set; }
}
I realise this might be an odd (anti)pattern. I developed it in haste, and am repenting at leisure. Any advice on improving this model would also be much appreciated!
My controller sets up the list:
private static IList<string> GenerateReferrerList()
{
var values = from ReferrerType e in Enum.GetValues(typeof(ReferrerType))
select new { Name = e.ToDescription() };
return values.Select(x => x.Name).ToList();
}
And I use it in my View like this:
<div class="radio-boolean form-field" id="Referrers">
<p class="form-field-attribute"> <span class="label">Referred By </span> </p>
<% for (var i = 0; i < ((IList<string>)ViewData["ReferrerList"]).Count; i++)
{ %>
<p class="form-field-value">
<%= Html.CheckBox(string.Format("Referrers[{0}].Type", i) ) %>
<label for="Referrers"> <%= ((IList<string>)ViewData["ReferrerList"])[i]%></label>
</p>
</div>
And it doesn't work! I guess I'm missing something obvious, but I can't work out what. There are no errors - just an empty database table where referrers should be...
As always, any help much appreciated!
Let's take a moment and see what do we need here. We need to show a form which will contain multiple checkboxes (one for each value of the enum) and an associated label (this label should come from the Description attribute use on the enum). When this form is submitted we want to fetch all the values that the use has checked.
So as always once we have clear definition of what we are trying to do we introduce our view model:
public class MyViewModel
{
public bool IsChecked { get; set; }
public ReferrerType ReferrerType { get; set; }
public string Text { get; set; }
}
Then we write a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = Enum.GetValues(typeof(ReferrerType)).Cast<ReferrerType>().Select(x => new MyViewModel
{
ReferrerType = x,
Text = x.ToDescription() // I guess that's an extension method you wrote
});
return View(model);
}
[HttpPost]
public ActionResult Index(IEnumerable<MyViewModel> model)
{
...
}
}
And finally a strongly typed view corresponding to the Index action of our controller (~/Views/Home/Index.aspx):
<% using (Html.BeginForm()) { %>
#Html.EditorForModel()
<input type="submit" value="OK" />
<% } %>
and the last part is the corresponding editor template (~/Views/Home/EditorTemplates/MyViewModel.ascx):
<%# Control
Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<AppName.Models.MyViewModel>" %>
<%= Html.CheckBoxFor(x => x.IsChecked) %>
<%= Html.HiddenFor(x => x.ReferrerType) %>
<label><%: Model.Text %></label>
Now when this form is submitted inside the POST index action you would get a list of all enums with a corresponding boolean value indicating whether the user checked it or not.
OT: Don't perform excess actions:
return (from e in Enum.GetValues(typeof(ReferrerType))
select e.ToDescription()).ToList();
or just
return Enum.GetValues(typeof(ReferrerType)).Select(e => e.ToDescription()).ToList();

Categories

Resources