How to show a button, only in specific rows in javascript?

Viewed 52

I have a datatable, with multiple columns. In the last column I have 2 buttons. I would like to show the second button only when a value in another column (Type column) is "2". If its 1 or 3, then hide that button. Any ideas? It's only show and hide the complete column when I tried to do this.

My datatable:

async function loadDesc(mainID) {
    let errDatatableId = '#desc-table';
    if ($.fn.dataTable.isDataTable(errDatatableId)) {
        $(errDatatableId).DataTable().destroy();
    }
    $(errDatatableId).DataTable({
        data: await getDescription(mainID),
        columns: [
            {
                "data": "Description",
                "render": function (data) {
                    return data;
                }
            },
            {
                "data": "User",
                "render": function (data) {
                    return data;
                }
            },
            {
                "data": "Date",
                "render": function (data) {
                    return moment(data).format('YYYY-MM-DD HH:mm');
                }
            },
            {
                "data": "Type",
                "render": function (data) {
                    switch (data) {
                        case 1:
                            return "Done";
                        case 2:
                            return "Modify";
                        case 3:
                            return "Over";
                        default:
                            return "Error";
                    }
                }
            },
            {
                "data": "ID",
                "render": function (data) {
                    return data;
                }
            },
{
                "data": "entityId",
                "render": function (data, type, row, meta) {
                    var sendTime = moment(Date()).format('YYYY-MM-DD HH:mm');
                return `
                <div class="ui icon buttons fluid" style="width:70%;">
                    <button class="firstButton"><i class="icon check"></i></button>
                    <button class="secondButton" hidden><i class="icon pencil"></i></button>
                </div>  
                `;
                }                                   
            }
        ],
        columnDefs: [{
            className: 'dt-nowrap',
            targets: [0, 2]
        }],
        lengthMenu: [
            [30, 100, 300],
            [30, 100, 300]
        ],
        order: [0, 'asc']
    });
}
1 Answers

This solution takes a different approach from what you are trying, by placing the logic you need in the DataTables definition, in another column renderer. In this approach, the second button is simply not drawn at all, if it is not needed.


You can repeat the switch logic in order to determine whether the second button needs to be displayed or not.

You can also move that logic to a separate function, so it can be used in both the relevant columns.

Here is a very basic runnable demo:

var dataSet = [
    {
      "id": "123",
      "name": "Tiger Nixon",
      "position": "System Architect",
      "salary": "$320,800",
      "start_date": "2011/04/25",
      "office": "Edinburgh",
      "extn": "5421"
    },
    {
      "id": "456",
      "name": "Donna Snider",
      "position": "Customer Support",
      "salary": "$112,000",
      "start_date": "2011/01/25",
      "office": "New York",
      "extn": "4226"
    },
    {
      "id": "567",
      "name": "Cedric Kelly",
      "position": "Senior Javascript Developer",
      "salary": "$433,060",
      "start_date": "2012/03/29",
      "office": "Edinburgh",
      "extn": "6224"
    },
    {
      "id": "432",
      "name": "Airi Satou",
      "position": "Accountant",
      "salary": "$162,700",
      "start_date": "2008/11/28",
      "office": "Tokyo",
      "extn": "5407"
    },
    {
      "id": "987",
      "name": "Brielle Williamson",
      "position": "Integration Specialist",
      "salary": "$372,000",
      "start_date": "2012/12/02",
      "office": "New York",
      "extn": "4804"
    }
  ];

$(document).ready(function() {

function doSwitch(data) {
  switch (data) {
    case '432':
      return "Done";
    case '987':
      return "Modify";
    case '567':
      return "Over";
    default:
      return "Error";
  }
}

var table = $('#example').DataTable( {
  data: dataSet,
  columns: [
    { title: "ID", data: "id" },
    { title: "Name", data: "name" },
    { title: "Office", data: "office" },
    { title: "Extn.", data: "extn" },
    { title: "Salary", data: "salary" },
    {
      "title": "switch",
      "data": "id",
      "render": function (data) {
        return doSwitch(data);
      }
    },
    {
      "data": "id",
      "render": function (data) {
        let cellContent = "<button>first</button>";
        let result = doSwitch(data);
        if (result === "Modify") {
          cellContent = cellContent + " <button>second</button>";
        }
        return cellContent;
      }
    }
  ]

} ); 

} );
<!doctype html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Demo</title>
  <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
  <script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
  <link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">

</head>

<body>

<div style="margin: 20px;">

    <table id="example" class="display dataTable cell-border" style="width:100%">
    </table>

</div>


</body>
</html>

The end result looks like this:

enter image description here

This uses ssomewhat contrived test data, but it shows the approach. You can see the doSwitch() function which is called in 2 different places.


Just to note, the column.render function actually takes 4 parameters:

render( data, type, row, meta )

They are documented on this reference page.

The row parameter gives you access to all the data in the row - but that means all the source data before any additional data is generated using render functions. So, unfortunately, we cannot take advantage of that in your case.


UPDATE

I realize the above proposed solution is unnecessarily complicated. You do not need to call the switch function 2 times. You can just use the "data": "Type" values again directly in the column containing your buttons.

Something like this:

{
  "data": "Type",
  "render": function (data, type, row, meta) {
    let cellContent = "<button>first</button>";
    if (data === 2) {
      cellContent = cellContent + " <button>second</button>";
    }
    return cellContent;
  }
}

Sorry about that. Not sure what I was thinking.

Related