| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669 |
- export default {
- getBootstrapVersion () {
- let bootstrapVersion = 5
- try {
- const rawVersion = $.fn.dropdown.Constructor.VERSION
- // Only try to parse VERSION if it is defined.
- // It is undefined in older versions of Bootstrap (tested with 3.1.1).
- if (rawVersion !== undefined) {
- bootstrapVersion = parseInt(rawVersion, 10)
- }
- } catch (e) {
- // ignore
- }
- try {
- // eslint-disable-next-line no-undef
- const rawVersion = bootstrap.Tooltip.VERSION
- if (rawVersion !== undefined) {
- bootstrapVersion = parseInt(rawVersion, 10)
- }
- } catch (e) {
- // ignore
- }
- return bootstrapVersion
- },
- getIconsPrefix (theme) {
- return {
- bootstrap3: 'glyphicon',
- bootstrap4: 'fa',
- bootstrap5: 'bi',
- 'bootstrap-table': 'icon',
- bulma: 'fa',
- foundation: 'fa',
- materialize: 'material-icons',
- semantic: 'fa'
- }[theme] || 'fa'
- },
- getIcons (prefix) {
- return {
- glyphicon: {
- paginationSwitchDown: 'glyphicon-collapse-down icon-chevron-down',
- paginationSwitchUp: 'glyphicon-collapse-up icon-chevron-up',
- refresh: 'glyphicon-refresh icon-refresh',
- toggleOff: 'glyphicon-list-alt icon-list-alt',
- toggleOn: 'glyphicon-list-alt icon-list-alt',
- columns: 'glyphicon-th icon-th',
- detailOpen: 'glyphicon-plus icon-plus',
- detailClose: 'glyphicon-minus icon-minus',
- fullscreen: 'glyphicon-fullscreen',
- search: 'glyphicon-search',
- clearSearch: 'glyphicon-trash'
- },
- fa: {
- paginationSwitchDown: 'fa-caret-square-down',
- paginationSwitchUp: 'fa-caret-square-up',
- refresh: 'fa-sync',
- toggleOff: 'fa-toggle-off',
- toggleOn: 'fa-toggle-on',
- columns: 'fa-th-list',
- detailOpen: 'fa-plus',
- detailClose: 'fa-minus',
- fullscreen: 'fa-arrows-alt',
- search: 'fa-search',
- clearSearch: 'fa-trash'
- },
- bi: {
- paginationSwitchDown: 'bi-caret-down-square',
- paginationSwitchUp: 'bi-caret-up-square',
- refresh: 'bi-arrow-clockwise',
- toggleOff: 'bi-toggle-off',
- toggleOn: 'bi-toggle-on',
- columns: 'bi-list-ul',
- detailOpen: 'bi-plus',
- detailClose: 'bi-dash',
- fullscreen: 'bi-arrows-move',
- search: 'bi-search',
- clearSearch: 'bi-trash'
- },
- icon: {
- paginationSwitchDown: 'icon-arrow-up-circle',
- paginationSwitchUp: 'icon-arrow-down-circle',
- refresh: 'icon-refresh-cw',
- toggleOff: 'icon-toggle-right',
- toggleOn: 'icon-toggle-right',
- columns: 'icon-list',
- detailOpen: 'icon-plus',
- detailClose: 'icon-minus',
- fullscreen: 'icon-maximize',
- search: 'icon-search',
- clearSearch: 'icon-trash-2'
- },
- 'material-icons': {
- paginationSwitchDown: 'grid_on',
- paginationSwitchUp: 'grid_off',
- refresh: 'refresh',
- toggleOff: 'tablet',
- toggleOn: 'tablet_android',
- columns: 'view_list',
- detailOpen: 'add',
- detailClose: 'remove',
- fullscreen: 'fullscreen',
- sort: 'sort',
- search: 'search',
- clearSearch: 'delete'
- }
- }[prefix]
- },
- getSearchInput (that) {
- if (typeof that.options.searchSelector === 'string') {
- return $(that.options.searchSelector)
- }
- return that.$toolbar.find('.search input')
- },
- // $.extend: https://github.com/jquery/jquery/blob/3.6.2/src/core.js#L132
- extend (...args) {
- let target = args[0] || {}
- let i = 1
- let deep = false
- let clone
- // Handle a deep copy situation
- if (typeof target === 'boolean') {
- deep = target
- // Skip the boolean and the target
- target = args[i] || {}
- i++
- }
- // Handle case when target is a string or something (possible in deep copy)
- if (typeof target !== 'object' && typeof target !== 'function') {
- target = {}
- }
- for (; i < args.length; i++) {
- const options = args[i]
- // Ignore undefined/null values
- if (typeof options === 'undefined' || options === null) {
- continue
- }
- // Extend the base object
- // eslint-disable-next-line guard-for-in
- for (const name in options) {
- const copy = options[name]
- // Prevent Object.prototype pollution
- // Prevent never-ending loop
- if (name === '__proto__' || target === copy) {
- continue
- }
- const copyIsArray = Array.isArray(copy)
- // Recurse if we're merging plain objects or arrays
- if (deep && copy && (this.isObject(copy) || copyIsArray)) {
- const src = target[name]
- if (copyIsArray && Array.isArray(src)) {
- if (src.every(it => !this.isObject(it) && !Array.isArray(it))) {
- target[name] = copy
- continue
- }
- }
- if (copyIsArray && !Array.isArray(src)) {
- clone = []
- } else if (!copyIsArray && !this.isObject(src)) {
- clone = {}
- } else {
- clone = src
- }
- // Never move original objects, clone them
- target[name] = this.extend(deep, clone, copy)
- // Don't bring in undefined values
- } else if (copy !== undefined) {
- target[name] = copy
- }
- }
- }
- return target
- },
- // it only does '%s', and return '' when arguments are undefined
- sprintf (_str, ...args) {
- let flag = true
- let i = 0
- const str = _str.replace(/%s/g, () => {
- const arg = args[i++]
- if (typeof arg === 'undefined') {
- flag = false
- return ''
- }
- return arg
- })
- return flag ? str : ''
- },
- isObject (obj) {
- if (typeof obj !== 'object' || obj === null) {
- return false
- }
- let proto = obj
- while (Object.getPrototypeOf(proto) !== null) {
- proto = Object.getPrototypeOf(proto)
- }
- return Object.getPrototypeOf(obj) === proto
- },
- isEmptyObject (obj = {}) {
- return Object.entries(obj).length === 0 && obj.constructor === Object
- },
- isNumeric (n) {
- return !isNaN(parseFloat(n)) && isFinite(n)
- },
- getFieldTitle (list, value) {
- for (const item of list) {
- if (item.field === value) {
- return item.title
- }
- }
- return ''
- },
- setFieldIndex (columns) {
- let totalCol = 0
- const flag = []
- for (const column of columns[0]) {
- totalCol += column.colspan || 1
- }
- for (let i = 0; i < columns.length; i++) {
- flag[i] = []
- for (let j = 0; j < totalCol; j++) {
- flag[i][j] = false
- }
- }
- for (let i = 0; i < columns.length; i++) {
- for (const r of columns[i]) {
- const rowspan = r.rowspan || 1
- const colspan = r.colspan || 1
- const index = flag[i].indexOf(false)
- r.colspanIndex = index
- if (colspan === 1) {
- r.fieldIndex = index
- // when field is undefined, use index instead
- if (typeof r.field === 'undefined') {
- r.field = index
- }
- } else {
- r.colspanGroup = r.colspan
- }
- for (let j = 0; j < rowspan; j++) {
- for (let k = 0; k < colspan; k++) {
- flag[i + j][index + k] = true
- }
- }
- }
- }
- },
- normalizeAccent (value) {
- if (typeof value !== 'string') {
- return value
- }
- return value.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
- },
- updateFieldGroup (columns, fieldColumns) {
- const allColumns = [].concat(...columns)
- for (const c of columns) {
- for (const r of c) {
- if (r.colspanGroup > 1) {
- let colspan = 0
- for (let i = r.colspanIndex; i < r.colspanIndex + r.colspanGroup; i++) {
- const underColumns = allColumns.filter(col => col.fieldIndex === i)
- const column = underColumns[underColumns.length - 1]
- if(underColumns.length > 1){
- for(let j = 0; j < underColumns.length - 1; j++){
- underColumns[j].visible = column.visible
- }
- }
- if (column.visible) {
- colspan++
- }
- }
- r.colspan = colspan
- r.visible = colspan > 0
- }
- }
- }
- if (columns.length < 2) {
- return
- }
- for (const column of fieldColumns) {
- const sameColumns = allColumns.filter(col => col.fieldIndex === column.fieldIndex)
- if (sameColumns.length > 1) {
- for (const c of sameColumns) {
- c.visible = column.visible
- }
- }
- }
- },
- getScrollBarWidth () {
- if (this.cachedWidth === undefined) {
- const $inner = $('<div/>').addClass('fixed-table-scroll-inner')
- const $outer = $('<div/>').addClass('fixed-table-scroll-outer')
- $outer.append($inner)
- $('body').append($outer)
- const w1 = $inner[0].offsetWidth
- $outer.css('overflow', 'scroll')
- let w2 = $inner[0].offsetWidth
- if (w1 === w2) {
- w2 = $outer[0].clientWidth
- }
- $outer.remove()
- this.cachedWidth = w1 - w2
- }
- return this.cachedWidth
- },
- calculateObjectValue (self, name, args, defaultValue) {
- let func = name
- if (typeof name === 'string') {
- // support obj.func1.func2
- const names = name.split('.')
- if (names.length > 1) {
- func = window
- for (const f of names) {
- func = func[f]
- }
- } else {
- func = window[name]
- }
- }
- if (func !== null && typeof func === 'object') {
- return func
- }
- if (typeof func === 'function') {
- return func.apply(self, args || [])
- }
- if (
- !func &&
- typeof name === 'string' &&
- args &&
- this.sprintf(name, ...args)
- ) {
- return this.sprintf(name, ...args)
- }
- return defaultValue
- },
- compareObjects (objectA, objectB, compareLength) {
- const aKeys = Object.keys(objectA)
- const bKeys = Object.keys(objectB)
- if (compareLength && aKeys.length !== bKeys.length) {
- return false
- }
- for (const key of aKeys) {
- if (bKeys.includes(key) && objectA[key] !== objectB[key]) {
- return false
- }
- }
- return true
- },
- regexCompare (value, search) {
- try {
- const regexpParts = search.match(/^\/(.*?)\/([gim]*)$/)
- if (value.toString().search(regexpParts ? new RegExp(regexpParts[1], regexpParts[2]) : new RegExp(search, 'gim')) !== -1) {
- return true
- }
- } catch (e) {
- return false
- }
- return false
- },
- escapeApostrophe (value) {
- return value.toString()
- .replace(/'/g, ''')
- },
- escapeHTML (text) {
- if (!text) {
- return text
- }
- return text.toString()
- .replace(/&/g, '&')
- .replace(/</g, '<')
- .replace(/>/g, '>')
- .replace(/"/g, '"')
- .replace(/'/g, ''')
- },
- unescapeHTML (text) {
- if (typeof text !== 'string' || !text) {
- return text
- }
- return text.toString()
- .replace(/&/g, '&')
- .replace(/</g, '<')
- .replace(/>/g, '>')
- .replace(/"/g, '"')
- .replace(/'/g, '\'')
- },
- removeHTML (text) {
- if (!text) {
- return text
- }
- return text.toString()
- .replace(/(<([^>]+)>)/ig, '')
- .replace(/&[#A-Za-z0-9]+;/gi, '')
- .trim()
- },
- getRealDataAttr (dataAttr) {
- for (const [attr, value] of Object.entries(dataAttr)) {
- const auxAttr = attr.split(/(?=[A-Z])/).join('-').toLowerCase()
- if (auxAttr !== attr) {
- dataAttr[auxAttr] = value
- delete dataAttr[attr]
- }
- }
- return dataAttr
- },
- getItemField (item, field, escape, columnEscape = undefined) {
- let value = item
- // use column escape if it is defined
- if (typeof columnEscape !== 'undefined') {
- escape = columnEscape
- }
- if (typeof field !== 'string' || item.hasOwnProperty(field)) {
- return escape ? this.escapeHTML(item[field]) : item[field]
- }
- const props = field.split('.')
- for (const p of props) {
- value = value && value[p]
- }
- return escape ? this.escapeHTML(value) : value
- },
- isIEBrowser () {
- return navigator.userAgent.includes('MSIE ') ||
- /Trident.*rv:11\./.test(navigator.userAgent)
- },
- findIndex (items, item) {
- for (const it of items) {
- if (JSON.stringify(it) === JSON.stringify(item)) {
- return items.indexOf(it)
- }
- }
- return -1
- },
- trToData (columns, $els) {
- const data = []
- const m = []
- $els.each((y, el) => {
- const $el = $(el)
- const row = {}
- // save tr's id, class and data-* attributes
- row._id = $el.attr('id')
- row._class = $el.attr('class')
- row._data = this.getRealDataAttr($el.data())
- row._style = $el.attr('style')
- $el.find('>td,>th').each((_x, el) => {
- const $el = $(el)
- const colspan = +$el.attr('colspan') || 1
- const rowspan = +$el.attr('rowspan') || 1
- let x = _x
- // skip already occupied cells in current row
- for (; m[y] && m[y][x]; x++) {
- // ignore
- }
- // mark matrix elements occupied by current cell with true
- for (let tx = x; tx < x + colspan; tx++) {
- for (let ty = y; ty < y + rowspan; ty++) {
- if (!m[ty]) { // fill missing rows
- m[ty] = []
- }
- m[ty][tx] = true
- }
- }
- const field = columns[x].field
- row[field] = this.escapeApostrophe($el.html().trim())
- // save td's id, class and data-* attributes
- row[`_${field}_id`] = $el.attr('id')
- row[`_${field}_class`] = $el.attr('class')
- row[`_${field}_rowspan`] = $el.attr('rowspan')
- row[`_${field}_colspan`] = $el.attr('colspan')
- row[`_${field}_title`] = $el.attr('title')
- row[`_${field}_data`] = this.getRealDataAttr($el.data())
- row[`_${field}_style`] = $el.attr('style')
- })
- data.push(row)
- })
- return data
- },
- sort (a, b, order, options, aPosition, bPosition) {
- if (a === undefined || a === null) {
- a = ''
- }
- if (b === undefined || b === null) {
- b = ''
- }
- if (options.sortStable && a === b) {
- a = aPosition
- b = bPosition
- }
- // If both values are numeric, do a numeric comparison
- if (this.isNumeric(a) && this.isNumeric(b)) {
- // Convert numerical values form string to float.
- a = parseFloat(a)
- b = parseFloat(b)
- if (a < b) {
- return order * -1
- }
- if (a > b) {
- return order
- }
- return 0
- }
- if (options.sortEmptyLast) {
- if (a === '') {
- return 1
- }
- if (b === '') {
- return -1
- }
- }
- if (a === b) {
- return 0
- }
- // If value is not a string, convert to string
- if (typeof a !== 'string') {
- a = a.toString()
- }
- if (a.localeCompare(b) === -1) {
- return order * -1
- }
- return order
- },
- getEventName (eventPrefix, id = '') {
- id = id || `${+new Date()}${~~(Math.random() * 1000000)}`
- return `${eventPrefix}-${id}`
- },
- hasDetailViewIcon (options) {
- return options.detailView && options.detailViewIcon && !options.cardView
- },
- getDetailViewIndexOffset (options) {
- return this.hasDetailViewIcon(options) && options.detailViewAlign !== 'right' ? 1 : 0
- },
- checkAutoMergeCells (data) {
- for (const row of data) {
- for (const key of Object.keys(row)) {
- if (key.startsWith('_') && (key.endsWith('_rowspan') || key.endsWith('_colspan'))) {
- return true
- }
- }
- }
- return false
- },
- deepCopy (arg) {
- if (arg === undefined) {
- return arg
- }
- return this.extend(true, Array.isArray(arg) ? [] : {}, arg)
- },
- debounce (func, wait, immediate) {
- let timeout
- return function executedFunction () {
- const context = this
- const args = arguments
- const later = function () {
- timeout = null
- if (!immediate) func.apply(context, args)
- }
- const callNow = immediate && !timeout
- clearTimeout(timeout)
- timeout = setTimeout(later, wait)
- if (callNow) func.apply(context, args)
- }
- }
- }
|