Home > OS >  Dynamically Render Columns In DataTable - Column.Render Property
Dynamically Render Columns In DataTable - Column.Render Property

Time:10-24

I am working on developing a dynamic DataTable in which the data source is dynamically generated with [n] columns, where the data source may contain 4 columns or 6 columns as an example. As per this post on the DataTables forum (Data Source

Rendered Table: DataTable

My question regards the empty final column of the table, in which I need to render a button. I would have normally written something along the lines of the code below, if I had been wanting to render a table with known column values, in which I would use the DataTable property column.Render. As you can see below, using the data property of the column, I can use create a function to render a button, which can be used to quick navigate to the Contact/Edit page passing the "id" as a Url route value, meaning that it is possible to edit the specific details of the choosen contact.

 <script>
    var dataToSend = {};
    var contactDataTable;

    dataToSend = {
       "regionId": @Model.RegionId
    };

    $(function () {
        contactDataTable = {
            dt: null,

            init: function () {
                dt = $('#contact-data-table').DataTable({
                    ajax: {
                        type: "GET",
                        url: "@Url.Action("GetDataForGrid", "Contact")",
                        data: function () {
                            return dataToSend;
                        },
                        datatype: "json",
                        dataSrc: ""
                    },
                    columns: [
                        {
                            "title": "Forename",
                            "data": "forename",
                            "searchable": true,
                        },
                        {
                            "title": "Surname",
                            "data": "surname",
                            "searchable": true,
                        },
                        {
                            "title": "Email",
                            "data": "email",
                            "searchable": true
                        },
                        {
                            "Status":
                            "status":
                            "searchable":
                        },
                        {
                            "title": "Role",
                            "data": "roleName",
                            "searchable": true
                        },
                        {
                            "title": "",
                            "data": "id",
                            "searchable": false,
                            "sortable": false,
                            "render": function (data, type, full, meta) {
                                var buffer = '<a href="@Url.Action("Edit","Contact")/'   data    '" ><i ></i></a>&nbsp;'

                                buffer  = '<a href="@Url.Action("Delete", "Contact")/'   data   '" ><i ></i></a>';

                                return buffer;
                            }
                        }
                    ],
                    columnDefs: [
                        { "width": "15%", "targets": 0 },
                        { "width": "15%", "targets": 1 },
                        { "width": "20%", "targets": 2 },
                        { "width": "15%", "targets": 3 },
                        { "width": "15%", "targets": 4 },
                        { "width": "20%", "targets": 5 },
                    ],
                    lengthMenu: [[10, 25, 50, 100], [10, 25, 50, 100]],
                });
            },
            refresh: function () {
                dt.ajax.reload();
            }
        }
</script>

How can I achieve the same principle of rendering a button in my table if I am defining and building my column defintion variable before passing this to my DataTable intialization?

Any help would be great.

CodePudding user response:

A simple solution to the given problem is to use the Column.defaultContent property and a custom onClick event that can be used to construct the relevant URL required.

In the example below, I've modified my dtColumns array as seen in the provided image, so that the relevant object contain a definition for defaultContent, set to a string that will render a simple button. For the defaultContent to be used by the DataTable, you must set the Data property to null.

DataTable - Data Source

var myColumnDefs = [
        { title: "Forename", data: "forename", width: "15%"},
        { title: "Surname", data: "surname", width: "15%"},
        { title: "Email", data: "email", width: "20%"},
        { title: "Status", data: "status", width: "15%"},
        { title: "Role", data: "roleName", width: "15%"},
        { title: "", data: "(string)null", width: "20%", searchable: false, sortable: false, defaultContent: "<a id='btnEdit' class='btn btn-sm btn-primary js-action'><i class='fas fa-edit'></i></a>"}
    ]

In doing so, a table such as the one below is rendered:

Rendered DataTable

The modified code really only includes extra functions to handle the onClick event of the buttons. In this case, I can obtain the data of the loaded record by using $("#dataTable").DataTable().row((selectedRow).parents("tr")).data(), in which the id property can be accessed. Using this Id value I was then able to construct the desired URL which happens to be passed into a function that renders a Bootstrap Modal.

    <script>
    var dataToSend = {};
    var dataTable;

    // Set Data To Send
    dataToSend = {
        "regionId": "@Model.RegionId"
    }

    // Get Column Defintions
    var dtColumns = @Html.Raw(Json.Serialize(listOfDefintions));

    // DataTable
    $(function () {
        dataTable = {
            dt: null,

            init: function () {
                dt = $("#dataTable").DataTable({
                    ajax: {
                        type: "GET",
                        url: "@Url.Action("GetDataForGrid", "Contact")",
                        data: function () {
                            return dataToSend;
                        },
                        datatype: "json",
                        dataSrc: ""
                    },
                    columns: dtColumns,
                    lengthMenu: [[10, 25, 50, 100], [10, 25, 50, 100]],
                });
            },
            refresh: function () {
                dt.ajax.reload();
            }
        }

        dynaGridDataTable.init();


        // DataTable Buttons
        $("#dataTable").on("click", ".js-action", function (event) {
            var btnId = $(this).attr("id");
            var recordId = getRecordId($(this));

            if (btnId !== undefined && btnId == "btnEdit") {
                // Create Edit URL
                var href = '@Url.Action("Popup", "DynaGrid")[email protected]&[email protected]&id='   recordId   '';
                
                renderModalForDataTableButton(href);
            } else if (btnId !== undefined && btnId == "btnDelete") {
                // Code 
                
            } else {
                alert("Something Went Wrong - Unable To Redirect");
            }
        });

        // Get Record Id Of Current Row
        function getRecordId(selectedRow) {
            var data = $("#dataTable").DataTable().row((selectedRow).parents("tr")).data();
            return data.id;
        }

        function renderModalForDataTableButton(href) {
            $.get(href, function (data) {
                $('#myModalContent').html(data);
                $('#myModal').modal('show');
            });
        }
    });
</script>
  • Related