From 1d7e70aa15060208f6b105bf616078bb25e7c6c5 Mon Sep 17 00:00:00 2001 From: grainsoft Date: Mon, 6 Jul 2026 19:23:12 +0300 Subject: [PATCH] updates --- src/widgets/table/Table.js | 904 +++++++++++++++++++----------------- src/widgets/table/table.css | 27 ++ 2 files changed, 504 insertions(+), 427 deletions(-) diff --git a/src/widgets/table/Table.js b/src/widgets/table/Table.js index 850f12d..742e39b 100644 --- a/src/widgets/table/Table.js +++ b/src/widgets/table/Table.js @@ -8,91 +8,93 @@ import { Render } from '../../core/Render'; export class Table { - static CLEAN = 0; - static APPEND = 1; - static PREPEND = 2; - static UPDATE = 3; + static CLEAN = 0; + static APPEND = 1; + static PREPEND = 2; + static UPDATE = 3; - /** - * Table, Constructor - */ - constructor(target, caller, opts) { + /** + * Table, Constructor + */ + constructor(target, caller, opts) { - this.target = target; - this.caller = caller; + this.target = target; + this.caller = caller; - this.vars = new FormData(); + this.vars = new FormData(); - this.reqOpts = {}; + this.reqOpts = {}; - this.vars.set('pg', 1); + this.vars.set('pg', 1); - this.opts = { ... { - layout : 'auto', - filter : false, - header : {}, - label : '%rows results', - sortable : 0 - }, ... opts, ... opts.children }; + this.opts = { ... { + layout : 'auto', + filter : false, + header : {}, + label : '%rows results', + sortable : 0 + }, ... opts, ... opts.children }; - this.rows = 0; - this.setHeader = true; - this.data = {}; + this.rows = 0; + this.setHeader = true; + this.data = {}; - if (!this.opts.header.cell || this.opts.display == 'none') { - this.setHeader = false; - } + if (!this.opts.header.cell || this.opts.display == 'none') { + this.setHeader = false; + } - this.makeUiTable(); + this.makeUiTable(); - if (this.opts.filter) { // create filter form - this.makeFilterForm(); - } + if (this.opts.filter) { // create filter form + this.makeFilterForm(); + } - if (Ut.isSet(this.opts.toolbar_header)) { // create toolbar header - this.makeToolbarHeader(); - } + if (Ut.isSet(this.opts.toolbar_header)) { // create toolbar header + this.makeToolbarHeader(); + } - if (this.opts.label) { // create info label - this.makeInfoLabel(); - } + if (this.opts.label) { // create info label + this.makeInfoLabel(); + } - this.makeNewTable(); + this.makeNewTable(); - this.makePagination(); + this.makePagination(); - if (Ut.isSet(this.opts.toolbar_footer)) { // create toolbar footer - this.makeToolbarFooter(); - } + if (Ut.isSet(this.opts.toolbar_footer)) { // create toolbar footer + this.makeToolbarFooter(); + } - this.setMode(Table.CLEAN); + this.setMode(Table.CLEAN); - if ( Ut.isFn(caller) ) { // Data Mode - this.makeRequest(); - } - else { - this.setTableData(caller); - } + if ( Ut.isFn(caller) ) { // Data Mode + this.makeRequest(); + } + else { + this.setTableData(caller); + } - if (this.opts.sortable) { - this.setSortable(); - } + if (this.opts.sortable) { + this.setSortable(); + } - Ut.trigger(this.opts.onInit, this); - } + this.setTableEvents(); - setMode(mode) { + Ut.trigger(this.opts.onInit, this); + } - this.mode = mode; + setMode(mode) { - if (mode == Table.CLEAN) { - this.id = 0; - } - } + this.mode = mode; - setTableData(data) { + if (mode == Table.CLEAN) { + this.id = 0; + } + } - this.data = data; + setTableData(data) { + + this.data = data; this.rows = parseInt(this.data.count); this.updateInfoRows(); @@ -111,540 +113,588 @@ export class Table { this.updatePagination(); Ut.trigger(this.opts.onUpdate, this); - } + } - makeInfoLabel() { - this.info = El('div', { className: 'sp-table-info' }); - this.ui.append(this.info); - } + makeInfoLabel() { + this.info = El('div', { className: 'sp-table-info' }); + this.ui.append(this.info); + } - // Make UI container + // Make UI container - makeUiTable() { - this.ui = El('div', { className: 'sp-table-ui' }); - this.target.append(this.ui); - } + makeUiTable() { + this.ui = El('div', { className: 'sp-table-ui' }); + this.target.append(this.ui); + } - // Make filter form + // Make filter form - makeFilterForm() { + makeFilterForm() { - let that = this; + let that = this; - this.filterForm = El('form', { novalidate: true, className: 'sp-form filter-main' }); - - Render.makeUiElements(Ut.objVal(this.opts.filter).children, this.filterForm); - - this.ui.append(this.filterForm); + this.filterForm = El('form', { novalidate: true, className: 'sp-form filter-main' }); + + Render.makeUiElements(Ut.objVal(this.opts.filter).children, this.filterForm); + + this.ui.append(this.filterForm); - this.filterForm.dxOn('changed clear', 'input[type="text"]', () => that.filterForm.dxTrigger('submit.form')); - this.filterForm.dxOn('change', 'select, input[type="radio"], input[type="checkbox"]', () => that.filterForm.dxTrigger('submit.form')); + this.filterForm.dxOn('changed clear', 'input[type="text"]', () => that.filterForm.dxTrigger('submit.form')); + this.filterForm.dxOn('change', 'select, input[type="radio"], input[type="checkbox"]', () => that.filterForm.dxTrigger('submit.form')); - new FormValidator(this.filterForm, { + new FormValidator(this.filterForm, { - onInit: el => that.filterFormEl = el, - onSubmit: function(vars) { + onInit: el => that.filterFormEl = el, + onSubmit: function(vars) { - that.vars = vars; + that.vars = vars; - that.vars.set('pg', 1); + that.vars.set('pg', 1); - that.setMode(Table.CLEAN); + that.setMode(Table.CLEAN); - that.makeRequest(); - } - }); + that.makeRequest(); + } + }); - fillData(that.filterFormEl, this.vars); - } + fillData(that.filterFormEl, this.vars); + } - // Make header toolbar + // Make header toolbar - makeToolbarHeader() { + makeToolbarHeader() { - this.toolbarHeader = El('div', { className: 'sp-toolbar toolbar-header' + (this.opts.toolbar_header.cls ? ' ' + this.opts.toolbar_header.cls : '') }); + this.toolbarHeader = El('div', { className: 'sp-toolbar toolbar-header' + (this.opts.toolbar_header.cls ? ' ' + this.opts.toolbar_header.cls : '') }); - Render.makeUiElements(Ut.objVal(this.opts.toolbar_header).children, this.toolbarHeader); + Render.makeUiElements(Ut.objVal(this.opts.toolbar_header).children, this.toolbarHeader); - this.ui.append( this.toolbarHeader ); + this.ui.append( this.toolbarHeader ); - Ut.trigger(this.opts.toolbarHeader, this); - } + Ut.trigger(this.opts.toolbarHeader, this); + } - // Make Pagination Area + // Make Pagination Area - makePagination() { - - this.paginationEl = this.ui.appendChild(El('div', { className: 'sp-pagination' })); + makePagination() { + + this.paginationEl = this.ui.appendChild(El('div', { className: 'sp-pagination' })); - this.paginationEl.dxOn('click', 'a', (e, t) => { + this.paginationEl.dxOn('click', 'a', (e, t) => { - this.vars.set('pg', t.dataset.id); + this.vars.set('pg', t.dataset.id); - this.setMode(Table.CLEAN); + this.setMode(Table.CLEAN); - this.makeRequest(); - }); + this.makeRequest(); + }); - this.paginationEl.dxOn('click', 'a.btn-before', (_, t) => { + this.paginationEl.dxOn('click', 'a.btn-before', (_, t) => { - this.vars.set('before', this.data.before); - this.vars.set('after', ''); + this.vars.set('before', this.data.before); + this.vars.set('after', ''); - this.setMode(Table.CLEAN); + this.setMode(Table.CLEAN); - this.makeRequest(); - }); + this.makeRequest(); + }); - this.paginationEl.dxOn('click', 'a.btn-after', function() { + this.paginationEl.dxOn('click', 'a.btn-after', function() { - this.vars.set('before', ''); - this.vars.set('after', this.data.after); + this.vars.set('before', ''); + this.vars.set('after', this.data.after); - this.setMode(Table.CLEAN); + this.setMode(Table.CLEAN); - this.makeRequest(); - }); - } + this.makeRequest(); + }); + } - // Make footer toolbar + // Make footer toolbar - makeToolbarFooter() { + makeToolbarFooter() { - this.toolbarFooter = El('div', { className: 'sp-toolbar toolbar-footer' + (this.opts.toolbar_footer.cls ? ' ' + this.opts.toolbar_footer.cls : '') }); + this.toolbarFooter = El('div', { className: 'sp-toolbar toolbar-footer' + (this.opts.toolbar_footer.cls ? ' ' + this.opts.toolbar_footer.cls : '') }); - Render.makeUiElements(Ut.objVal(this.opts.toolbar_footer).children, this.toolbarFooter); + Render.makeUiElements(Ut.objVal(this.opts.toolbar_footer).children, this.toolbarFooter); - this.ui.append(this.toolbarFooter); + this.ui.append(this.toolbarFooter); - Ut.trigger(this.opts.toolbarFooter, this); - } + Ut.trigger(this.opts.toolbarFooter, this); + } - // Make new ui table + // Make new ui table - makeNewTable() { - this.table = El('div', { className: 'sp-table layout-' + this.opts.layout + (!this.setHeader ? ' no-header' : '') + (this.opts.cls ? ' ' + this.opts.cls : '')}); - this.ui.append(this.table); - } + makeNewTable() { + this.table = El('div', { className: 'sp-table layout-' + this.opts.layout + (!this.setHeader ? ' no-header' : '') + (this.opts.cls ? ' ' + this.opts.cls : '')}); + this.ui.append(this.table); + } - // Make table head + // Make table head - makeTableHead() { + makeTableHead() { - if (!this.setHeader) { - return; - } + if (!this.setHeader) { + return; + } - let header = this.opts.header; + const header = this.opts.header; - let thead = El('div', { className: 'thead' + (header.cls ? ' ' + header.cls : '') }); + const thead = El('div', { className: 'thead' + (header.cls ? ' ' + header.cls : '') }); - let n = 1; + let n = 1; - for (; n < this.data.items[0].length; n++) { - let cell = header.cell ? (header.cell[ n - 1 ] || {}) : {}; - thead.append( El('div', { className: 'th' + (cell.cls ? ' ' + cell.cls : '') }, (cell.text || '') ) ); - } + for (; n < this.data.items[0].length; n++) { + + const cell = header.cell ? (header.cell[ n - 1 ] || {}) : {}; - this.table.prepend(thead); - } + const th = El('div'); - // Make table rows + th.className = 'th'; - makeTableRows() { + if (cell.cls) { + th.className += ` ${cell.cls}`; + } - let that = this; + if (cell.sortable) { - if (this.mode == Table.UPDATE) { + const sortMode = this.vars.get('sort_mode'); + + if (this.vars.get('sort_by') === cell.sortable && (sortMode === 'asc' || sortMode === 'desc')) { + th.className += ` sort-${sortMode}`; + } - let row = this.getRow(this.id); + th.dataset.sortable = cell.sortable; + } - if (row) { + th.textContent = cell.text || ''; - row.dxHtml(''); + thead.append(th); + } - let data = this.data.items[0]; + this.table.prepend(thead); + } - let n = 1; + // Make table rows - for (; n < data.length; n++) { + makeTableRows() { - let cell = that.opts.header.cell ? (that.opts.header.cell[ n - 1 ] || {}) : {}; + let that = this; - let column = El('div', { className: 't-col' }); + if (this.mode == Table.UPDATE) { - row.append( El('div', { className: 'td' + (cell.cls ? ' ' + cell.cls : ''), 'data-label': cell.text }, - column - )); + let row = this.getRow(this.id); - if (data[n]) { - column.dxHtml(data[n]); - } + if (row) { - if (n == 1 && that.opts.sortable) { - column.classList.add('flex', 'v-center'); - column.prepend( El('i', { className: 'handle' }) ); - } - } - } - } - else { + row.dxHtml(''); - this.data.items.forEach((data, i) => { + let data = this.data.items[0]; - let tbody = El('div', { - className: 'tbody' + (that.opts.body && that.opts.body.cls ? ' ' + that.opts.body.cls : ''), - 'data-id': data[0], - 'data-pos': i - }); + let n = 1; - let n = 1; + for (; n < data.length; n++) { - for (; n < data.length; n++) { - - let cell = that.opts.header.cell ? (that.opts.header.cell[ n - 1 ] || {}) : {}; + let cell = that.opts.header.cell ? (that.opts.header.cell[ n - 1 ] || {}) : {}; - let column = El('div', { className: 't-col' }); + let column = El('div', { className: 't-col' }); - tbody.append( El('div', { className: 'td' + (cell.cls ? ' ' + cell.cls : ''), 'data-label': cell.text }, - column - )); + row.append( El('div', { className: 'td' + (cell.cls ? ' ' + cell.cls : ''), 'data-label': cell.text }, + column + )); - if (data[n]) { - column.dxHtml(data[n]); - } + if (data[n]) { + column.dxHtml(data[n]); + } - if (n == 1 && that.opts.sortable) { - column.classList.add('flex', 'v-center'); - column.prepend( El('i', { className: 'handle' }) ); - } + if (n == 1 && that.opts.sortable) { + column.classList.add('flex', 'v-center'); + column.prepend( El('i', { className: 'handle' }) ); + } + } + } + } + else { - if (that.mode == Table.PREPEND) { - that.table.prepend(tbody); - } - else { - that.table.append(tbody); - } - } - }); - } - } + this.data.items.forEach((data, i) => { - // Set info rows + let tbody = El('div', { + className: 'tbody' + (that.opts.body && that.opts.body.cls ? ' ' + that.opts.body.cls : ''), + 'data-id': data[0], + 'data-pos': i + }); - updateInfoRows() { - this.setInfo(this.opts.label.replace(/%rows/g, this.rows)); - } + let n = 1; - // XHR Request + for (; n < data.length; n++) { + + let cell = that.opts.header.cell ? (that.opts.header.cell[ n - 1 ] || {}) : {}; - makeRequest() { + let column = El('div', { className: 't-col' }); - let that = this; + tbody.append( El('div', { className: 'td' + (cell.cls ? ' ' + cell.cls : ''), 'data-label': cell.text }, + column + )); - let vars = {}; - - if (this.mode == Table.UPDATE) { - vars.id = this.id; - } - else { - vars = this.vars; - vars.set('id', 0); - } + if (data[n]) { + column.dxHtml(data[n]); + } - this.reqOpts.vars = vars; + if (n == 1 && that.opts.sortable) { + column.classList.add('flex', 'v-center'); + column.prepend( El('i', { className: 'handle' }) ); + } - this.caller(this.reqOpts).then(jr => { + if (that.mode == Table.PREPEND) { + that.table.prepend(tbody); + } + else { + that.table.append(tbody); + } + } + }); + } + } - if (jr.code != Rc.DONE) { - that.setInfo('No Data'); - return; - } + // Set info rows - that.setTableData(jr.data); - - }).catch(error => console.error(error)); - } + updateInfoRows() { + this.setInfo(this.opts.label.replace(/%rows/g, this.rows)); + } - // Set ui sortable + // XHR Request - setSortable() { + makeRequest() { - let that = this, - isHandle = false, - toDrag; + let that = this; - let isBefore = function(a, b) { - if (a.parentNode == b.parentNode) { - for (let cur = a; cur; cur = cur.previousSibling) { - if (cur === b) { - return true; - } - } - } + let vars = {}; + + if (this.mode == Table.UPDATE) { + vars.id = this.id; + } + else { + vars = this.vars; + vars.set('id', 0); + } - return false; - } + this.reqOpts.vars = vars; - this.table.dxOn('mousedown mouseup', 'i.handle', function(e) { + this.caller(this.reqOpts).then(jr => { - let parent = this.dxParents('.tbody'); + if (jr.code != Rc.DONE) { + that.setInfo('No Data'); + return; + } - if (e.type == 'mousedown') { - isHandle = true; - parent.setAttribute('draggable', true); - } - else { - isHandle = false; - parent.removeAttribute('draggable'); - } + that.setTableData(jr.data); + + }).catch(error => console.error(error)); + } - }); + // Set ui sortable - this.table.dxOn('dragenter', '.tbody', function(e) { + setSortable() { - if (!isHandle) { - return; - } + let that = this, + isHandle = false, + toDrag; - let target = this.matches('.tbody') ? this : this.dxParents('.tbody'); + let isBefore = function(a, b) { + if (a.parentNode == b.parentNode) { + for (let cur = a; cur; cur = cur.previousSibling) { + if (cur === b) { + return true; + } + } + } - if (isBefore( toDrag, target )) { - target.before(toDrag); - } - else { + return false; + } - if (target.nextElementSibling === null) { - $('.sp-table').append( toDrag ); - } - else { - target.nextElementSibling.before(toDrag); - } - } + this.table.dxOn('mousedown mouseup', 'i.handle', function(e) { - }); + let parent = this.dxParents('.tbody'); - this.table.dxOn('dragstart', '.tbody', function(e) { + if (e.type == 'mousedown') { + isHandle = true; + parent.setAttribute('draggable', true); + } + else { + isHandle = false; + parent.removeAttribute('draggable'); + } - if (!isHandle) { - return; - } + }); - toDrag = this; + this.table.dxOn('dragenter', '.tbody', function(e) { - e.dataTransfer.setData('text/plain', null); - e.dataTransfer.effectAllowed = 'move'; + if (!isHandle) { + return; + } - toDrag.style.opacity = 0.4; - }); + let target = this.matches('.tbody') ? this : this.dxParents('.tbody'); - this.table.dxOn('dragend', '.tbody', function(e) { + if (isBefore( toDrag, target )) { + target.before(toDrag); + } + else { - if (!isHandle) { - return; - } + if (target.nextElementSibling === null) { + $('.sp-table').append( toDrag ); + } + else { + target.nextElementSibling.before(toDrag); + } + } - isHandle = false; + }); - let onSort = false; + this.table.dxOn('dragstart', '.tbody', function(e) { - toDrag.style.opacity = ''; - toDrag.removeAttribute('draggable'); + if (!isHandle) { + return; + } - let data = {}; + toDrag = this; - that.table.dxFind('.tbody', (el, i) => { + e.dataTransfer.setData('text/plain', null); + e.dataTransfer.effectAllowed = 'move'; - if (el.dataset.pos != i && !onSort) { - onSort = true; - } + toDrag.style.opacity = 0.4; + }); - if (el.dataset.pos != i) { - - data[ el.dataset.id ] = i; + this.table.dxOn('dragend', '.tbody', function(e) { - el.dataset.pos = i; - } - }); + if (!isHandle) { + return; + } - if (onSort) { - Ut.trigger(that.opts.onSort, that, data); - onSort = false; - } - - }); - } + isHandle = false; - // Update pagination area + let onSort = false; - updatePagination() { + toDrag.style.opacity = ''; + toDrag.removeAttribute('draggable'); - this.paginationEl.dxHtml(''); + let data = {}; - if (this.data.pagination && this.data.pagination.count > 1) { + that.table.dxFind('.tbody', (el, i) => { - let pg_btns = [], - pg_btn, - j = 0; + if (el.dataset.pos != i && !onSort) { + onSort = true; + } - if (this.data.pagination.start > 1) { + if (el.dataset.pos != i) { + + data[ el.dataset.id ] = i; - pg_btns[j] = [ - 1, '<<', false - ]; + el.dataset.pos = i; + } + }); - j = 1; - } + if (onSort) { + Ut.trigger(that.opts.onSort, that, data); + onSort = false; + } + + }); + } - for (let i = this.data.pagination.start; i <= this.data.pagination.end; i++) { + // Set Table Events - pg_btns[j] = [ - i, i, (this.vars.get('pg') == i) - ] + setTableEvents() { - j++; - } + this.table.dxOn('click', '.th[data-sortable]', (_, t) => { - if (this.data.pagination.start > 1 && this.data.pagination.page != this.data.pagination.end) { - pg_btns[j] = [ - this.data.pagination.count, '>>', false - ]; - } + this.vars.set('sort_by', t.dataset.sortable); - pg_btns.forEach((dat) => { + if (!t.classList.contains('sort-asc')) { + + t.className = 'th sort-asc'; - pg_btn = El('a', { - 'data-id': dat[0], - className: (dat[2] ? 'disabled' : '')}, dat[1] - ); + this.vars.set('sort_mode', 'asc'); + this.update(); - this.paginationEl.append(pg_btn); - }); - } - else if (this.data.before || this.data.after) { // update UI + return; + } - if (this.data.before) { - this.paginationEl.append( El('a', { 'data-id': this.data.before, className: 'btn-before' }, '<') ); - } + t.className = 'th sort-desc'; - if (this.data.after) { - this.paginationEl.append( El('a', { 'data-id': this.data.after, className: 'btn-after' }, '>') ); - } - } - } + this.vars.set('sort_mode', 'desc'); + this.update(); + });; + } - // Get All Rows + // Update pagination area - getRows(id) { - return this.table.dxFind('.tbody'); - } + updatePagination() { - // Get Row By ID + this.paginationEl.dxHtml(''); - getRow(id) { - return this.table.dxFind('.tbody[data-id="'+ id +'"]'); - } + if (this.data.pagination && this.data.pagination.count > 1) { - // Update Row Data + let pg_btns = [], + pg_btn, + j = 0; - updateRow(id, data) { + if (this.data.pagination.start > 1) { - this.setMode(Table.UPDATE); - this.id = id; + pg_btns[j] = [ + 1, '<<', false + ]; - if (data) { - this.setTableData(data); - } - else { - this.makeRequest(); - } - } + j = 1; + } - // Update All Rows + for (let i = this.data.pagination.start; i <= this.data.pagination.end; i++) { - update(data) { + pg_btns[j] = [ + i, i, (this.vars.get('pg') == i) + ] - this.setMode(Table.CLEAN); + j++; + } - if (data) { - this.setTableData(data); - } - else { - this.makeRequest(); - } - } + if (this.data.pagination.start > 1 && this.data.pagination.page != this.data.pagination.end) { + pg_btns[j] = [ + this.data.pagination.count, '>>', false + ]; + } - // Delete Row + pg_btns.forEach((dat) => { - deleteRow(id) { + pg_btn = El('a', { + 'data-id': dat[0], + className: (dat[2] ? 'disabled' : '')}, dat[1] + ); - let row = this.getRow(id); + this.paginationEl.append(pg_btn); + }); + } + else if (this.data.before || this.data.after) { // update UI - if (row) { + if (this.data.before) { + this.paginationEl.append( El('a', { 'data-id': this.data.before, className: 'btn-before' }, '<') ); + } - this.rows--; - this.updateInfoRows(); + if (this.data.after) { + this.paginationEl.append( El('a', { 'data-id': this.data.after, className: 'btn-after' }, '>') ); + } + } + } - row.remove(); + // Get All Rows - if (!this.rows) { + getRows(id) { + return this.table.dxFind('.tbody'); + } - let pg = this.vars.get('pg'); + // Get Row By ID - if (pg > 1) { - this.vars.set('pg', --pg); - } + getRow(id) { + return this.table.dxFind('.tbody[data-id="'+ id +'"]'); + } - this.update(); - } + // Update Row Data - Ut.trigger(this.opts.onUpdate, this); - } - } + updateRow(id, data) { - // Add Row At The End of the table + this.setMode(Table.UPDATE); + this.id = id; - appendRow(data) { + if (data) { + this.setTableData(data); + } + else { + this.makeRequest(); + } + } - this.setMode(this.table.children.length ? Table.APPEND : Table.CLEAN); + // Update All Rows - if (data) { - this.setTableData(data); - } - else { - this.makeRequest(); - } - } + update(data) { - // Add Row At Begining of the table + this.setMode(Table.CLEAN); - prependRow(data) { + if (data) { + this.setTableData(data); + } + else { + this.makeRequest(); + } + } - this.setMode(this.table.children.length ? Table.APPEND : Table.CLEAN); + // Delete Row - if (data) { - this.setTableData(data); - } - else { - this.makeRequest(); - } - } + deleteRow(id) { - // Set Info Table + let row = this.getRow(id); - setInfo(text) { - this.info.textContent = text; - }; + if (row) { - // Set Toolbar Header + this.rows--; + this.updateInfoRows(); - setHeaderToolbar(content) { - this.toolbarHeader.dxHtml(content); - } + row.remove(); - // Set Toolbar Footer + if (!this.rows) { - setFooterToolbar(content) { - this.toolbarFooter.dxHtml(content); - } + let pg = this.vars.get('pg'); + + if (pg > 1) { + this.vars.set('pg', --pg); + } + + this.update(); + } + + Ut.trigger(this.opts.onUpdate, this); + } + } + + // Add Row At The End of the table + + appendRow(data) { + + this.setMode(this.table.children.length ? Table.APPEND : Table.CLEAN); + + if (data) { + this.setTableData(data); + } + else { + this.makeRequest(); + } + } + + // Add Row At Begining of the table + + prependRow(data) { + + this.setMode(this.table.children.length ? Table.APPEND : Table.CLEAN); + + if (data) { + this.setTableData(data); + } + else { + this.makeRequest(); + } + } + + // Set Info Table + + setInfo(text) { + this.info.textContent = text; + }; + + // Set Toolbar Header + + setHeaderToolbar(content) { + this.toolbarHeader.dxHtml(content); + } + + // Set Toolbar Footer + + setFooterToolbar(content) { + this.toolbarFooter.dxHtml(content); + } } \ No newline at end of file diff --git a/src/widgets/table/table.css b/src/widgets/table/table.css index b2a777d..c0d7570 100644 --- a/src/widgets/table/table.css +++ b/src/widgets/table/table.css @@ -224,6 +224,8 @@ .sp-table .th { display: table-cell; font-weight: bold; + user-select: none; + -webkit-user-select: none; } .sp-table .td, @@ -231,6 +233,31 @@ vertical-align: middle; } + .sp-table .th[data-sortable] { + cursor: pointer; + } + + .sp-table .th[data-sortable]::after { + content: ''; + width: 14px; + height: 14px; + display: inline-block; + vertical-align: middle; + margin-left: 10px; + background-image: url(data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%3E%3Cpath%20fill%3D%22%23d3d3d3%22%20d%3D%22M7%2013h18a1%201%200%200%200%20.707-1.707l-9-9a1%201%200%200%200-1.414%200l-9%209A1%201%200%200%200%207%2013z%22%2F%3E%3Cpath%20fill%3D%22%23d3d3d3%22%20d%3D%22M25%2019H7a1%201%200%200%200-.707%201.707l9%209a1%201%200%200%200%201.414%200l9-9A1%201%200%200%200%2025%2019z%22%2F%3E%3C%2Fsvg%3E); + background-size: contain; + background-position: center; + background-repeat: no-repeat; + } + + .sp-table .th[data-sortable].sort-asc::after { + background-image: url(data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%3E%3Cpath%20fill%3D%22%238b8b8b%22%20d%3D%22M7%2013h18a1%201%200%200%200%20.707-1.707l-9-9a1%201%200%200%200-1.414%200l-9%209A1%201%200%200%200%207%2013z%22%2F%3E%3Cpath%20fill%3D%22%23d3d3d3%22%20d%3D%22M25%2019H7a1%201%200%200%200-.707%201.707l9%209a1%201%200%200%200%201.414%200l9-9A1%201%200%200%200%2025%2019z%22%2F%3E%3C%2Fsvg%3E); + } + + .sp-table .th[data-sortable].sort-desc::after { + background-image: url(data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%3E%3Cpath%20fill%3D%22%23d3d3d3%22%20d%3D%22M7%2013h18a1%201%200%200%200%20.707-1.707l-9-9a1%201%200%200%200-1.414%200l-9%209A1%201%200%200%200%207%2013z%22%2F%3E%3Cpath%20fill%3D%22%238b8b8b%22%20d%3D%22M25%2019H7a1%201%200%200%200-.707%201.707l9%209a1%201%200%200%200%201.414%200l9-9A1%201%200%200%200%2025%2019z%22%2F%3E%3C%2Fsvg%3E); + } + .sp-table .tbody { display: table-row; border-bottom: 1px solid #dee2e6;