/** * PrimeUI Datatable Widget */ $(function() { $.widget("primeui.puidatatable", { options: { columns: null, datasource: null, paginator: null, selectionMode: null, rowSelect: null, rowUnselect: null, caption: null }, _create: function() { this.id = this.element.attr('id'); if(!this.id) { this.id = this.element.uniqueId().attr('id'); } this.element.addClass('pui-datatable ui-widget'); this.tableWrapper = $('
').appendTo(this.element); this.table = $('
').appendTo(this.tableWrapper); this.thead = this.table.children('thead'); this.tbody = this.table.children('tbody').addClass('pui-datatable-data'); if(this.options.datasource) { if($.isArray(this.options.datasource)) { this.data = this.options.datasource; this._initialize(); } else if($.type(this.options.datasource) === 'function') { this.options.datasource.call(this, this._handleDataLoad); } } }, _initialize: function() { var $this = this; if(this.options.columns) { $.each(this.options.columns, function(i, col) { var header = $('').data('field', col.field).appendTo($this.thead); if(col.headerText) { header.text(col.headerText); } if(col.sortable) { header.addClass('pui-sortable-column') .data('order', 1) .append(''); } }); } if(this.options.caption) { this.table.prepend('' + this.options.caption + ''); } if(this.options.paginator) { this.options.paginator.paginate = function(state) { $this.paginate(); } this.options.paginator.totalRecords = this.options.paginator.totalRecords||this.data.length; this.paginator = $('
').insertAfter(this.tableWrapper).puipaginator(this.options.paginator); } if(this._isSortingEnabled()) { this._initSorting(); } if(this.options.selectionMode) { this._initSelection(); } this._renderData(); }, _handleDataLoad: function(data) { this.data = data; if(!this.data) { this.data = []; } this._initialize(); }, _initSorting: function() { var $this = this, sortableColumns = this.thead.children('th.pui-sortable-column'); sortableColumns.on('mouseover.puidatatable', function() { var column = $(this); if(!column.hasClass('ui-state-active')) column.addClass('ui-state-hover'); }) .on('mouseout.puidatatable', function() { var column = $(this); if(!column.hasClass('ui-state-active')) column.removeClass('ui-state-hover'); }) .on('click.puidatatable', function() { var column = $(this), field = column.data('field'), order = column.data('order'), sortIcon = column.children('.pui-sortable-column-icon'); //clean previous sort state column.siblings().filter('.ui-state-active').data('order', 1).removeClass('ui-state-active').children('span.pui-sortable-column-icon') .removeClass('ui-icon-triangle-1-n ui-icon-triangle-1-s'); $this.sort(field, order); //update state column.data('order', -1*order); column.removeClass('ui-state-hover').addClass('ui-state-active'); if(order === -1) sortIcon.removeClass('ui-icon-triangle-1-n').addClass('ui-icon-triangle-1-s'); else if(order === 1) sortIcon.removeClass('ui-icon-triangle-1-s').addClass('ui-icon-triangle-1-n'); }); }, paginate: function() { this._renderData(); }, sort: function(field,order) { this.data.sort(function(data1, data2) { var value1 = data1[field], value2 = data2[field], result = (value1 < value2) ? -1 : (value1 > value2) ? 1 : 0; return (order * result); }); if(this.options.selectionMode) { this.selection = []; } if(this.paginator) { this.paginator.puipaginator('option', 'page', 0); } this._renderData(); }, sortByField: function(a, b) { var aName = a.name.toLowerCase(); var bName = b.name.toLowerCase(); return ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0)); }, _renderData: function() { if(this.data) { this.tbody.html(''); var first = this.getFirst(), rows = this.getRows(); for(var i = first; i < (first + rows); i++) { var rowData = this.data[i]; if(rowData) { var row = $('').appendTo(this.tbody), zebraStyle = (i%2 === 0) ? 'pui-datatable-even' : 'pui-datatable-odd'; row.addClass(zebraStyle); if(this.options.selectionMode && PUI.inArray(this.selection, i)) { row.addClass("ui-state-highlight"); } for(var j = 0; j < this.options.columns.length; j++) { var column = $('').appendTo(row), fieldValue = rowData[this.options.columns[j].field]; column.text(fieldValue); } } } } }, getFirst: function() { if(this.paginator) { var page = this.paginator.puipaginator('option', 'page'), rows = this.paginator.puipaginator('option', 'rows'); return (page * rows); } else { return 0; } }, getRows: function() { return this.paginator ? this.paginator.puipaginator('option', 'rows') : this.data.length; }, _isSortingEnabled: function() { var cols = this.options.columns; if(cols) { for(var i = 0; i < cols.length; i++) { if(cols[i].sortable) { return true; } } } return false; }, _initSelection: function() { var $this = this; this.selection = []; this.rowSelector = '#' + this.id + ' tbody.pui-datatable-data > tr.ui-widget-content:not(.ui-datatable-empty-message)'; //shift key based range selection if(this._isMultipleSelection()) { this.originRowIndex = 0; this.cursorIndex = null; } $(document).off('mouseover.puidatatable mouseout.puidatatable click.puidatatable', this.rowSelector) .on('mouseover.datatable', this.rowSelector, null, function() { var element = $(this); if(!element.hasClass('ui-state-highlight')) { element.addClass('ui-state-hover'); } }) .on('mouseout.datatable', this.rowSelector, null, function() { var element = $(this); if(!element.hasClass('ui-state-highlight')) { element.removeClass('ui-state-hover'); } }) .on('click.datatable', this.rowSelector, null, function(e) { $this._onRowClick(e, this); }); }, _onRowClick: function(event, rowElement) { if(!$(event.target).is(':input,:button,a')) { var row = $(rowElement), selected = row.hasClass('ui-state-highlight'), metaKey = event.metaKey||event.ctrlKey, shiftKey = event.shiftKey; //unselect a selected row if metakey is on if(selected && metaKey) { this.unselectRow(row); } else { //unselect previous selection if this is single selection or multiple one with no keys if(this._isSingleSelection() || (this._isMultipleSelection() && !metaKey && !shiftKey)) { this.unselectAllRows(); } this.selectRow(row); } PUI.clearSelection(); } }, _isSingleSelection: function() { return this.options.selectionMode === 'single'; }, _isMultipleSelection: function() { return this.options.selectionMode === 'multiple'; }, unselectAllRows: function() { this.tbody.children('tr.ui-state-highlight').removeClass('ui-state-highlight').attr('aria-selected', false); this.selection = []; }, unselectRow: function(row, silent) { var rowIndex = this._getRowIndex(row); row.removeClass('ui-state-highlight').attr('aria-selected', false); this._removeSelection(rowIndex); if(!silent) { this._trigger('rowUnselect', null, this.data[rowIndex]); } }, selectRow: function(row, silent) { var rowIndex = this._getRowIndex(row); row.removeClass('ui-state-hover').addClass('ui-state-highlight').attr('aria-selected', true); this._addSelection(rowIndex); if(!silent) { this._trigger('rowSelect', null, this.data[rowIndex]); } }, _removeSelection: function(rowIndex) { this.selection = $.grep(this.selection, function(value) { return value !== rowIndex; }); }, _addSelection: function(rowIndex) { if(!this._isSelected(rowIndex)) { this.selection.push(rowIndex); } }, _isSelected: function(rowIndex) { return PUI.inArray(this.selection, rowIndex); }, _getRowIndex: function(row) { var index = row.index(); return this.options.paginator ? this.getFirst() + index : index; } }); });