How to check exisiting course and save changes in EmployeeCourse table - asp.net-mvc-4

Problem
update changes (name) in employee table
and changes in courses in table EmployeeCourse in database
in Edit function[HTTP post]
Detailes
I have 3 tables Employee,Course,EmployeeCourse
so that when i select employee then edit in courses selected
for this employee by add courses or remove courses
and change in (name)
will save in two tables employee and employee course table
details found in image link
update courses in employee courses and employee data for employee table
code
public class EditEmployeeVm
{
public int Id { set; get; }
public string Name { get; set; }
public List<SelectListItem> Courses { get; set; }
public int[] CourseIds { set; get; }
public List<CourseVm> ExistingCourses { set; get; }
}
public class CourseVm
{
public int Id { set; get; }
public string Name { set; get; }
}
in edit function get i pass data to edit view
public ActionResult Edit(int id)
{
var vm = new EditEmployeeVm { Id = id };
var emp = db.Employees.FirstOrDefault(f => f.Id == id);
vm.Name = emp.Name;
vm.ExistingCourses = db.EmployeeCourses
.Where(g => g.EmployeeId == id)
.Select(f => new CourseVm
{
Id = f.Id,
Name = f.Course.CourseName
}).ToList();
vm.CourseIds = vm.ExistingCourses.Select(g => g.Id).ToArray();
vm.Courses = db.Courses.Select(f => new SelectListItem
{
Value = f.Id.ToString(),
Text = f.CourseName
}).ToList();
return View(vm);
}
[HttpPost]
public ActionResult Edit(EditEmployeeVm model)
{
what code i write here to update changes in two tables
employee and employeecourse
course id as array
}

you can do it with checkbox if the employee is taking a course mark the checkbox like this
<div class="panel panel-default">
<div class="panel-heading">Asignaturas</div>
<div class="panel-body">
<ul class="list-group">
#foreach (var c in cursos)
{
var tomado = false;
foreach (var c2 in Model.Cursos)
{
if (c.id == c2.id)
{
tomado = true;
break;
}
}
<li class="list-group-item">
<label><input type="checkbox" #(tomado ? "checked" : "") name="cursos" value="#c.id" /> #c.Nombre</label>
</li>
}
</ul>
</div>
</div>
I leave the blog where you can see more detailed
Here
and as for the name you can do a partial view and edit it with ajax

Related

"mes":"Value cannot be null. (Parameter 'source')" when want to show value which is true in view with checkbox

Hi I have 3 tables: Role , Permission , RolePermission
In my Razor page view I want to show each permission that is true for a special role with marking the check box . In every role I show all permission in a tree model (my permission is a parent child table)
So for this reason I make a model
[Table("tblPermission", Schema = "cmn")]
public class Permission
{
[Key]
public int PermissionId { get; set; }
public string PermissionTitle { get; set; }
public int? ParentId { get; set; }
[ForeignKey("ParentId")]
public List<Permission> Permissions { get; set; }
public List<RolePermission> RolePermissions { get; set; }
}
And two action
[BindProperty]
public Role Role { get; set; }
public void OnGet(int id)
{
Role = _permissionService.GetRoleById(id);
var b= _permissionService.GetAllPermission();
ViewData["Permissions"] = b;
var a= _permissionService.permissionsRole(id);
ViewData["SelectedPermission"] = a;
}
public IActionResult OnPost()
{
if (!ModelState.IsValid)
{
return Page();
}
_permissionService.UpdateRole(Role);
return RedirectToPage("Index");
}
And my view is like bellow :
#page "{id}"
#using Entities.Permission
#model Pages.Admin.Roles.EditRoleModel
#{
ViewData["Title"] = "Edit role";
List<Permission> permissions = ViewData["Permissions"] as List<Permission>;
List<int> SelectedPermissions = ViewData["SelectedPermissions"] as List<int>;
}
<div class="panel-body">
<ul>
#foreach (var permission in permissions.Where(p => p.ParentId == null))
{
<li>
<input type="checkbox" name="SelectedPermission"
#((SelectedPermissions.Any(p=>p==permission.PermissionId)?"checked":""))
value="#permission.PermissionId" /> #permission.PermissionTitle
#if (permissions.Any(p => p.ParentId == permission.ParentId))
{
<ul>
#foreach (var sub in permissions.Where(p => p.ParentId == permission.PermissionId))
{
<li>
<input type="checkbox" name="SelectedPermission"
#((SelectedPermissions.Any(p=>p==sub.PermissionId)?"checked":"")) value="#sub.PermissionId"
/> #sub.PermissionTitle
</li>
}
</ul>
}
</li>
}
</ul>
</div>
At this line “#((SelectedPermissions.Any(p=>p==sub.PermissionId)?"checked":""))” I get the error :
"mes":"Value cannot be null. (Parameter 'source')" .And when I Check out I found that none of my viewData is not null.

