Rendering a varying number of buttons in a column
Rendering a varying number of buttons in a column
I have a table that, based on a value in the data source, needs to render anywhere from one to three buttons. I found a page showing an example of how to use defaultContent to render a single button: https://datatables.net/reference/option/columns.defaultContent
However, that doesn't describe what to do when you have to render a varying number of buttons. I thought maybe I could pass a function to defaultContent but then I didn't know how to access the data to determine which buttons to render.
I actually already successfully render the buttons by including the html in the data, Below is an example of the code that generates the html for those buttons. A list of "assetInfo" objects is provided to the table. The jquery function provided at the bottom of this message, named getAssets(), retrieves the data for the table and then wires-up the "click" event to the buttons. You may be asking yourself then, "why am I posting this question here if I am already rendering buttons?" Sadly, this solution only sometimes works. I'll explain in a moment. As a result, I started questioning my implementation and began looking to see how datatables recommends rendering buttons in the table. That's when I discovered the above reference. At this point, I find myself with only a partial understanding of how to solve the problem.
The problem I'm having with my current implementation is that, when a user changes pages, sorts columns, searches, etc., the buttons often become un-clickable.
So, I either need to solve the problem of un-clickable buttons or change how I am rendering the buttons and wiring them up to the click event. What is the best way to render a varying number of buttons in each row?
Thank you.
Saxon
---- code sample showing the logic I am using to generate html to render multiple buttons ----
if (assetInfo.Status == "Available")
{
assetInfo.Actions =
$"<img class='ui-icon editAsset' title='Edit' data-assetId='{assetInfo.AssetId}' src='img/Icon_Edit.png'/> " +
$"<img class='ui-icon deactivateAsset' title='Deactivate' data-assetId='{assetInfo.AssetId}' src='img/Icon_Delete.png'/> " +
$"<img class='ui-icon transferAsset' title='Transfer' data-assetId='{assetInfo.AssetId}' src='img/Icon_Transfer.png'/>";
}
else if (assetInfo.Status == "Assigned")
{
assetInfo.Actions =
$"<img class='ui-icon editAsset' title='Edit' data-assetId='{assetInfo.AssetId}' src='img/Icon_Edit.png'/>";
}
else //Deactivated
{
assetInfo.Actions =
$"<img class='ui-icon editReactivate' title='Reactivate' data-assetId='{assetInfo.AssetId}' src='img/Icon_Reactivate.png'/>";
}
----- The javscript function and ajax call that populates the table and wires-up the buttons to the click event ----
function getAssets() {
$.ajax({
type: "POST",
url: "Assets.aspx/GetAssets",
data: "{organizationId: " + $("#ddAssetOrganization").val() + "}",
datatype: "json",
contentType: "application/json; charset=utf-8",
success: function (response) {
if (response.d.Success) {
if (!$.fn.dataTable.isDataTable("#tblAssets")) {
dtAssets = $("#tblAssets")
.DataTable(
{
data: response.d.AssetInfoList,
columns: [
{ data: 'AssetTagNumber', "title": "Asset #" },
{ data: 'SimNumber', "title": "SIM #" },
{ data: 'IMEI', "title": "IMEI" },
{ data: 'SerialNumber', "title": "Serial #" },
{ data: 'Status', "title": "Status" },
{
data: 'Actions',
"orderable": false,
"searchable": false,
"title": "Actions"
}
],
order: [[0, "asc"]]
});
} else {
dtAssets.clear();
dtAssets.rows.add(response.d.AssetInfoList).draw();
}
$("#tblAssets").show();
$(".editAsset").click(function () {
$("#divAssetMessage").hide();
$("#ulErrors").remove();
getAssetDetail($(this).attr("data-assetId"));
$("#assetDialog").dialog({
title: "Edit Asset",
buttons:
{
"Update": function () {
updateAsset();
},
"Cancel": function () {
$("#assetDialog").dialog('close');
}
}
});
$("#assetDialog").dialog('open');
});
} else {
alert(response.d.ErrorMessage);
}
},
failure: function (response) {
alert('Error getting the asset: ' + response.d);
}
});
}
Answers
I thought I had a solution. The problem may not be what I thought it was. I refactored the above code thusly:
1) when rendering the buttons, use an "onclick" event as shown:
$"<img class='ui-icon' title='Edit' src='img/Icon_Edit.png' onclick='openEditAssetDialog({assetInfo.AssetId})'/> " +
$"<img class='ui-icon' title='Deactivate' src='img/Icon_Delete.png' onclick='openDeactivateAssetDialog({assetInfo.AssetId})'/> " +
$"<img class='ui-icon' title='Transfer' src='img/Icon_Transfer.png' onclick='openTransferAssetDialog({assetInfo.AssetId})'/>";
2) In the previous javascript function, extract the click event code out into it's own function which is called by the above onclick event.
I really thought this was going to work but, still, the images are un-clickable after paging to the next page in the table. Why?
The solution in the previous comment does work after all. But I would be interested in learning if there is a better way to do this.
Try this:
In nutshell, when you bind your event, .editAsset may or may not exist yet but the tblAssets does.
To make my point, I made the font awesome icons clickable even before the $("#example").DataTable is executed at http://jsbin.com/herehoc/54/edit
This example was written for someone else but you will see where I added
near the top