-4

I want to INSERT employee attendance into database where i have a department dropdown and on selection of department, html table is filled with all emp code, emp name and a dropdown with attendance status(present/absent) related to selected department and on submit it is inserted in database with department name,emp code,emp name, status in mvc

this is TblEmpAttendance model

namespace SchoolManagementSystem.EFModel
{
using System;
using System.Collections.Generic;
using System.Web.Script.Serialization;

public partial class TblEmpAttendance
{
    public int Emp_Attendance_Id { get; set; }
    public string Session { get; set; }
    public int Emp_Type_Id { get; set; }
    public string Emp_Type { get; set; }
    public int Emp_Dept_Id { get; set; }
    public string Emp_Deptartment { get; set; }
    public System.DateTime Date { get; set; }
    public int Emp_Official_Id { get; set; }
    public string Emp_Code { get; set; }
    public string Emp_Name { get; set; }
    public int Status_Id { get; set; }
    public string Status { get; set; }

    [ScriptIgnore]
    public TblDepartment TblDepartment { get; set; }
    [ScriptIgnore]
    public TblEmployeeOfficialDetail TblEmployeeOfficialDetail { get; set; }
    [ScriptIgnore]
    public  TblEmployeeType TblEmployeeType { get; set; }
}

}

This is my EF model

@model SchoolManagementSystem.EFModel.TblEmpAttendance

