Search code examples
javascripthtmljquerydatatables

how to truncate a field data in datatable and add <more options> towards the end to view the entire field data?


I am using datatable to display a report in my application. Some of the columns have huge data which I want to truncate the view and add a clickable option towards the end so that a user can click it to view the entire content of a call.

I have tried using ellipsis render to transform the data using substring but it is not a feasible solution as I have download option as well in my table. If i use renderer the downloaded report also shows the truncated format.

Please suggest how can i achieve this as the table has download functionalities too? https://jsfiddle.net/jwrmgbnc/3/

Below is the sample code for the same:

$(document).ready(function() {
 $("#TableName").Datatable( {
    language: { "search": "Filter"},
    paging: false,
    info: true,
    scrollY:'50px',
    scrollCollapse: true,
    scrollX: false,
    
   });
});

Solution

  • One approach to handle this is to:

    1. Create an extra "Description" column, which contains the same data as the original "Description" column.

    2. Hide this extra column.

    3. Apply truncation to the original (visible) "Description" column.

    4. Customize the Excel export button so that it skips the original "Description" column (with its potentially truncated data), and only export the hidden column.

    Example data row:

    <tr>
        <td>NumberYYYYYY</td>
        <td>S3 </td>
        <td>Description again is very very very very very very long. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</td>
        <td>Description again is very very very very very very long. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</td>
        <td>Firewall Operations</td>
        <td>Assignee2</td>
        <td>Impact2</td>
    </tr>
    

    For convenience, I will use the DataTables ellipsis renderer for text truncation - but you can use whatever you prefer, if that does not work for you:

    <script type="text/javascript" src="https://cdn.datatables.net/plug-ins/1.10.24/dataRender/ellipsis.js"></script>
    

    In this approach, you can see the full text of the field as a tooltip, by hovering over the truncated text. If that is not suitable, see the final section below.

    Then, the DataTable definition becomes this:

    $(document).ready(function() {
    
      $('#TableName').DataTable( {
        dom: 'Brftip',
        columnDefs: [
          { 
            targets: [2], 
            render: $.fn.dataTable.render.ellipsis( 40 )
          },
          { 
            targets: [3],
            visible: false 
          }
        ],
        buttons: [
          { 
            extend: 'excelHtml5', 
            text: 'To Excel',
            exportOptions: {
              columns: [0, 1, 3, 4, 5, 6]
            }
          }
        ]
      } );
    
    } );
    

    Longer text will be displayed in the DataTable truncated to 40 characters.

    The Excel exporter will skip the visible "Description" column: columns: [0, 1, 3, 4, 5, 6]


    Enhancing the display

    You can enhance the above solution to provide a "more" button which, when clicked, will show the full text instead of truncated text.

    The button is styled to look like a link, to be less intrusive:

    .more-button {
      background: none!important;
      border: none;
      padding: 0!important;
      /*optional*/
      font-family: arial, sans-serif;
      /*input has OS specific font-family*/
      color: #069;
      text-decoration: underline;
      cursor: pointer;
    }
    

    The render function for column index 2 is then changed to be as follows:

    { 
      targets: [2], 
      render: function ( data, type, row, meta ) {
        if (type === 'display') {
          if ( data.length > 40)  {
            return '<span>' + data.substr( 0, 38 ) + '... </span>' +
                '<button class="more-button" onclick="showMore(this, ' + meta.row + ')">more</button>' ;
          } else {
            return data;
          }
        } else {
          return data;
        }
      }
    },
    

    The showMore() function:

    function showMore(node, rowId) {
      var rowData = $('#TableName').DataTable().rows( rowId ).data().toArray()[0];
      var fullText = rowData[3];
      $( node.parentNode ).text( fullText );
    }
    

    This is a fairly basic feature - you cannot re-hide the text unless you refresh the table.