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 (
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> '
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:
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>