Skip to content
This repository has been archived by the owner on Feb 5, 2025. It is now read-only.

Commit

Permalink
Created a DataTables extension for row selection and select all funct…
Browse files Browse the repository at this point in the history
…ionality.
  • Loading branch information
dlabrecq committed Nov 8, 2016
1 parent 4f291ca commit ade73df
Show file tree
Hide file tree
Showing 7 changed files with 261 additions and 20 deletions.
7 changes: 6 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ module.exports = function (grunt) {
js: {
files: [
// copy js src file
{expand: true, cwd: 'src/js/', src: ['patternfly.js', 'patternfly-settings.js', 'patternfly-functions.js'], dest: 'dist/js/'}
{expand: true, cwd: 'src/js/', src: ['*.js'], dest: 'dist/js/'}
]
}
},
Expand Down Expand Up @@ -146,9 +146,14 @@ module.exports = function (grunt) {
},
production: {
files: {
<<<<<<< 4f291caa1779cd39cea160b7b43f7b8de122cb76
'dist/js/patternfly.min.js': ['dist/js/patternfly.js'],
'dist/js/patternfly-settings.min.js': ['dist/js/patternfly-settings.js'],
'dist/js/patternfly-functions.min.js': ['dist/js/patternfly-functions.js']
=======
'dist/js/patternfly.min.js': ['src/js/patternfly.js'],
'dist/js/patternfly.dataTables.pfSelect.min.js': ['src/js/patternfly.dataTables.pfSelect.js']
>>>>>>> Created a DataTables extension for row selection and select all functionality.
}
}
},
Expand Down
3 changes: 2 additions & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ module.exports = function(config) {
'node_modules/patternfly-bootstrap-combobox/js/bootstrap-combobox.js',
'node_modules/bootstrap-datepicker/dist/js/bootstrap-datepicker.js',
'node_modules/bootstrap-select/dist/js/bootstrap-select.js',
'node_modules/datatables/media/js/jquery.dataTables.js',
'node_modules/datatables.net/js/jquery.dataTables.js',
'node_modules/datatables.net-select/js/dataTables.select.js',
'node_modules/bootstrap-switch/dist/js/bootstrap-switch.js',
'node_modules/patternfly-bootstrap-treeview/src/js/bootstrap-treeview.js',
'node_modules/c3/c3.js',
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"datatables": "~1.10.12",
"datatables.net-colreorder": "~1.3.2",
"datatables.net-colreorder-bs": "~1.3.2",
"datatables.net-select": "~1.2.0",
"drmonty-datatables-colvis": "~1.1.2",
"eonasdan-bootstrap-datetimepicker": "~4.15.35",
"google-code-prettify": "~1.0.5",
Expand Down
236 changes: 236 additions & 0 deletions src/js/patternfly.dataTables.pfSelect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
/**
* @summary pfSelect for DataTables
* @description A collection of API methods providing individual row selection and select all functionality in a
* DataTable using traditional HTML checkboxes. This ensures the DataTable meets the Patternfly design pattern while
* maintaining accessibility. Selection checkboxes are expected to be located in the first column of the DataTable.
*
* The following selection styles are supported for user interaction with the DataTable:
*
* api - Selection can only be performed via the API
* multi - Multiple items can be selected
* multi+shift - a hybrid between the os style and multi
* os - Operating system style selection with complex behaviors such as ctrl/cmd, shift and an unmodified click
* single - Only a single item can be selected
*
* For details see: https://datatables.net/reference/option/select.style
*
* Example:
*
* <div class="datatable-pf">
* <table class="table table-striped table-bordered table-hover" id="table2">
* <thead>
* <tr>
* <th><input type="checkbox" name="selectAll"></th>
* <th>Test</th>
* </tr>
* </thead>
* </table>
* </div>
* <script>
* $(document).ready(function() {
* var dt = $('#table2').DataTable({
* columns: [{
* data: null,
* className: "datatable-pf-select",
* render: function (data, type, full, meta) {
* return '<input type="checkbox" name="select">';
* },
* sortable: false
* }, {
* data: "test"
* }],
* data: [{ test: "1" }, { test: "2" }],
* dom: 't',
* order: [[ 1, 'asc' ]],
* select: {
* style: 'multi',
* selector: 'td:first-child input[type="checkbox"]'
* }
* });
* dt.table().pfSelect.selectAllRows(true); // Select all rows
* });
* </script>
*
* Note: This functionality requires the following Javascript library files to be loaded:
*
* https://cdn.datatables.net/select/1.2.0/js/dataTables.select.min.js
*/
(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd ) {
// AMD
define (['jquery', 'datatables.net'], function ($) {
return factory ($, window, document);
});
} else if (typeof exports === 'object') {
// CommonJS
module.exports = function (root, $) {
if (!root) {
root = window;
}
if (!$ || !$.fn.dataTable) {
$ = require('datatables.net')(root, $).$;
}
return factory($, root, root.document);
};
} else {
// Browser
factory(jQuery, window, document);
}
}(function ($, window, document, undefined) {
'use strict';
var DataTable = $.fn.dataTable;
var RESULTS_SELECTOR = '.datatable-pf-results-right'; // Toolbar results area displaying selected rows text
var SELECT_SELECTOR = 'td:first-child input[type="checkbox"]'; // Checkboxes used for row selection
var SELECT_ALL_SELECTOR = 'th:first-child input[type="checkbox"]'; // Checkbox used to select all rows

DataTable.pfSelect = {};

/**
* Initialize
*
* @param {DataTable.Api} dt DataTable
* @private
*/
DataTable.pfSelect.init = function (dt) {
var style = dt.select.style();
if (style === 'api') {
// Select all checkbox
$(dt.table().container()).on('click', SELECT_ALL_SELECTOR, function (evt) {
evt.preventDefault();
});

// Select checkboxes
$(dt.table().container()).on('click', SELECT_SELECTOR, function (evt) {
evt.preventDefault();
});

dt.table().on('select.dt', function () {
syncSelectCheckboxes(dt);
});
} else {
// Select all checkbox
$(dt.table().container()).on('click', SELECT_ALL_SELECTOR, function (evt) {
selectAllRows(dt, evt.target.checked);
});

// Select checkboxes
$(dt.table().container()).on('click', SELECT_SELECTOR, function (evt) {
if (style !== 'multi' || style !== 'multi+shift') {
syncSelectCheckboxes(dt); // No need to sync checkbox selections when "multi" is used
} else {
syncSelectAllCheckbox(dt); // Still need to sync select all checkbox
}
});
}

// Sync checkbox selections when paging and filtering is applied
dt.table().on('draw.dt', function () {
syncSelectCheckboxes(dt);
});

// Initialize selected rows text
updateSelectedRowsText(dt);
};

// Local functions

/**
* Select all rows on current page
*
* @param {DataTable.Api} dt DataTable
* @param {boolean} select True to select all rows on current page, defaults to false
* @private
*/
function selectAllRows (dt, select) {
// Retrieve all rows taking into account currently applied filter
var filteredRows = dt.rows({'page': 'current', 'search': 'applied'});

// Check if style is single
if (dt.select.style() === 'single') {
throw new Error("Cannot select all rows with selection style 'single'");
}

// Select rows
if (select) {
filteredRows.select();
} else {
filteredRows.deselect();
}
$(SELECT_SELECTOR, dt.table().container()).prop('checked', select); // De/select checkboxes in view
syncSelectAllCheckbox(dt);
}

/**
* Sync select all checkbox with row selections on current page
*
* @param {DataTable.Api} dt DataTable
* @private
*/
function syncSelectAllCheckbox (dt) {
// Retrieve all rows taking into account currently applied filter
var filteredRows = dt.rows({'page': 'current', 'search': 'applied'}).flatten().length;
var selectedFilteredRows = dt.rows({'page': 'current', 'search': 'applied', 'selected': true}).flatten().length;

// De/select the select all checkbox
var selectAll = $(dt.table().container()).find(SELECT_ALL_SELECTOR)[0];
if (selectAll) {
selectAll.checked = (filteredRows === selectedFilteredRows);
}
updateSelectedRowsText(dt);
}

/**
* Sync select checkboxes with row selections on current page
*
* @param {DataTable.Api} dt DataTable
* @private
*/
function syncSelectCheckboxes (dt) {
$(SELECT_SELECTOR, dt.table().container()).prop('checked', false); // Deselect all checkboxes
dt.rows({'page': 'current', 'search': 'applied', 'selected': true}).every(function (index) {
$(SELECT_SELECTOR, dt.table().row(index).node()).prop('checked', true); // Select checkbox for selected row
});
syncSelectAllCheckbox(dt);
}

/**
* Update selection results
*
* @param {DataTable.Api} dt DataTable
* @private
*/
function updateSelectedRowsText (dt) {
var selectedRows = dt.rows({'selected': true}).flatten().length;
var totalRows = dt.rows().flatten().length;
var results = $(dt.table().container()).parent('div').find(RESULTS_SELECTOR);
if (results === undefined) {
return;
}
results.html("<strong>" + selectedRows + "</strong> of <strong>" + totalRows + "</strong> selected");
}

// DataTables API

/**
* Select all rows on current page
*
* Example: dt.table().pfSelect.selectAllRows(true);
*
* @param {boolean} select True to select all rows on current page, defaults to false
*/
DataTable.Api.register('pfSelect.selectAllRows()', function (select) {
return this.iterator('table', function (ctx) {
selectAllRows(new DataTable.Api(ctx), select);
});
});

// DataTables creation
$(document).on('preInit.dt.dtSelect', function (e, ctx) {
if (e.namespace !== 'dt') {
return;
}
DataTable.pfSelect.init(new DataTable.Api(ctx));
});
return DataTable.pfSelect;
}));
28 changes: 12 additions & 16 deletions tests/pages/_includes/widgets/datatables/datatable.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
</div>
{% include widgets/datatables/js/data.js.html %}
{% include widgets/datatables/js/filter.js.html %}
{% include widgets/datatables/js/select.js.html %}
{% include widgets/datatables/js/empty.js.html %}
<script>
$(document).ready(function() {
// Initialize data table
var table = $('#table').DataTable({
var dt = $('#table').DataTable({
columns: [
{ data: null,
className: "datatable-pf-select",
Expand All @@ -24,7 +23,7 @@
{ data: "browser" },
{ data: "platforms" },
{ data: "version" },
{ data: "grade" },
{ data: "grade"},
{ data: null,
className: "datatable-pf-actions",
render: function (data, type, full, meta) {
Expand All @@ -36,15 +35,15 @@
className: "datatable-pf-actions",
render: function (data, type, full, meta) {
// Inline action kebab renderer
return '<div class="dropdown pull-right dropdown-kebab-pf">' +
'<button class="btn btn-link dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">' +
return '<div class="dropdown dropdown-kebab-pf">' +
'<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">' +
'<span class="fa fa-ellipsis-v"></span></button>' +
'<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownKebabRight">' +
'<li><a href="#">Action</a></li>' +
'<li><a href="#">Another action</a></li>' +
'<li><a href="#">Something else here</a></li>' +
'<li role="separator" class="divider"></li>' +
'<li><a href="#">Separated link</a></li></div>';
'<li><a href="#">Separated link</a></li></ul></div>';
}
}
],
Expand All @@ -53,23 +52,20 @@
language: {
zeroRecords: "No records found"
},
order: [[ 1, 'asc' ]]
order: [[ 1, 'asc' ]],
select: {
style: 'multi',
selector: 'td:first-child input[type="checkbox"]'
}
});

// Initialize filtering util
new dataTableFilter({
new dataTableFilterUtil({
datatableId: ".datatable-pf"
});

// Initialize selection util
new dataTableSelect({
datatableId: ".datatable-pf",
deleteAllRowsId: "#deleteAllRows",
selectAllId: "#selectAllRows"
});

// Initialize empty data table util
new dataTableEmpty({
new dataTableEmptyUtil({
data: dataSet,
datatableId: ".datatable-pf",
deleteAllRowsId: "#deleteAllRows",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<table class="table table-striped table-bordered table-hover" id="table">
<thead>
<tr>
<th><input type="checkbox" id="selectAllRows" name="selectAllRows"></th>
<th><input type="checkbox" name="selectAll"></th>
<th>Rendering engine</th>
<th>Browser</th>
<th>Platform(s)</th>
Expand Down
4 changes: 3 additions & 1 deletion tests/pages/datatables.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
layout: page
title: Data Tables
resource: true
url-js-extra: '//cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js'
url-js-extra: [ '//cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js',
'//cdn.datatables.net/select/1.2.0/js/dataTables.select.min.js',
'../../dist/js/patternfly.dataTables.pfSelect.js' ]
---
{% include widgets/datatables/datatable.html %}

0 comments on commit ade73df

Please sign in to comment.