Intuition

The client requires a table with the following features:

  • Search functionality via an input field
  • Column-based sorting
  • Pagination support

The table should accept a CSV file as input. The CSV data may include HTML tags such as <b>, <i>, or <sup>, which must be rendered correctly with their respective styles.

We were originally was using the DVF (Data Visualisation Framework) modules to achieve this feature, along with some other stuff like charts and graphs, but since it is a modules only used by few, the maintainers don’t seems to have intention of making it Drupal 11 compatible (despite the fact there’s already a merge request).

So we need to swap it out with alternative solution. Borrowing from the code of the DVF modules, I found it is possible to using the DataTables JavaScript Library to turn a normal table into interactive ones; and the TableField module seems to be a viable solution (to use CSV file to create table) that will gain long term support, because it is used by lots (19,188 site usage as of November 2025)

Solution

First, install the TableField module via the following:

1
2
composer require 'drupal/tablefield'
drush pm:install tablefield

and modify the table.html.twig file to add |raw twig filter for tables created using the TableField modules, for instance, the table body will need to be modified:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
...
	<tbody>
      {% for row in rows %}
		...
        <tr{{ row.attributes.addClass(row_classes) }}>
          {% for cell in row.cells %}
            <{{ cell.tag }}{{ cell.attributes }}>
+               {% if attributes.hasClass('tablefield') %}
+                   {{- cell.content|raw -}}
+               {% else %}
+                   {{- cell.content -}}
+               {% endif %}
-				{{- cell.content -}}
            </{{ cell.tag }}>
          {% endfor %}
        </tr>
...

(example file: table.html.twig)

Second, to include DataTable JavaScript library to the equation, we’ can add it to the theme level and use it against all the tables created using TableField modules (<table> that have .tablefield classname):

File: your_theme_name.libraries.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
datatable:
  version: VERSION
  css:
    theme:
      //cdn.datatables.net/2.3.5/css/dataTables.dataTables.min.css:
        weight: -10
  js:
    //cdn.datatables.net/2.3.5/js/dataTables.min.js: {}
    js/index-DataTable.js: {}
  dependencies:
    - drupal/datatables

File: index-DataTable.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
(function($, Drupal, once) {
  'use strict';
  Drupal.behaviors.bootstrapDatatable = {
    attach: function(context, settings) {
    document.querySelectorAll("table.tablefield").forEach(function(_table_) {
        let table = new DataTable(_table_);
      });
    }
  };
})(jQuery, Drupal, once);

2025-11-28T095011

Outcome

2025-11-28T095640

Reference