Advanced Tables plugin

This plugin is only available for paid TinyMCE subscriptions.

The advtable plugin is a premium plugin that extends the core table plugin by adding the following advanced functionality:

  • Sort options for rows and columns.

  • Row numbering column for tables.

Try our Advanced Tables Demo

  • TinyMCE

  • HTML

  • JS

  • Edit on CodePen

<textarea id="advtable">
  <p>Try sorting by a Student's Assessment Results:</p>
  <ol>
  <li>Select a student's <em>Assessment 1</em> result.</li>
  <li>Right-click and select <strong>Sort</strong> &gt; <strong>Advanced Sort&hellip;</strong></li>
  <li>In the <strong>Advanced Sort</strong> dialog, set:
  <ul>
  <li><strong>Sort by</strong>: Row</li>
  <li><strong>Row</strong>: <em>leave unchanged</em></li>
  <li><strong>Sort</strong>: Table</li>
  <li><strong>Order</strong>: Ascending</li>
  </ul>
  </li>
  <li>Click <strong>Sort</strong>.</li>
  </ol>
  <p>Try sorting by <em>Final Grade</em>:</p>
  <ol>
  <li>Selecting the <em>Final Grade</em> column.</li>
  <li>Right-click and select <strong>Sort</strong> &gt; <strong>Sort table by column descending</strong>.</li>
  </ol>
  <p>Try adding a numeric row numbering column:</p>
  <ol>
  <li>Select any cell in the table</li>
  <li>Click the <strong>Row numbering</strong> button in the toolbar</li>
  <li>Select <strong>Numeric</strong></li>
  </ol>
  <table style="border-collapse: collapse; width: 100%; height: 352px;" border="1">
  <thead>
  <tr style="height: 24px;">
  <th style="width: 14.2857%; border-color: #000000; border-style: groove; text-align: center; height: 24px; background-color: #c2e0f4;">Student ID</th>
  <th style="width: 14.2857%; border-color: #000000; border-style: groove; text-align: center; height: 24px; background-color: #c2e0f4;">Last Name</th>
  <th style="width: 14.2857%; border-color: #000000; border-style: groove; text-align: center; height: 24px; background-color: #c2e0f4;">First Name</th>
  <th style="width: 14.2857%; border-color: #000000; border-style: groove; text-align: center; background-color: #c2e0f4;">Assessment 1 (30%)</th>
  <th style="width: 14.2857%; border-color: #000000; border-style: groove; text-align: center; height: 24px; background-color: #c2e0f4;">Assessment 2&nbsp; (20%)</th>
  <th style="width: 14.2857%; border-color: #000000; border-style: groove; text-align: center; height: 24px; background-color: #c2e0f4;">Assessment 3&nbsp; (50%)</th>
  <th style="width: 14.2857%; border-color: #000000; border-style: groove; text-align: center; height: 24px; background-color: #c2e0f4;">Final Grade</th>
  </tr>
  </thead>
  <tbody>
  <tr style="height: 22px;">
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">41297</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Hisakawa</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Ekin</th>
  <td style="width: 14.2857%; text-align: center;">11</td>
  <td style="width: 14.2857%; text-align: center;">2</td>
  <td style="width: 14.2857%; text-align: center;">41</td>
  <td style="width: 14.2857%; text-align: center;">54</td>
  </tr>
  <tr style="height: 22px;">
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">71215</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Newman</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Logan</th>
  <td style="width: 14.2857%; text-align: center;">24</td>
  <td style="width: 14.2857%; text-align: center;">4</td>
  <td style="width: 14.2857%; text-align: center;">40</td>
  <td style="width: 14.2857%; text-align: center;">68</td>
  </tr>
  <tr style="height: 22px;">
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">53249</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Wilkins</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Kagiso</th>
  <td style="width: 14.2857%; text-align: center;">23</td>
  <td style="width: 14.2857%; text-align: center;">12</td>
  <td style="width: 14.2857%; text-align: center;">46</td>
  <td style="width: 14.2857%; text-align: center;">81</td>
  </tr>
  <tr style="height: 22px;">
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">13965</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Rom&agrave;</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Chibueze</th>
  <td style="width: 14.2857%; text-align: center;">5</td>
  <td style="width: 14.2857%; text-align: center;">20</td>
  <td style="width: 14.2857%; text-align: center;">40</td>
  <td style="width: 14.2857%; text-align: center;">65</td>
  </tr>
  <tr style="height: 22px;">
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">24559</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Jacobs</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Celestine</th>
  <td style="width: 14.2857%; text-align: center;">2</td>
  <td style="width: 14.2857%; text-align: center;">11</td>
  <td style="width: 14.2857%; text-align: center;">26</td>
  <td style="width: 14.2857%; text-align: center;">39</td>
  </tr>
  <tr style="height: 22px;">
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">78321</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Seabrooke</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Agam</th>
  <td style="width: 14.2857%; text-align: center;">5</td>
  <td style="width: 14.2857%; text-align: center;">18</td>
  <td style="width: 14.2857%; text-align: center;">17</td>
  <td style="width: 14.2857%; text-align: center;">40</td>
  </tr>
  <tr style="height: 22px;">
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">19271</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">McKay</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Oluwayemisi</th>
  <td style="width: 14.2857%; text-align: center;">16</td>
  <td style="width: 14.2857%; text-align: center;">8</td>
  <td style="width: 14.2857%; text-align: center;">2</td>
  <td style="width: 14.2857%; text-align: center;">26</td>
  </tr>
  <tr style="height: 22px;">
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">63992</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Takala</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Oyibo</th>
  <td style="width: 14.2857%; text-align: center;">6</td>
  <td style="width: 14.2857%; text-align: center;">20</td>
  <td style="width: 14.2857%; text-align: center;">22</td>
  <td style="width: 14.2857%; text-align: center;">48</td>
  </tr>
  <tr style="height: 22px;">
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">57415</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Abbasi</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Dallas</th>
  <td style="width: 14.2857%; text-align: center;">28</td>
  <td style="width: 14.2857%; text-align: center;">14</td>
  <td style="width: 14.2857%; text-align: center;">7</td>
  <td style="width: 14.2857%; text-align: center;">49</td>
  </tr>
  <tr style="height: 22px;">
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">17804</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Fonda</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Apoorva</th>
  <td style="width: 14.2857%; text-align: center;">30</td>
  <td style="width: 14.2857%; text-align: center;">9</td>
  <td style="width: 14.2857%; text-align: center;">18</td>
  <td style="width: 14.2857%; text-align: center;">57</td>
  </tr>
  <tr style="height: 22px;">
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">11380</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Steffensen</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Oghenekaro</th>
  <td style="width: 14.2857%; text-align: center;">12</td>
  <td style="width: 14.2857%; text-align: center;">2</td>
  <td style="width: 14.2857%; text-align: center;">31</td>
  <td style="width: 14.2857%; text-align: center;">45</td>
  </tr>
  <tr style="height: 22px;">
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">92756</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Palomo</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Emerson</th>
  <td style="width: 14.2857%; text-align: center;">16</td>
  <td style="width: 14.2857%; text-align: center;">11</td>
  <td style="width: 14.2857%; text-align: center;">28</td>
  <td style="width: 14.2857%; text-align: center;">55</td>
  </tr>
  <tr style="height: 22px;">
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">66195</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Falk</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Nalani</th>
  <td style="width: 14.2857%; text-align: center;">13</td>
  <td style="width: 14.2857%; text-align: center;">1</td>
  <td style="width: 14.2857%; text-align: center;">49</td>
  <td style="width: 14.2857%; text-align: center;">63</td>
  </tr>
  <tr style="height: 22px;">
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">88853</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Butler</th>
  <th style="width: 14.2857%; text-align: center; background-color: #ecf0f1;">Lian</th>
  <td style="width: 14.2857%; text-align: center;">1</td>
  <td style="width: 14.2857%; text-align: center;">20</td>
  <td style="width: 14.2857%; text-align: center;">49</td>
  <td style="width: 14.2857%; text-align: center;">70</td>
  </tr>
  </tbody>
  </table>