How can I dynamically update the span and the contents of the first row of headers in a table with 2 rows of headers in ASP.Net Core 3.1?

I'm trying to make a table with 2 rows of headers, both of them update dynamically from 2 separate database tables. The content update part is ok, it works. The problem is, the cells in the first row must span over whatever the number of entries of that particular category is in the 2nd row.
I've grouped the second row categories by elements with their id, counted the ids and put them in a ViewBag.
The first row model:
[Table("categories")]
public class CategoriesModel
{
[Column("category_id")]
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Required]
public int CategoryId { get; set; }
[Column("category_name")]
//[Required]
public string CategoryName { get; set; }
}
Second row model:
[Table("materials")]
public class MaterialModel
{
[Column("material_id")]
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Required]
public int MaterialId { get; set; }
[Column("height_x_width")]
[Required]
public string Dimensions { get; set; }
[Column("category_id")]
[Required]
public int CategoryId { get; set; }
public List<CategoriesModel> MaterialCategory { get; set; }
}
The ViewModel:
public class NationalCampaignViewModel
{
public string Campaign { get; set; }
public IEnumerable<RestaurantModel> Restaurant { get; set; }
public IEnumerable<CategoriesModel> Categories { get; set; }
public IEnumerable<MaterialModel> Materials { get; set; }
public IEnumerable<OptionModel> Options { get; set; }
}
the ViewModelController:
public class NationalCampaignViewModelController : Controller
{
private readonly McDdbContext _context;
public NationalCampaignViewModelController(McDdbContext context)
{
_context = context;
}
// GET: NationalCampaign
public async Task<IActionResult> Index(int? id)
{
var campaign = await _context.NationalCampaigns.FirstOrDefaultAsync(m => m.Id == id);
var restaurant = await _context.Restaurants.ToListAsync();
//var stl = await _context.STL.ToListAsync();
//var dtl = await _context.DTL.ToListAsync();
var categories = await _context.CategoriesModel.ToListAsync();
var options = await _context.OptionModel.ToListAsync();
var materials = await _context.MaterialModel.ToListAsync();
var colSpan = materials.OrderBy(x => x.CategoryId).GroupBy(x => x.CategoryId).ToDictionary(g => g.Key, g => g.Count());
ViewBag.ColSpan = colSpan.Values;
var tables = new NationalCampaignViewModel
{
Campaign = campaign.CampaignName,
Restaurant = from r in restaurant select r,
Categories = from c in categories orderby c.CategoryId select c,
//Options = from o in options select o,
Materials = from m in materials orderby m.CategoryId select m
};
if (id == null)
{
return NotFound();
}
return View(tables);
}
The View:
#{
ViewData["Title"] = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>#Model.Campaign</h1>
<div class="container">
<div class="row">
<div class="col">
<table class="table-bordered">
#foreach (var span in ViewBag.ColSpan)
{
<colgroup>
<col span="#span" />
</colgroup>
}
<thead>
<tr align="center">
<th>#Html.DisplayNameFor(model => model.Restaurant.FirstOrDefault().Restaurant_Name)</th>
#foreach (var c in Model.Categories)
{
<th scope="colgroup">#c.CategoryName</th>
}
</tr>
<tr>
<th>Dimensions</th>
#foreach (var m in Model.Materials)
{
<th>#m.Dimensions</th>
}
</tr>
</thead>
<tbody>
#*#foreach (var item in Model.Restaurant)
{
<tr>
<td>
<a asp-controller="Restaurant" asp-action="Edit"
asp-route-id="#item.Restaurant_Id">#Html.DisplayFor(modelItem => item.Restaurant_Name)</a>
</td>
</tr>
}*#
</tbody>
</table>
</div>
The table with the number of columns to span over:
Solved it with dictionary.
Controller:
var colSpan = materials.OrderBy(x => x.CategoryId).GroupBy(x => x.CategoryId).ToDictionary(g => g.Key, g => g.Count());
Dictionary<string, int> headerValues = new Dictionary<string, int>();
List<string> keys = new List<string>();
foreach (var category in categories)
{
keys.Add(category.CategoryName);
}
headerValues = keys.Zip(colSpan.Values, (k, v) => new { k, v })
.ToDictionary(x => x.k, x => x.v);
ViewBag.ColSpan = headerValues;
View:
#foreach (var item in ViewBag.Colspan)
{
<th colspan="#item.Value">#item.Key</th>
}

Update data in multiple table relation(employee and employeecourse tables)

I have two tables employee and employee course in a one-to-many relation.
Needs: update name in table employee and courseid in employeecourse table in edit view
Problem: when click submit button in edit view it delete all data and save only selected
Courses from drop down courses just now
If no changes happen to courses by(add or remove courses) when click submit
Button it delete all
code logic
I try to using logic to delete all data when click submit then save all data
after changes
meaning submit button do two task
delete courses exist before for the employee i edit view
add the courses after all changes done in edit view for this employee
see image below
code
model class EditEmployeeVm
public class EditEmployeeVm
{
public int Id { set; get; }
public string Name { get; set; }
public List<SelectListItem> Courses { get; set; }
public int[] CourseIds { set; get; }
public List<CourseVm> ExistingCourses { set; get; }
}
public class CourseVm
{
public int Id { set; get; }
public string Name { set; get; }
}
in edit function get i pass data to edit view
public ActionResult Edit(int id)
{
var vm = new EditEmployeeVm { Id = id };
var emp = db.Employees.FirstOrDefault(f => f.Id == id);
vm.Name = emp.Name;
vm.ExistingCourses = db.EmployeeCourses
.Where(g => g.EmployeeId == id)
.Select(f => new CourseVm
{
Id = f.Id,
Name = f.Course.CourseName
}).ToList();
vm.CourseIds = vm.ExistingCourses.Select(g => g.Id).ToArray();
vm.Courses = db.Courses.Select(f => new SelectListItem
{
Value = f.Id.ToString(),
Text = f.CourseName
}).ToList();
return View(vm);
}
[HttpPost]
public ActionResult Edit(EditEmployeeVm model)
{
**//i need to save name employee changes in employee table and all courses changes in emloyeecourse table
//what is wrong here**
var emp = db.Employees
.Include(e => e.EmployeeCourses)
.FirstOrDefault(f => f.Id == model.Id);
foreach (var eec in emp.EmployeeCourses.ToList())
{
db.EmployeeCourses.Remove(eec);
}
foreach (var couseid in model.CourseIds)
{
db.EmployeeCourses.Add(new EmployeeCourse { CourseId = couseid, EmployeeId = emp.Id });
}
db.SaveChanges();
return View();
}
update
public ActionResult Edit(EditEmployeeVm model)
{
var emp = db.Employees.FirstOrDefault(f => f.Id == model.Id);
foreach (var couseid in model.CourseIds)
{
db.EmployeeCourses.Add(new EmployeeCourse { CourseId = couseid, EmployeeId = emp.Id });
db.SaveChanges();
}
return View();
}
I Try in code above under update section
i can add data and save when click submit button
but problem when click remove button to course by jquery
it remove it but it not save changes of remove in database
so that when open edit view again i see item i removed before
how to solve that when click submit button to save item removed in database

MVC4 Razor drop down list binding with foreign key

So as I wanted to have a deeper understanding. I added a little bit more functionality to the MSFT tutorial on MVC4 that you can find here (http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/intro-to-aspnet-mvc-4)
The model is very simple. You have movies and directors. Every movie has 1 director max.
I want the user to be able to assign a director to a movie from a drop down list and save it but somehow the movie gets saved with a null Director_ID field in the database.
Here are my simple models:
public class Movie
{
public int ID { get; set; }
[Required]
public string Title { get; set; }
public DateTime ReleaseDate { get; set; }
[Required]
public string Genre { get; set; }
public decimal Price { get; set; }
public string Ranking { get; set; }
public Director Director { get; set; }
}
public class Director
{
public int ID { get; set; }
public string Name { get; set; }
}
When the movie table gets generated it comes with a Director_ID field. Sweet!
I would like the user to select a director while editing a movie form a drop down list so
in the movie edit view I managed to bind a drop down list to a list of all directors obtained form the database
<div class="editor-field">
#Html.DropDownListFor(model => model.Director.ID, ViewBag.Directors as List<SelectListItem>, "All")
</div>
Controller:
//GET
public ActionResult Edit(int id = 0)
{
var DirectorsList = new List<SelectListItem>();
var DirQuery = from d in db.Directors select d;
foreach (var d in DirQuery)
{
DirectorsList.Add(new SelectListItem { Value = d.ID.ToString(), Text = d.Name });
}
ViewBag.Directors = DirectorsList;
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
return View(movie);
}
I get my list of all directors in my drop down. All right!
Now when I save the movie :
[HttpPost]
public ActionResult Edit(Movie movie)
{
if (ModelState.IsValid)
{
movie.Director = db.Directors.Find(movie.Director.ID);
db.Entry(movie).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(movie);
}
The argument movie that the Edit method receives comes with a Director property (as I specified in the model), when I browse into it I see the two properties form director:
"ID": which comes with the proper value that the user selected form the drop down and "Name": set to null.
As you can see in the code I pick the whole director object form the database matching the drop down value and save it
The problem is that when saving the movie, the foreign key on Movies table (Director_ID) never gets updated.
What am I doing wrong? Is there any better approach for doing this?
Make Id of the Director part of your model, like
public class Movie
{
public int ID { get; set; }
[Required]
public string Title { get; set; }
public DateTime ReleaseDate { get; set; }
...
public int DirectorId { get; set; }
public virtual Director Director { get; set; }
}
Then in your controller:
//GET
public ActionResult Edit(int id = 0)
{
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
ViewBag.DirectorId = new SelectList(db.Directors, "DirectorId", "Name", movie.DirectorId);
...
}
And in your view:
<h2>Edit</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Movie</legend>
...
<div class="editor-label">
#Html.LabelFor(model => model.DirectorId, "Director")
</div>
<div class="editor-field">
#Html.DropDownList("DirectorId", String.Empty)
#Html.ValidationMessageFor(model => model.DirectorId)
</div>
...

Filling dropdownlist from DB

I'm trying to move over to MVC from webforms, and to be honest, it's not going very well.
I need a DropDownList populated with values from my database, and I'm having a hard time understanding how to do this.
I'm thinking, that I need to create a model,using entity framework, and refer my DropDownList to that? But how do I point it to that model?
Also, if I make a model, from a database table, how do I adjust the select command, so I only get certain values, and not the entire table?
I know this is kind of a broad question, and I have no examples listed, but I've had a really hard time, finding information I could understand, with regards to my issue.
I would start from this this should get you the project created if you have not done so so you can have the model ready
http://msdn.microsoft.com/en-us/data/gg685489
in order to create a dropdownlist here is an example
ViewBag.dropdownlist = new SelectList(db.tablename, "Valuefiled", "NameGField");
where Valuefiled=name of a column in your database that you want to use for values
"NameGField"=name of a column in your database that you want to use for names
getting drop down list to view
#Html.DropDownList("dropdownlist")
How About this
Your ViewModel
public class CategoryViewModel
{
public Category Category { get; set; }
public IEnumerable<SelectListItem> CategoryTitles { get; set; }
}
Your Controller
public ActionResult Create()
{
var categoryviewmodel = new CategoryViewModel();
categoryviewmodel.Category = new Category();
var list = categoryRepository.AllCategoryTitles().ToList().Select(t => new SelectListItem
{
Text = t.CategoryName,
Value = t.CategoryID.ToString()
})
.ToList();
list.Insert(0, new SelectListItem { Value = "0", Text = "Please Selext" });
categoryviewmodel.CategoryTitles = list;
return View(categoryviewmodel);
}
Your Repository
public IQueryable<Category> AllCategoryTitles()
{
var query = context.Categories.Where(m => m.ParentCategoryID == null && m.IsActive==true);
return query;
}
Your View
#Html.DropDownListFor(model => model.CategoryParentID, Model.CategoryTitles)
You can use a viewModel. Here is an example solution with some assumptions. Refer to the dropdownlist (here in the dropdown I am listing departments of type "InBound"
Employee Model
public class EmployeeModel
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int DeptId { get; set; }
}
Department Model
public class DepartmentModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Type { get; set; }
}
ViewModel (to be passed into the view)
public class EmployeeViewModel
{
public EmployeeModel Employee { get; set; }
public IEnumerable<DepartmentModel> Departments { get; set; }
}
Controller
public ActionResult Index()
{
EmployeeViewModel vm = new EmployeeViewModel();
//This is hardcoded. However you will write your own method to pull the department details with filtering
List<DepartmentModel> departments = new List<DepartmentModel>() { new DepartmentModel { Id = 1, Name = "Accounts", Type = "InBound" }, new DepartmentModel { Id = 2, Name = "Finance", Type = "OutBound" }, new DepartmentModel { Id = 3, Name = "HR", Type = "InBound" } };
vm.Departments = departments.Where(d => d.Type == "InBound");
return View(vm);
}
View
#model Test1.ViewModels.EmployeeViewModel
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using (Html.BeginForm())
{
#Html.HiddenFor(model => model.Employee.Id);
<table>
<tr>
<td>#Html.LabelFor(model => model.Employee.FirstName)</td>
<td>#Html.EditorFor(model => model.Employee.FirstName)</td>
</tr>
<tr>
<td>#Html.LabelFor(model => model.Employee.LastName)</td>
<td>#Html.EditorFor(model => model.Employee.LastName)</td>
</tr>
<tr>
<td>#Html.Label("Department")</td>
<td>#Html.DropDownListFor(model => model.Employee.DeptId, new SelectList(Model.Departments, "Id", "Name"))</td>
</tr>
</table>
}