npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

stimulus-datatables

v1.0.6

Published

Run DataTables under Rails Turbolinks

Downloads

960

Readme

Run DataTables under Rails Turbolinks

(This has been renamed to rails-datatables)

A Stimulus wrapper for DataTables under Rails Turbolinks.

Toggle Scrolling demo

Examples

Here is a zero config example.

<table id="zero-config" class="table" data-controller="datatable" >
  <thead>
    <tr><th>First</th><th>Last</th></tr>
  </thead>
  <tbody>
    <tr><td>Tenzin</td><td>Gyatso</td></tr>
    <tr><td>Barak</td><td>Obama</td></tr>
    <tr><td>Nelson</td><td>Mandela</td></tr>
  </tbody>
</table>

Here is an example of passing the ajax data path from Rails to DataTables. This uses the ajax-datatables-rails gem. It also sets { debug: true } to turn on console logging.

<table id="ajax-datatable" class="table"
  data-controller="datatable"
  data-datatable-config="<%= {
    debug: true,
    serverSide: true,
    ajax: datatable_articles_path,
    dom: 'lfriptrip',
    stateSave: true,
    columns: [
      {title: 'Title', data: 'title', width: '30%' },
      {title: 'Text', data: 'text', },
    ],
  }.to_json %>"
>
</table>

Setup

Add ajax-datatables-rails to your Gemfile and follow the data source setup instructions.

gem 'ajax-datatables-rails'

Add stimulus-datatables to package.json and register it with Stimulus.

yarn add stimulus-datatables
// If jQuery is not already registered in window.jQuery do it here.
window.jQuery = window.$ = require('jquery')

// The controller will call: window.jQuery(table).DataTable(config)
require('datatables.net')

// These examples use bootstrap4 and the scroller plugin.
// See https://datatables.net/download for more options.
require('datatables.net-bs4')
require('datatables.net-scroller-bs4')

// Stimulus setup.
import { Application } from 'stimulus'
const application = Application.start()

// Register the stimulus-datatables controller.
import Datatable from 'stimulus-datatables'
application.register('datatable', Datatable)

There appears to be a Datatable problem with long lines not folding in the scroller plugin. Here is the scss setup for these examples with the line folding workaround.

@import 'datatables.net-bs4/css/dataTables.bootstrap4';
@import 'datatables.net-scroller-bs4/css/scroller.bootstrap4.css';

table.dataTable tbody tr td {
  white-space: normal;
}

Advanced Usage

You can make custom stimulus controllers which extend the standard stimulus datatables controller.

Datatables under Turbolinks triggers extra initialize() and connect() calls that are ignored by the controller. The .DataTable() call alters the table element which causes ghost initialization and connect events that need to be ignored.

When we navigate to a page which is already in the Turbolinks cache, Turbolinks shows the cached copy as a preview page until the real page arrives from the server.

There is no point in setting up DataTables for preview pages since we will need to wait for the ajax call to retrieve the data from the server for display in the real page.

There are three events that you can customize. initialize() sets up the configuration options. connect() starts up DataTables. teardown() destroys the DataTable instance.

When you override initialize() and connect() you will want to ignore the ghost events by testing with this.isBooting(). See the example below. super.initialize() and super.connect() return the config object while booting and return false for ghost events.

Call this.log(msg, data) to write to the console log to debug custom controller setups. See below for an example.

You can turn on debug messages by setting { debug: true }. Call this.debug(msg, data) to write to console.log only when this.config.debug is true.

import DataTable from 'stimulus-datatables'

export default class extends DataTable {
  initialize() {
    // Ignore ghost events.
    if (!this.isBooting()) return

    // Default settings here will be overridden by component configurations.
    this.config = { pagingType: 'full_numbers', debug: true }

    // Call the super method which gets the component configuration.
    super.initialize()

    // This sets the final config values.
    this.config.dom = 'lfriptrip'
  }

  connect() {
    // Ignore ghost events.
    if (!this.isBooting()) return

    // You can alter the config here before the connect.

    // Call the super method to start up DataTables.
    super.connect()

    // Any post connect actions here.
  }

  teardown() {
    // Any before or after teardown actions. Here we write to console.log.
    this.log('finished', { dt: this })

    // Call the super method to destroy the DataTable instance.
    super.teardown()
  }
}

External Control

Sometimes we will want to make changes to a running DataTables instance.

In order to facilitate this, the DOM table element is linked to its controller instance: table.dt. Each controller instance is linked back to the DOM table dt.element, the dt.config, and the live DataTable API object dt.dataTable.

Here is an example of a custom controller which can change state between scrolling or paging depending on a #toggle-scrolling checkbox. This example is running in the animated gif above.

As the comment mentions, we can reconfigure a DataTable by updating the config and calling dt.teardown(). The teardown process will alter the DOM element which will trigger a stimulus reconnect with the new config.

Here is the html containing the checkbox and the table.

<input id="toggle-scrolling" type="checkbox" checked
       data-controller="articles-datatable"
       data-action="change->articles-datatable#toggle_scrolling"
/>

<table id="articles-datatable" class="table"
  data-controller="articles-datatable"
  data-articles-datatable-config="<%= {
    debug: true,
    serverSide: true,
    ajax: datatable_articles_path,
    scroller: true,
    scrollY: 600,
    dom: 'lfriptrip',
    deferRender: true,
    pagingType: 'full_numbers',
    columns: [
      {title: 'Title', data: 'title', width: '30%' },
      {title: 'Text', data: 'text' },
    ],
  }.to_json %>"
>
</table>

Here is the custom articles-datatable controller which toggles between scrolling and paging display modes.

import DataTable from 'stimulus-datatables'

export default class extends DataTable {

  initialize() {
    if (!this.isBooting()) return

    // Link to the scrolling checkbox and back.
    const checkbox = $('#toggle-scrolling')[0]
    if (checkbox) {
      checkbox.dt = this
      this.checkbox = checkbox
    }

    // Get the table config and the scrolling state.
    super.initialize()
    this.setScrollingState()
  }

  toggle_scrolling = event => {
    const dt = this.element.dt
    if (dt) {
      dt.setScrollingState()
      dt.teardown() // This triggers a reconnect.
    }
  }

  setScrollingState = () => {
    const scrolling = this.checkbox && this.checkbox.checked
    const config = this.config || {}
    config.scroller = scrolling
    config.scrollY = scrolling ? 600 : undefined
    config.stateSave = !scrolling
  }
}