create CheckboxFor from List in View Model - asp.net-mvc-4

My View Model Class is
public class StudentQuestions
{
public int StudentId{ get; set; }
public int FormId { get; set; }
public virtual ICollection<Questions> Question { get; set; }
}
and question class is
public partial class Questions
{
public int questionID { get; set; }
public string field_name { get; set; }
public string question { get; set; }
public int qutyp_refID {get,set}
public string description { get; set; }
public int ord { get; set; }
public bool IsEnabled { get; set;}
public virtual ICollection<Answers> Answers { get; set; }
}
in my view
#model Test.ViewModels.StudentQuestions
<table>
<tr><td>#Model.FormId</td><td>#Model.StudentId</td></tr>
#foreach(var q in Model.Question)
{
<tr>
<td> #Html.CheckBoxForFor(i=> i.Question.question)</td>
</tr>
}
</table>
I cant access i.Question.question but I can access in CheckBox, TextBox like following and I want to change Textbox to TextBoxFor and CheckBox to CheckBoxFor and TextBox to TextBoxFor
#foreach(var q in Model.Question)
{
<tr>
#if (#q.qutyp_refID == 4)
{
<td>#Html.CheckBox(q.questionID.ToString())
</td>
}
else if (#q.qutyp_refID <= 2)
{
<td>#Html.TextBox("txtDateQuestions", DateTime.Today.ToString("dd/MM/yyyy"), new { style = "width: 120px" }) </td>
}
else
{
<td>#Html.TextBox(q.questionID.ToString(), null)</td>
}
</tr>
}
Thanks in Advance.........

Try like this,
#Html.CheckBoxFor(i => m.questionID, new { id = #m.questionID, #checked = "checked", Name = "CheckBox" })<span>m.description</span>
Example
Model
public class AssignProject
{
public Guid Id { get; set; }
public string EmployeesName { get; set; }
public Guid? EmployeeId { get; set; }
public Guid? ProjectId { get; set; }
public string AssignEmployeeId { get; set; }
public bool IsChecked { get; set; }
}
View
#foreach (var item in Model)
{
#Html.CheckBoxFor(m => item.IsChecked, new { value = item.EmployeeId, id = "chk_" + #item.EmployeeId, #checked = "checked", Name = "CheckBox" })
}

Related

Why is my Viewmodel that I am returning to my POST method in MVC returning a null ViewModel

I really thought I understood what I was doing, but here goes. I decided I need more properties in my View so I created a ViewModel called ViewDataset and replaced the original Dataset model in the View. On my HttpGet TestDataset the View Model is populated correctly with data from the Viewmodel:
My original dataset that was working is below:
public class Dataset
{
public int Dataset_ID { get; set; }
public int Category_ID { get; set; }
public string Provider { get; set; }
public string Name { get; set; }
public string Institution { get; set; }
public string Description { get; set; }
public string Location { get; set; }
public bool Domestic { get; set; }
public bool International { get; set; }
public bool Includes_PHI { get; set; }
public bool PHI_Limited { get; set; }
public bool Includes_PIL { get; set; }
public bool PIL_Limited { get; set; }
public bool Citation_Requirements { get; set; }
public string Citation_Comments { get; set; }
public Nullable<System.DateTime> Availability_Beg_DT { get; set; }
public Nullable<System.DateTime> Availability_End_DT { get; set; }
public bool Subscription_Renewal { get; set; }
public Nullable<System.DateTime> Subscription_Renewal_DT { get; set; }
public bool Retention_Expiry { get; set; }
public Nullable<System.DateTime> Retention_Expiry_DT { get; set; }
public bool Data_Destruction { get; set; }
public Nullable<System.DateTime> Data_Destruction_DT { get; set; }
public string Data_Destruction_Instructions { get; set; }
public Nullable<int> Contract_ID { get; set; }
public bool Draft_Status { get; set; }
public bool Admin_Only { get; set; }
public string Dataset_Alias { get; set; }
public bool Loc_Amazon { get; set; }
public bool Loc_IT_Research { get; set; }
public bool Loc_Research_Proj { get; set; }
public bool Loc_Secure_Data { get; set; }
public bool Loc_Mercury { get; set; }
public bool Loc_Research_CC { get; set; }
public bool Loc_Research_VM { get; set; }
public bool Loc_External { get; set; }
public bool Access_Url { get; set; }
public bool Access_Download_App { get; set; }
public bool Access_Lab_Terminal { get; set; }
public bool Access_Email_Req { get; set; }
public bool Access_File_Download { get; set; }
public bool Access_Other { get; set; }
public string Location_Notes { get; set; }
public string Access_Notes { get; set; }
public Nullable<System.DateTime> Date_Added { get; set; }
public Nullable<System.DateTime> Date_Modified { get; set; }
public string Added_By_User { get; set; }
public string Updated_By_User { get; set; }
public bool External_Collaborators
{
get; set;
}
}
Here is my new ViewDataset (viewmodel)
public class ViewDataset
{
public Dataset dataset;
public List<SelectListItem> categories_list;
}
Here is my is a sample of my view ... couple of lines, but the view is populated correctly with data from the ViewDataset model
#model ResearchDataInventoryWeb.Models.ViewDataset
<td>
#Html.TextBoxFor(model => model.dataset.Institution, new { placeholder = "<Institution>", #class = "input-box" })
</td>
<td>
#Html.TextBoxFor(model => model.dataset.Name, new { placeholder = "<Dataset Name>", #class = "input-box" })
</td>
#Html.CheckBoxFor(model => model.dataset.Domestic) <span class="display-checkbox">Domestic</span>
#Html.CheckBoxFor(model => model.dataset.International) <span class="display-checkbox">International</span>
#Html.CheckBoxFor(model => model.dataset.Includes_PHI) <span class="display-checkbox">Includes PHI </span>
#Html.CheckBoxFor(model => model.dataset.Includes_PIL) <span class="display-checkbox">Includes PII </span><br />
#Html.CheckBoxFor(model => model.dataset.External_Collaborators) <span class="display-checkbox">External Collaborators Allowed (Sharable)</span>
#Html.CheckBoxFor(model => model.dataset.Citation_Requirements) <span class="display-checkbox">Citation Requirements</span>
<input type="submit" value="TestPost" />
Here is my HttpPost TestDataset : The model Viewdataset (dataset, categories_list) properties that I am passing back from the view are NULL, am I missing something?
[HttpPost]
public ActionResult TestDataset(ViewDataset viewdataset)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:4251/");
//HTTP POST
viewdataset.dataset.Category_ID = 2;
viewdataset.dataset.Dataset_ID = 1;
viewdataset.dataset.Location = "Fingers Crossed";
viewdataset.dataset.Institution = "Not Null";
var dataset = viewdataset.dataset;
// var postTask = client.PostAsJsonAsync<Dataset>("api/datasets/1", dataset);
var postTask = client.PostAsJsonAsync("api/datasets/1", dataset);
postTask.Wait();
var result = postTask.Result;
if (result.IsSuccessStatusCode)
{
return RedirectToAction("Index");
}
}
ModelState.AddModelError(string.Empty, "Server Error. Please contact administrator.");
return View(viewdataset);
}
Here if my HttpGet TestDataset in case you need to see it
public async Task<ActionResult> TestDataset()
{
//Hosted web API REST Service base url
string Baseurl = "http://localhost:4251/";
List<Dataset> dataset = new List<Dataset>();
List<Category> categories = new List<Category>();
var parm = "1";
var returned = new Dataset();
var ViewDataset = new ViewDataset();
using (var client = new HttpClient())
{
//Passing service base url
client.BaseAddress = new Uri(Baseurl);
client.DefaultRequestHeaders.Clear();
//Define request data format
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//Sending request to find web api REST service resource GetAllEmployees using HttpClient
HttpResponseMessage Res = await client.GetAsync("api/Datasets/" + parm);
HttpResponseMessage Res2 = await client.GetAsync("api/Categories");
//Checking the response is successful or not which is sent using HttpClient
if (Res.IsSuccessStatusCode)
{
//Storing the response details recieved from web api
var EmpResponse = Res.Content.ReadAsStringAsync().Result;
//Deserializing the response recieved from web api and storing into the Employee list
returned = JsonConvert.DeserializeObject<Dataset>(EmpResponse);
}
if (Res2.IsSuccessStatusCode)
{
//Storing the response details recieved from web api
var CatResp = Res2.Content.ReadAsStringAsync().Result;
//Deserializing the response recieved from web api and storing into the Employee list
categories = JsonConvert.DeserializeObject<List<Category>>(CatResp);
}
// Create the Categories Select List
var categoryList = new List<SelectListItem>();
foreach (Category c in categories)
{
categoryList.Add(new SelectListItem
{
Value = c.Category_ID.ToString(),
Text = c.Description,
Selected = (c.Category_ID == returned.Category_ID ? true : false)
});
}
ViewDataset.dataset = returned;
ViewDataset.categories_list = categoryList;
//returned.External_Collaborators = returned.External_Collaborators == null || false ? false : true;
//returning the employee list to view
return View(ViewDataset);
}
}
Try to change
public class ViewDataset
{
public Dataset dataset;
public List<SelectListItem> categories_list;
}
to
public class ViewDataset
{
public Dataset dataset { get; set; }
public List<SelectListItem> categories_list { get; set; }
}

