6

I have a table of employees which I fetch using $.load ajax call by sending back a partialview as below:

Model Class

public class EmployeeDetails
{
    public string FirstName{get;set;}
    public string LastName{get;set;}
    public string AccountStatus{get; set;}
    public string LastLogin{get;set;}
    public string EmailAddress{get;set;}
    public string Contact {get;set;}
    public string Gender {get;set;}
}

PartialViewResult method in controller

public PartialViewResult GetEmployeeDetails()
{
    List<EmployeeDetails> model=new List<EmployeeDetails>();
    using(var context=new ContextConnection())
    {
        var employees=(from e in context.tbl_employees select e).ToList();
        foreach(var employee in employees) //Fill the model
        {
            model.add(new EmployeeDetails(){
                 FirstName=employee.fname,
                 LastName=employee.lname,
                 AccountStatus=employee.acc_status,
                 LastLogin=employee.last_login,
                 EmailAddress=employee.email,
                 Contact=employee.contact,
                 Gender=employee.gender
            });
        }
    }
    return PartialView("_EmployeeDetails",model) //passing model back
}

_EmployeeDetails View

@model IEnumerable<ProjectName.Models.EmployeeDetails>

<table id="employee" class="display" cellspacing="0" width="100%">
        <thead>
            <tr>
                <th></th>
                <th>Full Name</th>
                <th>Account Status</th>
                <th>Last Login</th>
                <th>Email Address</th>
            </tr>
        </thead>
        <tbody>
        @foreach(var emp in Model)
        {
            <tr>
                <td></td>
                <td>@emp.FirstName + " " + @emp.LastName</td>
                <td>@emp.AccountStatus</td>
                <td>@emp.LastLogin</td>
                <td>@emp.EmailAddress</td>
            </tr>
         }
         </tbody>
</table>

From this link I was able to achieve the UI whatever given in the link

var table; //global variable
$('.loadEmployee').on('click',function(){
   $("#loadBody").load("/Admin/GetEmployeeDetails",function(){
         table=$("#employee").dataTable({
               "columns": [
                {
                    "className":      'details-control',
                    "orderable":      false,
                    "data":           null,
                    "defaultContent": ''
                },
                { "data": "Full Name" },
                { "data": "Account Status" },
                { "data": "Last Login" },
                { "data": "Email Address" }
                ],
                "order": [[1, 'asc']]
         });
   }
})

function format ( d ) {
    // `d` is the original data object for the row
    return '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
        '<tr>'+
            '<td>Full name:</td>'+
            '<td>'+d["Full Name"]+'</td>'+ //this is fine
        '</tr>'+
        '<tr>'+
            '<td>Extension number:</td>'+
            '<td>'+d["Contact Details"]+'</td>'+ //Need to get Contact here
        '</tr>'+
        '<tr>'+
            '<td>Gender:</td>'+
            '<td>d["Gender"]</td>'+ //Need to get Gender here
        '</tr>'+
    '</table>';
}

// Add event listener for opening and closing details
$('#employee tbody').on('click', 'td.details-control', function () {
    var tr = $(this).closest('tr');
    var row = table.row( tr );

    if ( row.child.isShown() ) {
        // This row is already open - close it
        row.child.hide();
        tr.removeClass('shown');
    }
    else {
        // Open this row
        row.child( format(row.data()) ).show();
        tr.addClass('shown');
    }
 });

My question here is:

I have model filled with all the data but how to display the extra data which is in the model (Contact),(Gender) in format function

The demo given in the above link uses .txt files to extract data but nowhere it is mentioned how to do this with model data according to my above scenario. The + link and - links are working fine except the model values for Contact and Gender are not getting displayed. One scenario I am thinking of is add all these as tds in foreach and hide them so that I can get the column values as I am getting now for displayed data. But then this would be heavy when there is huge amount of columns to be displayed. Any ideas/lights on this is much appreciated.

Guruprasad J Rao
  • 29,410
  • 14
  • 101
  • 200
  • 1
    You could add the values as `data-*` attributes, perhaps to the `` element - `` and then get them in the `$('#employee tbody').on('click', 'td.details-control', function () {` function using `var contact = tr.data('contact');` etc and pass those values to your `format()` function –  Aug 25 '15 at 04:34
  • Oh yea!! Come on!! How silly I missed this part.. :) Please post this as answer @StephenMuecke and I shall accept it.. :) but one more doubt here.. If you have seen that link they get data from some `txt` file and they bind but still `data` which aren't displayed were able to be fetched from `row.data()`? How does that work? any idea.. :) – Guruprasad J Rao Aug 25 '15 at 04:42
  • Don't use the dataTable plugin so not sure, but I'll have look a bit later and see what I can find out –  Aug 25 '15 at 04:44
  • Sure buddy @StephenMuecke and please do post it as answer.. :) – Guruprasad J Rao Aug 25 '15 at 04:45
  • 1
    OK, I think I know whats happening. The example you linked to is using a `datasource` to populate the table, in this case `../ajax/data/objects.txt` which is json data (you can see it by clicking on the Ajax tab of the example) so the `"ajax": ...` option reads the data and stores it (I assume as `data-*` attributes in each row). Because the json includes a property for `extn` its value is stored even though its not displayed in a column. I presume that the `row.data()` function then read these values so they are available. –  Aug 25 '15 at 05:29
  • Yea I saw that part but couldn't grasp much on that, but I think it is not stored as `data-*` because I inspected the table row and did not found it there.. May be some other technique.. Better I need to see `data()` function and understand what's happening there.. :) – Guruprasad J Rao Aug 25 '15 at 05:33
  • 1
    Much the same as per my answer (the only difference being because the `data-*` attributes are added programatically, you don't see them when viewing the page source). I suspect if you were to use `"ajax": '@Url.Action(someMethod)` that initialized your collection and had `return Json(model, JsonRequestBehavior.AllowGet);` you would access to the other properties in the `d` object –  Aug 25 '15 at 05:34
  • You don't physically see `data-` attributes if you add them using javascrip/jquery which would explain why you don't see them –  Aug 25 '15 at 05:37
  • Agree, but then there is a huge process. When I opt for that particular approach it makes me to write my own `filtering`, `sorting` etc., functionalities which is a headache again. But my doubt was if it was using `data-*` shouldn't that be visible on Inspect Element? But it is 100% true as you said that I need to use `ajax` property of `dataTables` to get all the values in `d` object.. :) – Guruprasad J Rao Aug 25 '15 at 05:38
  • Oh alright.. Never knew about hiding attributes.. :) – Guruprasad J Rao Aug 25 '15 at 05:39

1 Answers1

3

One option would be to add the 'extra' values as data-* attributes in the table row.

@foreach(var emp in Model)
{
  <tr data-contact="emp.contact" data-gender="emp.Gender">
    ....
  </tr>
}

and then extract them in the buttons click event and pass those values to the format() function

$('#employee tbody').on('click', 'td.details-control', function () {
  var tr = $(this).closest('tr');
  var contact = tr.data('contact');
  var gender = tr.data('gender');
  // you could also add the following as an option to using the row data
  var fullName = tr.children('td').eq(1).text();
  var row = table.row( tr );
  if ( row.child.isShown() ) {
    // This row is already open - close it
    row.child.hide();
    tr.removeClass('shown');
  } else {
    // Open this row
    row.child(format(row.data(), contact, gender)).show();
    // or row.child(format(fullName, contact, gender)).show();
    tr.addClass('shown');
  }
});

and then change the format() function to accept the additional parameters

function format(d, contact, gender) {