@using (Html.BeginForm("InsertEmpAttendanceAction", "Employee", FormMethod.Post)) {

<div>
    <div class="form-group" style="width :50%; float:left; padding-right:10px">
        <label>SESSION</label> <br />
        <input type="text" class="form-control font" id="ses" name="ses" value="2015-2016" readonly>
    </div>
        <div class="form-group" style="width: 50%; float: right; padding-right: 10px">
            <label>DATE</label> <br />             
            <input type="text" class="form-control font" id="Date" name="Date" value="@Model.Date.ToShortDateString()">
        </div>
    </div>

<div>

    <div class="form-group" style="width :50%; float:left">
        <label>EMPLOYEE TYPE</label> <br />
       @foreach (var type in ViewBag.Type_IdList)
        {
            <input type="radio" name="type" value="@type.Value" style="font:bold 16px verdana" /> <label>@type.Text</label> <br />
        }
       </div>
    <div class="form-group" style="width :50%; float:right">
        <label>EMPLOYEE DEPARTMENT</label> <br />
        @Html.DropDownList("DDLDepartment", ViewBag.Department_IdList as SelectList,"--SELECT DEPARTMENT--", new { @class = "ddlfont" })
    </div>
</div>


<div id="original" hidden>
    @Html.DropDownList("DDLStatus", ViewBag.Status_IdList as SelectList, new {@class = "ddlfont" })
</div>

<div class="form-group font" id="attend">

    <table>
        <tr>
            <th>EMPLOYEE CODE</th>
            <th>EMPLOYEE NAME</th>
            <th>ATTENDANCE</th>                
        </tr>
         <tr>

          </tr>

    </table>
</div> 

I am filling the table using jQuery and it is properly filled:

$(document).ready(function () {
        $("#DDLDepartment").click(function () {

        $("#Emp_Deptartment").val($("#DDLDepartment option:selected").text());
        $("#Emp_Dept_Id").val($("#DDLDepartment option:selected").val());

       $('#attend table tr:not(:first)').remove();
        var deptid = parseInt($('#DDLDepartment').val());
        console.log(deptid);
        if ($('#DDLDepartment').val() != "--SELECT DEPARTMENT--") {

            $.ajax({
                url: "@Url.Action("GetEMPDetails", "Employee")",
                type: "GET",
                data: { DeptId: deptid },
                dataType: "json",
                contentType: "application/json",
                processdata: true,
                success: function (data) {                      
                    var dropdown = $('#DDLStatus').clone();
                    $.each(data, function (i, empdetail) {
                        console.log(empdetail);
                        $('#attend table').append("<tr><td>" + empdetail.Employee_Code + "</td><td>" + empdetail.Employee_Name + "</td><td>" + "<span class='abc'></span>" + "</td></tr>");
                        $('.abc').html(dropdown);


                        //$("#Emp_Official_Id").val(empdetail.Employee_Official_Id);                            

                    });


                },

            });
        }
        else {
            alert(" PLEASE SELECT VALID DEPARTMENT ")
        }

});
});

In My controller

public ActionResult InsertEmpAttendanceAction(TblEmpAttendance empattendanceobj, **ICollection<TblEmpAttendance> attendance**)// here i was stuck as it returns null
        {

}
James Z
  • 12,209
  • 10
  • 24
  • 44
JOE
  • 3
  • 3
  • 2
    Welcome to stackoverflow. Please read [ask]. – Zohar Peled Jul 29 '15 at 05:21
  • where is your code and where have you stuck? – Bhushan Kawadkar Jul 29 '15 at 05:21
  • now help me to solve this... – JOE Jul 29 '15 at 06:06
  • 1
    Your generating form controls with `name` attributes that have no relationship at all to your model so wont bind when you post back. At the very least you need to show you model for `TblEmpAttendance` in order to help you solve this (hint: you must use a `for` loop or custom `EditorTemplate`, not a `foreach` loop and generate your html using strongly types html helpers) And since your claim you script is working, why have you included it (what has it got to do with the question)? –  Jul 29 '15 at 06:13
  • ok i removed the foreach loop and also added TblEmpAttendance – JOE Jul 29 '15 at 06:35
  • Its still a little unclear. Is the intention that you select a department, and that you load all `TblEmpAttendance` items for that department, and then you want to be able to edit those `TblEmpAttendance` items and save them? If so, update your question to better explain what your trying to do and I'll reopen the question –  Jul 29 '15 at 06:56
  • ex. when i select account dept from department dropdown all the employee in account department is load in the table with attendance dropdown. Then i set the attendance status of all employee of account department and click on submit. on click of submit all the data should be inserted in database with attendance status. – JOE Jul 29 '15 at 07:00
  • @JOE, But your script is not adding any controls associated with the properties of `TblEmpAttendance` so there is nothing to edit and nothing to post back. Which properties of `TblEmpAttendance` do you want to edit? - just the `Status`? –  Jul 29 '15 at 07:05
  • i tried to put value in hidden input type text but it is taking on the last value of the table – JOE Jul 29 '15 at 07:18
  • You will find this far easier if your `GetEMPDetails()` method returns a partial view rather than json data. Is that an acceptable solution? And if you do want to understand how to do all this purely client side, then refer [this answer](http://stackoverflow.com/questions/29837547/set-class-validation-for-dynamic-textbox-in-a-table/29838689#29838689) for some guidance –  Jul 29 '15 at 07:40

1 Answers1

0

You not currently creating any form controls relating to TblEmpAttendance, just a one <select> for each row in you table with name="DDLStatus" (which is also generating invalid html because of the duplicate id attributes). The easy way to handle this is by returning a partial view rather than a JsonResult from your GetEMPDetails() method.

First you need to start by defining view models that represent what you are displaying/editing in the view (refer What is ViewModel in MVC?)

public class EmployeeVM
{
  public int ID { get; set; }
  public sting Code { get; set; }
  public string Name { get; set; }
  [Required(ErrorMessage = "Please select the status")]
  public int StatusID { get; set; }
}
public class AttendanceVM
{
  [Display(Name = "Department")]
  [Required(ErrorMessage = "Please select a department")]
  public int DepartmentID { get; set; }
  public DateTime Date { get; set; }
  .... // add other properties, for example for employee type etc, but its unclear how these are used in the view
  public List<EmployeeVM> Employees { get; set; }
  public SelectList StatusList { get; set; }
  public SelectList DepartmentList { get; set; }
}

Next create an EditorTemplate for type of EmployeeVM. In /Views/Shared/EditorTemplates/EmployeeVM.cshtml

@model yourAssembly.EmployeeVM
<tr>
  <td>@Html.DisplayFor(m => m.Code)</td>
  <td>@Html.DisplayFor(m => m.Name)</td>
  <td>
    @Html.HiddenFor(m => m.ID)
    @Html.DropDownListFor(m => m.StatusID, (SelectList)ViewData["statuslist"], "-Please select-")
  </td>
</tr>

Then create a partial view to display the selected employees (say _EmployeeDetails.cshtml)

@model yourAssembly.AttendanceVM
@Html.EditorFor(m => m.Employees, new { statuslist = Model.StatusList })

And the main view will be

@model yourAssembly.AttendanceVM
@using (Html.BeginForm())
{
  @Html.LabelFor(m => m.DepartmentID)
  @Html.DropDownListFor(m => m.DepartmentID, Model.DepartmentList, "-Please select-")
  @Html.ValidationMessageFor(m => m.DepartmentID)
  @Html.LabelFor(m => m.Date)
  @Html.TextBoxFor(m => m.Date, "{0:d}")
  @Html.ValidationMessageFor(m => m.Date)
  // .... controls for other properties
  <table>
    <thead>
      <tr>
        <th>Code</th>
        <th>Name</th>
        <th>Attendance</th>                
      </tr>
    </thead>
    <tbody id="employees">
    </tbody>
  </table>
}

And modify your script to

var url = '@Url.Action("GetEmployeeDetails", "Employee")';
var table = $('#employees');
var form = $('form');
$('#DepartmentID').change(function() {
  if (!$(this).val() {
    return;
  }
  $.get(url, { ID: $(this).val() }, function(data) {
    table.html(data);
    // Reparse the validator
    form.data('validator', null);
    $.validator.unobtrusive.parse(form);
  });
});

Finally your controller methods

public ActionResult Index()
{
  AttendanceVM model = new AttendanceVM();
  ... // populate SelectList's, set default values for properties etc.
  return View(model);
}
[HttpPost]
public ActionResult Index(AttendanceVM model)
{
  if (!ModelState.IsValid)
  {
    ... // repopulate SelectList's
    returnView (model);
  }
  // Get the employees data models from the database based on model.DepartmentID
  var employees = db.TblEmpAttendance.Where(e => e.Emp_Dept_Id == model.DepartmentID);
  // Update each one based on the view model data
  foreach (var item in Model.Employee)
  {
    var employee = employees.Where(e => e.Emp_Attendance_Id == item.ID).FirstOrDefault();
    employee.Status_Id = item.StatusID;
    ....
  }
  // save each data model and redirect
}
public PartialViewResult GetEmployeeDetails(int ID)
{
  AttendanceVM model = new AttendanceVM();
  ... // populate collection of employees based on the department ID
  ... // populate SelectList for StatusList
  return PartialView("_EmployeeDetails", model);
}

To understand why this will bind to you model when you post, look at the html it generates for the controls, for example the dropdownlist for employees will be

<select name="Employees[0].StatusID" ...>
<select name="Employees[1].StatusID" ...>
<select name="Employees[2].StatusID" ...>

The name attributes not relate to you model - your model contains a collection property named Employees and each employee (defined by the index) has a property named StatusID

Side note: I strongly recommend follow normal conventions for your class and property names

Community
  • 1
  • 1
  • Thanks a lot , its really very helpful i am new to mvc and trying to learn mvc. – JOE Jul 30 '15 at 05:10