简体   繁体   中英

How to bind an ActionLink for DataTable row click event?

I have a server-side dataTable where when I click each row, I want it to show its Edit and Delete action links for the user to click on it and be directed to those pages.

    @*<td>
       @Html.ActionLink("Edit", "Edit", new { id = item.DepartmentID }) |
       @Html.ActionLink("Details", "Details", new { id = item.DepartmentID }) |
       @Html.ActionLink("Delete", "Delete", new { id = item.DepartmentID })
    </td>*@

When I search on their website, they use the editor for datatables. But I am not able to implement the actionlinks with the editor for many undefined errors.

Can someone please assist me to figure out how to make the on click event work?

This is the script for the dataTable

     init: function () {
       dt = $('#datatableServer').DataTable({
                    "serverSide": true,
                    "processing": true,
                    "ajax": {
                        "url":
                        "@Url.Action("DataHandler","Department")"
                    },
                    "columns": [
                        { "data": "Name",
                        "searchable": true },
                        {
                         "data": "Budget", "render": $.fn.dataTable.render.number(',', '.', 0, '$'),
                        "searchable": false },
                        { "data": "StartDate",
                            "searchable": false,
                            "type" : "datetime"},
                        { "data": "Administrator",
                        "searchable": true }
                    ],
                 ............ 
               departmentsList.init();});


$('#datatableServer tbody').on('click', 'tr', function () {

            //editor.edit(this, 'Edit record', {
                //"label": "Update",
                //"fn": function () {
                    //editor.submit()
                //}
            //})
            console.log('clicked');
            console.log(dt.row(this).data().DT_RowId);  // DT_RowId is each row's Id
        });

I have the DT_RowId getting the id for each table row for my data.

var data = query.Select(a => new DepartmentData
                {
                    DT_RowId = a.DepartmentID.ToString(),
                    Name = a.Name,
                   ..........
                }).ToList();

First thing first

When I have them in my , my dataTable does not show.

The number in your column should match the number of you have. From what i can see, you specified 4 columns

"columns": [
    { "data": "Name", "searchable": true },
    { "data": "Budget", "render": $.fn.dataTable.render.number(',', '.', 0, '$'), "searchable": false },
    { "data": "StartDate", "searchable": false, "type" : "datetime"}, 
    { "data": "Administrator", "searchable": true }
]

but you also have an action column where your Actionlinks sit. So i suggest adding an addtional data column

{ data: "Action" }

Also make sure your have five header columns too

<thead>
    <tr>
        <th>Name</th>
        <th>Budget</th>
        <th>StartDate</th>
        <th>Administrator</th>
        <th>Action</th>
    </tr>
</thead>

Now next thing, i haven't acutally tried to use their editor before, the way i do it is to use my own modal, any modal will do, bootstrap modal is an good option.

For example, you specify a modal in your dataTable view, I place it at the end of the page

<div id="companyModal" class="modal hide" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="false">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                <h3 id="myCompanyModalLabel"></h3>
            </div>
            @{Html.RenderAction("CompanyModal", "CV");}
        </div>
    </div>
</div>

I like to use ViewModal in my modal, so i do RenderAction to get all the goodies from ViewModal validation. Of course, you can do @Html.Partial() too instead of RenderAction, RenderAction only if you want to get some value for the ViewModel before returning it.

 [ChildActionOnly]
 public ActionResult CompanyModal()
 {
    var model = new CompanyViewModel();
    return PartialView("~/Views/Dashboard/CV/_CompanyModal.cshtml", model);
 }

The partial view:

@model XXX.CompanyViewModel

<form id="companyForm" style="margin: 0px;">
    @Html.AntiForgeryToken()
    <div class="modal-body">
        @Html.HiddenFor(m => m.CompanyId)
        <div class="row-fluid">
            <div class="span6">
                @Html.LabelFor(m => m.CompanyName)
                @Html.TextBoxFor(m => m.CompanyName, new { @class = "input-block-level" })
                @Html.ValidationMessageFor(m => m.CompanyName)
            </div>
            <div class="span6">
                @Html.LabelFor(m => m.JobTitle)
                @Html.TextBoxFor(m => m.JobTitle, new { @class = "input-block-level" })
                @Html.ValidationMessageFor(m => m.JobTitle)
            </div>
        </div>
    </div>
    <div class="modal-footer">
        <button type="button" class="btn btn-white" data-dismiss="modal">Close</button>
        <button id="companyEditSubmitBtn" name="edit" class="ladda-button btn btn-primary" data-style="zoom-in" data-spinner-size="25" type="button">Save</button>
    </div>
</form>

Now on to the script:

//init dataTable
var cTable = $("#company-table").dataTable();

//open work experience edit modal
$("#company-table").on("click", ".companyEditBtn", function () {
        //do
        $("#myCompanyModalLabel").text("Edit Work Experience");

        //get current position
        position = cTable.fnGetPosition((this).closest("tr"));
        data = cTable.fnGetData(position);

        //set values to modal
        $("#companyModal #CompanyId").val(data[0]);
        $("#companyModal #CompanyName").val(data[1]);
        $("#companyModal #JobTitle").val(data[2]);

        //open modal
        $("#companyModal").modal("show");
    });

After you open the modal, post the value to your server to save using ajax:

//work experience edit
$("#companyEditSubmitBtn").click(function () {
        //get the form
        var form = $("#companyForm");
        //validate form
        if (!form.valid()) {
            return;
        }
        //serialize the form
        serializedForm = form.serialize();

        //ajax post
        $.ajax({
            url: "@Url.Action("CompanyEdit", "CV")",
            type: "POST",
            data: serializedForm,
            beforeSend: function () {
                l.ladda("start");
            },
            success: function (result) {
                if (result.success) {
                    //update row of table
                    cTable.fnUpdate([
                        result.id,
                        result.name,
                        result.title,
                        "<button class='companyEditBtn btn' title='Edit Work Experience'><i class='icon-pencil'></i></button>" + " " + "<button class='companyDeleteBtn btn' title='Delete Work Experience'><i class='icon-trash'></i></button>"
                    ], position);

                    toastrSuccess(result.message);
                } else {
                    toastrError(result.message);
                }
            },
            error: function (jqXHR, textStatus, errorThrown) {
                toastrError(textStatus);
            },
            complete: function () {
                //stop ladda button loading
                l.ladda("stop");
                //hide modal
                $(".modal").modal("hide");
            }
        });
    });

And your edit controller

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CompanyEdit(CompanyViewModel model)
{
        if (ModelState.IsValid)
        {
            var company = repository.FindCompany(model.CompanyId);

            if (company != null)
            {
                try
                {
                    //map automapper
                    model.Description = model.Description.Replace(Environment.NewLine, "<br />");
                    mapper.Map(model, company);

                    repository.EditCompany(company);
                    return Json(new { success = true, message = "Wokr Experience Edited", id = company.CompanyId, title = company.JobTitle, name = company.CompanyName });
                }
                catch (Exception ex)
                {
                    return Json(new { success = false, message = string.Format("{0}", ex) });
                }
            }
            else
            {
                return Json(new { success = false, message = "Work Experience not found" });
            }
        }
        return Json(new { success = false, message = "Modal state is not valid" });
    }

Another thing to mention, instead of using a foreach loop, use DisplayTemplate,

where the Companies property is an IEnumerable which will automatically do the looping and render the CompanyViewModel.cshtml display template for each item of this collection.

Source here

<table id="company-table" class="table table-striped table-bordered table-hover dataTables" width="100%">
    <thead>
        <tr>
            <th>ID</th>
            <th>Company</th>
            <th>Title</th>
            <th>Action</th>
        </tr>
    </thead>
    <tbody>
        @Html.DisplayFor(m => m.Companies)
    </tbody>
    <tfoot>
        <tr>
            <th>ID</th>
            <th>Company</th>
            <th>Title</th>
            <th>Action</th>
        </tr>
    </tfoot>
</table>

And specify your display template inside Shared -> DisplayTemplates -> CompanyViewModel.cshtml

@model Taw.WebUI.Models.CompanyViewModel

<tr>
    <td>
        @Html.DisplayFor(m => m.CompanyId)
    </td>
    <td>
        @Html.DisplayFor(m => m.CompanyName)
    </td>
    <td>
        @Html.DisplayFor(m => m.JobTitle)
    </td>
    <td>
        <button class="companyEditBtn btn" title="Edit Work Experience"><i class="icon-pencil"></i></button>
        <button class='companyDeleteBtn btn' title="Delete Work Experience"><i class="icon-trash"></i></button>
    </td>
</tr>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM