Rendering a varying number of buttons in a column

Rendering a varying number of buttons in a column

SaxonSaxon Posts: 3Questions: 1Answers: 0
edited June 2017 in Free community support

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'/>&nbsp;" +
                            $"<img class='ui-icon deactivateAsset' title='Deactivate' data-assetId='{assetInfo.AssetId}' src='img/Icon_Delete.png'/>&nbsp" +
                            $"<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

  • SaxonSaxon Posts: 3Questions: 1Answers: 0

    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})'/>&nbsp" +
    $"<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?

  • SaxonSaxon Posts: 3Questions: 1Answers: 0
    edited June 2017

    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.

  • bindridbindrid Posts: 730Questions: 0Answers: 119

    Try this:

    $("#tblAssets").on("click", ".editAsset", function(){ do your thing});
    
  • bindridbindrid Posts: 730Questions: 0Answers: 119

    In nutshell, when you bind your event, .editAsset may or may not exist yet but the tblAssets does.

  • bindridbindrid Posts: 730Questions: 0Answers: 119

    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

    $(document).ready(function () {
        
        $('#example').on("click", ".fa-floppy-o", function(){
            
           alert(this.className);
        })
    

    near the top

This discussion has been closed.