How can I display data from multiple entities in same view and group them by one of the entity

I have clients, projects, client comments and project comments. I want to display one table grouped by client followed by all projects and for each client where there is a comment as well as for each project that has a comment display the last provided comment.
The table would have the Client Name at the top followed by the latest respective comment if provided.
It would be followed by the list of all projects for that client with their latest comment if provided.
I have the client model:
public class Client
{
public int Id { get; set; }
public string ClientName { get; set; }
public bool IsActive { get; set; }
public ICollection<ClientComment> ClientComments { get; set; }
public ICollection<Project> Projects { get; set; }
The project model:
public class Project
{
public int Id { get; set; }
public string ProjectName { get; set; }
public int ClientId { get; set; }
public Client Client { get; set; }
public bool IsArchived { get; set; }
public ICollection<ProjectComment> ProjectComments { get; set; }
The client comment model:
public class ClientComment
{
public int Id { get; set; }
public int? ClientId { get; set; }
public Client Client { get; set; }
public string StatusComment { get; set; }
public DateTime LastUpdateDate { get; set; }
public ClientComment ()
{
this.LastUpdateDate = DateTime.UtcNow;
}
The project comment model:
public class ProjectComment
{
public int Id { get; set; }
public int? ProjectId { get; set; }
public Project Project { get; set; }
public string StatusComment { get; set; }
public DateTime LastUpdateDate { get; set; }
public ProjectComment ()
{
this.LastUpdateDate = DateTime.UtcNow;
}
The end result should be with their respective table headers:
ClientName1 | ClientStatusComment
ProjectName1 | ProjectStatusComment
ProjectName2 | ProjectStatusComment
ProjectName3 | ProjectStatusComment
ClientName2 | ClientStatusComment
ProjectName1 | ProjectStatusComment
ProjectName2 | ProjectStatusComment
ProjectName3 | ProjectStatusComment
You could use View Model which contains the properties you need display in the view.Refer to as follows:
ClientVM and ProjectVM
public class ClientVM
{
public string ClientName { get; set; }
public string ClientStatusComment { get; set; }
public List<ProjectVM> Projectlist { get; set; }
}
public class ProjectVM
{
public string ProjectName { get; set; }
public string ProjectStatusComment { get; set; }
}
Populate the ViewModel
public class ClientsDetailsModel : PageModel
{
private readonly MyDbContext _context;
public ClientsDetailsModel(MyDbContext context)
{
_context = context;
}
[BindProperty]
public List<ClientVM> clientVMList { get; set; }
public async Task<IActionResult> OnGet()
{
var clientlist = _context.Clients
.Include(c => c.ClientComments)
.Include(c => c.Projects)
.ThenInclude(p => p.ProjectComments).ToList();
clientVMList = new List<ClientVM>();
foreach (var item in clientlist)
{
ClientVM clientVM = new ClientVM()
{
Projectlist = new List<ProjectVM>()
};
clientVM.ClientName = item.ClientName;
if (item.ClientComments != null && item.ClientComments.Any())
{
clientVM.ClientStatusComment = item.ClientComments.OrderByDescending(cc => cc.LastUpdateDate).First().StatusComment;
}
else
{
clientVM.ClientStatusComment = "No StatusComment";
}
foreach (var projectItem in item.Projects)
{
ProjectVM projectVM = new ProjectVM();
projectVM.ProjectName = projectItem.ProjectName;
if (projectItem.ProjectComments != null && projectItem.ProjectComments.Any())
{
projectVM.ProjectStatusComment = projectItem.ProjectComments.OrderByDescending(pc => pc.LastUpdateDate).First().StatusComment;
}
else
{
projectVM.ProjectStatusComment = "No StatusComment";
}
clientVM.Projectlist.Add(projectVM);
}
clientVMList.Add(clientVM);
}
return Page();
}
}
ClientsDetails.cshtml
#page
#model MultipleEntitiesInSameView.Pages.ClientsDetailsModel
<table class="table">
<thead>
<tr>
<th>
Name
</th>
<th>
LastStatusComment
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.clientVMList)
{
<tr style="background-color:aliceblue;">
<td>
#Html.DisplayFor(modelItem => item.ClientName)
</td>
<td>
#Html.DisplayFor(modelItem => item.ClientStatusComment)
</td>
</tr>
#foreach (var projectItem in item.Projectlist)
{
<tr>
<td>
#Html.DisplayFor(modelItem => projectItem.ProjectName)
</td>
<td>
#Html.DisplayFor(modelItem => projectItem.ProjectStatusComment)
</td>
</tr>
}
}
</tbody>
</table>
4.Result :

search function in ASP.NET MVC not working properly

i have a student table in my database that i created and i have a view that displays a list of all the students grouped by class... on top of the view i made a textbox and a search button to be able to access the student information faster. The problem is that i when i enter the first name and the last name in the textbox, nothing comes up. When i enter only the first name or only the last name, then it finds it. I'm new to programming and i can't figure out how to make it work. I would really appreciate if someone can help me with this. This is part of my code:
[HttpGet]
public ActionResult ViewStudents()
{
ViewBag.classes = db.Courses.ToList();
var studentCourses = db.StudentCourses.OrderBy(s=>s.Person.FirstName).ToList();
return View(studentCourses);
}
[HttpPost]
public ActionResult ViewStudents(string SearchString)
{
var student=new List<int>();
List<StudentCourse>sc=new List<StudentCourse>();
ViewBag.classes = db.Courses.ToList();
var studentCourse=db.StudentCourses.ToList();
var studentCourses = db.StudentCourses.OrderBy(s => s.Person.FirstName).ToList();
var substring = SearchString.IndexOf(" ").ToString();
if (!string.IsNullOrEmpty(SearchString))
{
student = (from p in db.People
where (p.FirstName.Contains(SearchString)) && (p.LastName.Contains(substring))||((p.FirstName.Contains(SearchString)) || (p.LastName.Contains(SearchString)))
select p.PersonId).ToList();
}
foreach (var s in studentCourse)
{
foreach (var i in student)
{
if (s.StudentId == i)
{
sc.Add(s);
}
}
}
return View(sc);
}
This is my view:
#model List<SchoolFinalProject.Models.StudentCourse>
#using (Html.BeginForm())
{
<div style="font-size:16px;"> <input type="text" id="search" placeholder="search" Name="SearchString" /><span class="glyphicon glyphicon-search"></span>
<input type="submit" value="search"></div>
}
#{
List<int> c = new List<int>();
foreach (var courses in ViewBag.classes)
{
foreach(var s in Model)
{
if(courses.CourseId==s.CourseId)
{
c.Add(courses.CourseId);
}
}
}
}
#foreach (var course in ViewBag.classes)
{
if(c.Contains(course.CourseId))
{
<h2>#course.Name<span>-</span>#course.Gender</h2>
<table class="table table-hover table-bordered table-striped">
<tr><th>First Name</th><th>Last Name</th><th>Email</th><th>Phone Number</th><th>Address</th><th>Date Of Birth</th></tr>
#foreach (var s in Model)
{
if(course.CourseId==s.CourseId)
{
<tr>
<td>#s.Person1.FirstName</td>
<td>#s.Person1.LastName</td>
<td>#s.Person1.Email</td>
<td>#s.Person1.PhoneNumber</td>
<td>#s.Person1.Address</td>
<td>#s.Person1.DateOfBirth</td>
<td>
<span class="glyphicon glyphicon-edit"></span>
#Html.ActionLink("Edit", "Edit","Person", new { id = s.Person1.PersonId }, null) |
<span class="glyphicon glyphicon-trash"></span>
#Html.ActionLink("Details", "Details","Person", new { id = s.Person1.PersonId }, null)
</td>
</tr>
}
}
</table>
}
}
Go to top of page
this is my person Model:
public partial class Person
{
public Person()
{
this.Bonus = new HashSet<Bonu>();
this.ConversationHistories = new HashSet<ConversationHistory>();
this.ConversationHistories1 = new HashSet<ConversationHistory>();
this.EmployeePaymentDetails = new HashSet<EmployeePaymentDetail>();
this.StudentCourses = new HashSet<StudentCourse>();
this.StudentCourses1 = new HashSet<StudentCourse>();
this.TeacherCourses = new HashSet<TeacherCourse>();
this.Reminders = new HashSet<Reminder>();
}
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string PhoneNumber { get; set; }
public string Address { get; set; }
public Nullable<System.DateTime> DateOfBirth { get; set; }
public PersonType PersonTypeId { get; set; }
public Nullable<System.DateTime> LastModified { get; set; }
public Nullable<int> Gender { get; set; }
public Nullable<int> Status { get; set; }
public string FullName
{
get { return FirstName + ", " + LastName; }
}
public virtual ICollection<Bonu> Bonus { get; set; }
public virtual ICollection<ConversationHistory> ConversationHistories { get; set; }
public virtual ICollection<ConversationHistory> ConversationHistories1 { get; set; }
public virtual ICollection<EmployeePaymentDetail> EmployeePaymentDetails { get; set; }
public virtual ICollection<StudentCourse> StudentCourses { get; set; }
public virtual ICollection<StudentCourse> StudentCourses1 { get; set; }
public virtual ICollection<TeacherCourse> TeacherCourses { get; set; }
public virtual ICollection<Reminder> Reminders { get; set; }
}
}
You might want to try concatenating the first and last name properties in your person model like this:
[Display(Name = "Full Name")]
public string FullName
{
get
{
return LastName + ", " + FirstMidName;
}
}
There is a very good tutorial on what you are trying to do here: https://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-a-more-complex-data-model-for-an-asp-net-mvc-application
Also see this page of same tutorial: https://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application
As an aside, you might want to check out using the Datatables plugin, which gives you search functionality without have to query your database with each search: https://datatables.net

#Html.LisboxFor Model Binding for multiple items

My Class is
public partial class Team
{
public int TeamId { get; set; }
public string TeamName { get; set; }
public string TeamDescription { get; set; }
public virtual IList<Trials> Trials { get; set; }
}
Trials is anothetr calss
public partial class Trials
{
public int TrialID { get; set; }
public string Name { get; set; }
public int TrialTyp_RefID { get; set; }
public bool isChk { get; set; }
public virtual ICollection<Team> Team { get; set; }
}
in my view I amn trying to bind the ListBoxFor with Trials inseide the team
#model Trials.Classes.Team
<td colspan="2">
#Html.ListBoxFor(model=> model.Trials,
new SelectList(ViewBag.trials,"TrialID", "Name"),
new { #class = "chosen-select", data_placeholder = "Select Trials...", style = "width:500px;", tabindex = "4" }
)
</td>
I cant get any value for Trials calss in the controller ..It shows null but I select multi values from listbox
A multiple select only posts back an array of primitive values. It does not post back a collection of complex objects.
You need a view model with a property to bind the selected Trials
public class TeamVM
{
public int TeamId { get; set; }
....
public int[] SelectedTrials { get; set; }
public SelectList Trials { get; set; } // Assign this in your controller rather than using ViewBag
}
then in you view
#Html.ListBoxFor(m => m.SelectedTrials, Model.Trials)
When you post back, Team.SelectedTrials will contain and array of the selected TrialID values.
I changed the Team class as
public partial class Team
{
public int TeamId { get; set; }
public string TeamName { get; set; }
public string TeamDescription { get; set; }
public virtual IList<Trials> Trials { get; set;
public int[] AuthorisedTrials { get; set; }
}
and in View
#model Trials.Classes.Team
<td colspan="2">
#Html.ListBoxFor(model=> model.AuthorisedTrials ,
new SelectList(ViewBag.trials,"TrialID", "Name"),
new { #class = "chosen-select", data_placeholder = "Select Trials...", style = "width:500px;", tabindex = "4" }
)
</td>
and in my controller I was able to get the Vlaues for Selected Trials

System.Collections.Generic.IEnumerable<MyBlogSite.Models.BlogPost>' does not contain a definition for 'Categories'

Here is my BlogPost Model class:
public class BlogPost
{
public int Id { get; set; }
public string Title { get; set; }
[AllowHtml]
public string ShortDescription { get; set; }
[AllowHtml]
public string PostBody { get; set; }
public string Meta { get; set; }
public string UrlSlug { get; set; }
public DateTime PostedOn { get; set; }
public DateTime? Modified { get; set; }
public virtual ICollection<BlogPostCategory> Categories { get; set; }
public virtual ICollection<BlogPostTag> Tags { get; set; }
}
Here is my BlogPostCategory Model class:
public class BlogPostCategory
{
public int Id { get; set; }
public string Name { get; set; }
public string UrlSlug { get; set; }
public string Description { get; set; }
// Decared virtual because the data must be returned from another table.
public virtual ICollection<BlogPost> BlogPosts { get; set; }
}
Each class belongs to a separate Controller/View.
Finally, here is the top port of the Index View for Blog:
#model IEnumerable<MyBlogSite.Models.BlogPost>
#{
ViewBag.Title = "Index";
}
#Html.RenderPartial("~/Views/Category/_Categories.cshtml", Model.Categories );
<p>
#Html.ActionLink("New Blog Post", "Create")
</p>
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.Title)
</th>
....
In the View where Model.Categories is being passed in is where I am getting the exception from the title of this post. It seems to me that I have defined Categories within the BlogPost Model. What am I doing wrong?
The Model on your Razor page is an IEnumerable<MyBlogSite.Models.BlogPost>. It seems you're trying to display the information about each of the items in your collection. If so, then you can loop through them or create a display/editor template and use #Html.DisplayFor(x => x) or #Html.EditorFor(x => x), respectively.
#foreach(var post in Model) {
<p>Do stuff here with the local "post" variable.</p>
}
Here's a link to Scott Gu's blog talking about the #model directive in Razor views.