</textarea>
tinymce.init({
  selector: 'textarea#advtable',
  height: '800px',
  plugins: 'table code advtable lists fullscreen',
  toolbar: 'undo redo | blocks | bold italic | ' +
    'alignleft aligncenter alignright alignjustify | indent outdent | ' +
    'table tableinsertdialog tablecellprops tableprops advtablerownumbering | fullscreen',
  content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }'
});

Enabling the Advanced Tables plugin

To enable the Advanced Tables plugin, add advtable to the list of plugins. For example:

tinymce.init({
  selector: 'textarea',  // change this value according to your HTML
  plugins: 'table advtable',
});

Sorting table rows and columns

Tables can be sorted by row or column values using:

  • The Sort options in the Table menu.

  • The Sort options in the table contextual menu.

  • The Sort options in the Table toolbar menu button.

For example:

Sort rows based on the selected column Advanced Sort Dialog

Advanced Tables enhanced contextual menu for sorting rows based on the selected Column (Sort > Sort table by column ascending/descending).

Advanced Tables sort dialog (Sort > Advanced Sort…).

The plugin is capable of sorting:

  • Numerical data

  • Text data

Currently, the sort function will treat cells with Alphanumeric data as Text data. This includes currency symbols which are text characters.

Adding row numbering to a table

