initializing data tables on a page, using classes or data attributes rather than javascript directly
initializing data tables on a page, using classes or data attributes rather than javascript directly
I've been using dattables for a while, and I'm to the point where I have several in a page (basically slapped onto every table in the report)
I've gotten kind of frustrated with having to copy/paste large chunks of javascript into new pages to do the same functionality. One example would be the column filtering example code: https://datatables.net/examples/api/multi_filter.html
That requires
1. A footer (or header, depending on where you want the column search) row with a duplicate of the header
2. javascript for a specific table to add the column filtering
I've already written the javascript to make that all driven off of classes on the table/th cells so that when I add a new datatable, all I need to do is add a few classes to it to get it to initialize with the features I want. So I wind up with a table like the one below, that is pretty feature rich without having to do anything other than call my initDataTables function.
- unless otherwise specified, every column gets it's own sort box (input box by default)
- All of the html 5 export buttons that are available are appended to the table button section
- column 2 is sorted ascending by default (forces date sort, but that uses current datatables targeting to do it)
- column 4 isn't sortable
- column 6 puts a select box in the column filter section, populated with all unique values of the column.
- column 7 isn't filterable
- Column 8 is hidden
- columns 3 and 5 are missing from the example because they're features I'm still playing around with (related to sorting/filtering part of a column)
<
table class="dataTable columnFilter allHtml5Buttons table table-striped" border="0" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th>Table Header Cell 1</th>
<th class="defaultSort dateSort">Table Header Cell 2</th>
<th class="noSort">Table Header Cell 4 (no sort)</th>
<th class="selectFilter">Table Header Cell 6</th>
<th class="noFilter">Table Header Cell 7 (no filter)</th>
<th class="hidden">Table Header Cell 8 (hidden)</th>
</tr>
</thead>
<tbody>
some of the things that I'm doing just use the targets:classes part of column def;
- { targets: 'noSort', orderable: false },
- { targets: 'hidden', visible: false },
- { targets: 'noFilter', searchable: false },
- { targets: "dateSort", "type": "date" },
other parts I've had to write some javascript that pulls it all together during the init
Some kind of random thoughts
1. data-attributes might be a better fit semantically than classes for some things, say, like data-sortable="true/false" on a column and targeting that by default rather than giving the user a targets class... I'm not sure if your choice to do targets off of classes is performance related (selecting by class is faster, I think) or if it's in tje interest in giving the most flexible way of setting columndefs, ors omething else
2. The pieces that I pull together in javascript (turning on/off buttons, column filtering, default sort columns, etc) seem like they'd be something that other people might be interested in. Is it likely that those sorts of things will be settable via class or data-attribute in the future?
Replies
The table example from earlier winds up looking like:
Thanks for the feedback.
Already quite possible. Example here. It won't do more complex things like event handlers for filtering, but that is something that can readily be done with your own event handler listening for the
init
event, which is what most of the extensions for DataTables do.Regards,
Allan
I'd seen the one for data-sort and data-filter to handle sorting of complex displayed columns... but I hadn't seen the table and column examples.
so does that mean that something like example:
columnDefs: [
{ targets: 'noSort', orderable: false },
{ targets: 'noFilter', searchable: false },
{ targets: "dateSort", "type": "date" },
]
<thead>
<th class="noSort"></th>
<th class="noFilter"></th>
<th class="dateSort"></th>
</thead>
could be done with
<thead>
<th data-orderable="false"></th>
<th data-searchable="false"></th>
<th data-type='date'></th>
</thead>
Yes, exactly that.
I should point out though that you should never need to set the
columns.type
option. If the auto detection doesn't automatically assign it as a date type, then the content in the column isn't suitable for use as a date type column (ISO8601 is the only built in format supported).Allan
re: I should point out though that you should never need to set the columns.type option.
It will not autodetect dates in format MM/DD/YYYY but it sorts them just fine if I force date formatting by setting the type.
https://jsfiddle.net/charleycartee/9q8tyxxm/1/
Not across browsers and locales though. For example
06/06/2018
is ambiguous and since I'm in the UK it would be treated as DD/MM/YYYY.Chrome tries very hard to parse anything you send into
Date.parse()
as a date - evenDate.parse('5')
would result in a date stamp being returned. Other browsers try less hard. ISO8601 is the only one that is truly reliable, which is why DataTables' built in date sorting is restricted to that.Use this plug-in with Moment.JS to resolve that. I'm going to have that built into the next major version of DataTables.
Allan
re: Not across browsers and locales though
I'm sure it is wonky based on locale, but doesn't really seem to be a browser issue. In my locale, forcing date searching with data-type="date" works in ie11, chrome, edge, Opera, and Firefox
I couldn't get the moment.js plugin to work for MM/DD/YYYY via autodetect either... it only worked when I specified the column as type = date. It did pick up both of the weird formats in the example code. I may have a jsfiddle with that set up (I'll have to check)
Since my target audience is entirely in the US, and 90%+ of them are using ie11, I'm fine with just forcing type=date... though it would be nice if tat wasn't necessary.
should be all that was needed with MomentJS also included on the page.
However, good to hear you've got it working now.
Allan
re: I couldn't get the moment.js plugin to work for MM/DD/YYYY via autodetect either..
Actually, I just retested it, and it seems to work. I think I may have had a date of format M/D/YYYY that threw it off.
Actually, it was an old version of moment.min.js that did it.