PVR
GitHub

Tables

Plain Bootstrap tables and interactive DataTables, with configuration and examples.

3 min read
Updated June 20, 2026

Two kinds of tables ship with the kit: plain Bootstrap tables (regularTables.html) and interactive DataTables (dataTableDefault.html and the master/list pages such as roleMaster.html).

Plain Bootstrap tables — regularTables.html

↗ View live demo

Wrap any table in .table-responsive for horizontal scroll on small screens:

<div class="table-responsive">
  <table class="table table-striped table-bordered table-hover">
    <thead>
      <tr><th>Name</th><th>Role</th><th>Status</th></tr>
    </thead>
    <tbody>
      <tr><td>Jane</td><td>Admin</td><td><span class="badge badge-green">Active</span></td></tr>
    </tbody>
  </table>
</div>

Modifiers (combine freely): table-striped, table-bordered, table-borderless, table-hover, table-sm, table-dark. Color a single row/cell with the contextual classes table-primary, table-success, table-danger, table-warning, table-info.

DataTables — the kit's standard list table

The interactive list pages all follow the same recipe: a table with id="initDataTable" wrapped in .table-responsive.dt-wrapper, initialized in the page script using the app.datatables helpers (toolbar, serial numbers, processing state, expandable rows).

Markup

<div class="table-responsive dt-wrapper">
  <table class="table table-striped table-bordered w-100 nowrap" id="initDataTable">
    <thead>
      <tr>
        <th></th>                                <!-- expand control -->
        <th>S.No</th>
        <th class="apply_search">Role</th>       <!-- text filter -->
        <th class="apply_search">Description</th>
        <th class="apply_select">Status</th>     <!-- dropdown filter -->
        <th>Users</th>
        <th>Action</th>
      </tr>
    </thead>
  </table>
</div>
  • apply_search — render a per-column text filter for this column.
  • apply_select — render a per-column dropdown filter for this column.
  • The first empty <th> is the row-expand toggle (optional).

Initialization (real pattern from roleMaster.js)

Page scripts define a small object and initialize the table in its init():

"use strict";
var roleMaster = {
    renderers: {
        actionButtons: function () {
            return app.datatables.renderers.actionButtons([
                { className: 'btn-view', icon: 'visibility', title: 'View' },
                { className: 'btn-edit', icon: 'edit',       title: 'Edit' }
            ]);
        }
    },
    getColumns: function () {
        var self = this;
        return [
            { className: 'details-control', orderable: false, data: null,
              defaultContent: '<span class="material-symbols-sharp">add_circle</span>' },
            { data: null, orderable: false, className: 'text-center serial-number', defaultContent: '' },
            { data: 'role' },
            { data: 'description' },
            { data: 'status' },
            { data: 'totalUsers', className: 'text-center' },
            { data: null, orderable: false, className: 'text-center',
              render: function () { return self.renderers.actionButtons(); } }
        ];
    },
    callbacks: {
        onInitComplete: function (settings, json, table) {
            app.datatables.initToolbar(this.api(), table, {
                expandButton: true,
                addButton: { text: 'Add Role', href: 'addRoleMaster.html' }
            });
        },
        onDraw: function () {
            app.datatables.renderSerialNumbers(this.api(), 1);   // serial # in column index 1
        }
    },
    table: null,
    init: function () {
        var self = this;
        app.datatables.initProcessingState('#initDataTable');
 
        self.table = $('#initDataTable').DataTable({
            dom: app.datatables.getDom(),
            processing: true,
            scrollX: false,
            autoWidth: false,
            ajax: {
                url: API_CONFIG.getUrl(API_CONFIG.endpoints.RoleMaster.getRoleMaster),
                dataSrc: 'data'
            },
            columnDefs: [
                { width: '60px',  targets: 0, orderable: false },
                { width: '80px',  targets: 1, orderable: false },
                { width: '120px', targets: 6 }
            ],
            columns: self.getColumns(),
            order: [[1, 'asc']],
            initComplete: function (settings, json) {
                self.callbacks.onInitComplete.call(this, settings, json, self.table);
            },
            drawCallback: self.callbacks.onDraw
        });
 
        app.datatables.initExpandEvents(self.table, self.formatExpandedRow);
    },
    main: function () { this.init(); }
};
 
$(document).ready(function () { roleMaster.main(); });

What the helpers do (full reference in 08 — JavaScript):

HelperPurpose
app.datatables.getDom()Standard DOM layout (length menu, filter row, table, info, paging).
app.datatables.initToolbar(api, table, opts)Adds the toolbar — addButton, expandButton, filter button.
app.datatables.renderers.actionButtons([…])Renders the row action icon buttons.
app.datatables.renderSerialNumbers(api, colIndex)Fills the running S.No column.
app.datatables.initProcessingState(selector)Shows the themed loading state.
app.datatables.initExpandEvents(table, formatFn)Wires the row-expand child rows.

Static data: the example loads rows via ajax from your backend (see 08 — JavaScript › API_CONFIG). For a self-contained demo you can drop the ajax option and put <tbody> rows directly in the HTML instead.

DataTables variants

Demo pages showing optional DataTables extensions. The markup/init is the same base recipe plus one option or class:

PageAddsEnabled by
dataTableDefault.htmlThe standard list table.base recipe
dataTableResponsive.htmlColumns collapse on small screens.responsive: true
dataTableButtons.htmlCopy / Excel / PDF / Print export buttons.Buttons extension in dom / buttons: [...]
dataTableAjax.htmlServer-side / AJAX-sourced data.ajax: { url, dataSrc }
dataTableSelect.htmlSelectable rows (checkbox column).Select extension / select: true
dataTableFixedHeader.htmlHeader stays visible while scrolling.fixedHeader: true
dataTableFixedColumns.htmlPin left/right columns.fixedColumns
dataTableScroller.htmlVirtual scrolling for large sets.scroller: true
dataTableRowGroup.htmlGroup rows under headings.rowGroup
dataTableRowreorder.html / dataTableColreorder.htmlDrag to reorder rows / columns.RowReorder / ColReorder
dataTableKeytable.htmlKeyboard cell navigation.KeyTable
dataTableAutofill.htmlDrag-fill across cells.AutoFill
dataTableCombine.htmlSeveral extensions together.combined options

All DataTables plugins and extensions are bundled under assets/plugins/DataTables/.

Was this page helpful?