A row numbering column containing a series of values can be added to a table to help identify rows in a table. To allow row numbering on tables, the advtablerownumbering toolbar button and menu item can be used.

A numeric and alpha value series are available by default. The available value series can be configured using the advtable_value_series option.

Table with numeric row numbering column and row numbering menu open (Numeric item checked)

A commonly desired customisation of the row-numbering column is that a table’s header and footer rows not be included in the numbering.

This can be done using the advtable_value_series option to specify a custom generator.

Options

The following configuration options affect the behavior of the Advanced Tables plugin.

advtable_value_series

The advtable_value_series option configures one or more series of values for populating cells in a table. This option can be used to create row identifiers.

Type: Object

Default value:

{
  // Natural number series
  numeric: {
    title: 'Numeric',
    update: true,
    resizable: false,
    generator: `GeneratorFunction` // For details, see: 'Creating a value series generator'
  },
  // English alphabetic series
  alpha: {
    title: 'Alpha',
    update: true,
    resizable: false,
    generator: `GeneratorFunction` // For details, see: 'Creating a value series generator'
  },
}

Both default series are configured to update on table changes and not resize when using the resize bars.

Each top-level properties of the advtable_value_series object are used as the name of the value series and its configuration. In the following example, there are two value series named "numbers" and "letters":

{
  numbers: {
    title: 'Numbered',
    generator: `GeneratorFunction`
  },
  letters: {
    title: 'Lettered',
    generator: `GeneratorFunction`
  },
}

Series configuration

Name Value Requirement Description

title

string

Required

The text shown in the UI for the series.

update

boolean

Optional

default: false - When true, the series values will be updated when changes are made to the table.

resizable

boolean

Optional

default: true - When true, table cells containing the series values can be resized using a mouse or touch device.

generator

(info: GeneratorInfo, rowIndex: number, columnIndex: number) => GeneratorResult

Required

For details on creating a value series generator, see: Creating a value series generator.

Creating a value series generator

The generator is a callback function used to specify how a table cell of a value series will update. The callback is passed information relating to: the generator and table cell, the row index, and column index of the table cell. For details, see: GeneratorInfo. The callback should return an object containing the value and optionally, any classes and attributes to be applied to the table cell. For details, see: GeneratorResult.

If the "state" of the series needs to be kept between generator iterations, additional properties can be added to the generator result. The state can be accessed through the prev property of the info parameter. For details, see: GeneratorInfo.

GeneratorInfo

An object with the following properties is passed to the generator callback function as the info parameter.

Name Value Description

sectionType

'thead', 'tbody' or 'tfoot'

The section of the table cell.

cellType

'td' or 'th'

The type of the table cell.

getRowType

() => 'header' | 'body' | 'footer'

A function that returns the type of row the table cell is part of. A 'header' row is either a row that is part of a thead section or contains all th cells.

classes

string[]

The classes present on the table cell.

direction

'row' or 'column'

The direction of the generator.

prev

GeneratorResult

The generator result from the previous iteration.

GeneratorResult

The generator callback function should return an object with the following properties.

Name Value Requirement Description

classes

string[]

Optional

The classes to be applied to the table cell.

attributes

Object

Optional

The attributes to be applied to the table cell. The attributes should be provided as an object where each key is an attribute and each value is of type string, boolean, number, or null. A value of null for an attribute will remove the attribute from the table cell.

value

string, number or undefined

Optional

The value of the table cell. If the value is undefined, the editor will use the previous value of the table cell.

Example: using advtable_value_series

tinymce.init({
  selector: 'textarea',  // change this value according to your html
  plugins: 'table advtable',
  toolbar: 'advtablerownumbering',
  advtable_value_series: {
    numeric: {
      title: 'Numeric',
      update: true,
      resizable: false,
      generator: (info, rowIndex, columnIndex) => ({
        value: rowIndex + 1
      })
    },
  }
});
tinymce.init({
  selector: "textarea",  // change this value according to your html
  plugins: 'table advtable',
  toolbar: "table advtablerownumbering",
  advtable_value_series: {
    numbers: {
      update: true,
      resizable: false,
      generator: function(info, rowIndex, colIndex) {
        var prevCount = info.prev ? info.prev.count : 0;
        if (info.sectionType === 'tbody' && info.cellType === 'td') {
          var newCount = prevCount + 1;
          return {
            value: newCount,
            count: newCount
          };
        } else {
          return {
            count: prevCount
          };
        }
      }
    }
  }
});

With this custom generator, when a table with a header and footer row already set has row numbers added via the advtablerownumbering toolbar item, row numbers are not added to the header and footer rows.

Row-numbered table with un-numbered header and footer rows
This simple custom generator is a demonstration. It has limitations. Perhaps most significant, it requires the header and footer rows be set before row numbers are added to a table. If row numbers are added and then a header row, or a footer row, or both, are set, this generator will not remove existing row numbers from the now-set header and footer rows.

Toolbar buttons

The Advanced Tables plugin provides the following toolbar buttons:

Toolbar button identifier Description

advtablerownumbering

Adds or removes (toggles) a row numbering column on the selected table.

These toolbar buttons can be added to the editor using:

The Advanced Tables plugin provides the following menu items:

Menu item identifier Default Menu Location Description

advtablesort

Table

Advanced tables sort menu item with related controls.

advtablerownumbering

Not Applicable

Adds or removes (toggles) a row numbering column on the selected table.

These menu items can be added to the editor using:

Commands

The Advanced Tables plugin provides the following TinyMCE commands.

Command Description

mceAdvancedTableSort

Opens the Advanced Table Sort Dialog for the current selection or cursor location.

mceSortTableAdvanced

Performs an Advanced Table Sort. For details, see Using mceSortTableAdvanced.

mceSortTableByColumnAsc

Sorts the current table ascending by column based on the current cursor position or selection.

mceSortTableByColumnDesc

Sorts the current table descending by column based on the current cursor position or selection.

mceSortTableByRowAsc

Sorts the current table ascending by row based on the current cursor position or selection.

mceSortTableByRowDesc

Sorts the current table descending by row based on the current cursor position or selection.

mceTableToggleSeries

Toggles a series column on the selected table. For details, see Using mceTableToggleSeries.

Examples
tinymce.activeEditor.execCommand('mceAdvancedTableSort');
tinymce.activeEditor.execCommand('mceSortTableAdvanced', false, { sortby: 'row', roworcol: '2', sort: 'table', order: 'ascending' });
tinymce.activeEditor.execCommand('mceSortTableByColumnAsc');
tinymce.activeEditor.execCommand('mceSortTableByColumnDesc');
tinymce.activeEditor.execCommand('mceSortTableByRowAsc');
tinymce.activeEditor.execCommand('mceSortTableByRowDesc');
tinymce.activeEditor.execCommand('mceTableToggleSeries', false, { name: 'numeric' });

Using mceSortTableAdvanced

mceSortTableAdvanced accepts an object with the following key-value pairs:

Name Value Requirement Description

sortby

'row' or 'column'

Required

roworcol

number

Required

A zero-indexed integer in a string representing the row from the top of the table or column from the left of the table.

sort

'row', 'column', 'selection', or 'table'

Required

order

'ascending' or 'descending'

Required

Using mceTableToggleSeries

mceTableToggleSeries accepts an object with the following key-value pairs:

Name Value Requirement Description

name

string

Required

Specifies the series to toggle. Series and their associated names are configured using the advtable_value_series option.

If the table already has a series column that uses the series specified in name, the series column will be removed from the table. Otherwise, a new series column will be created, replacing any other series column that may already be in the table.