u
This commit is contained in:
1 parent
a9ea500cd4
commit
f7e7c24d7a
3 files changed
+6555
-67
No files matched your search
@@ -0,0 +1,901 @@
|
||||
/**
|
||||
* DataGrid ScrollView for jQuery EasyUI
|
||||
* version: 1.0.2
|
||||
*/
|
||||
|
||||
$.extend($.fn.datagrid.defaults, {
|
||||
rowHeight: null,
|
||||
maxDivHeight: 10000000,
|
||||
maxVisibleHeight: 15000000,
|
||||
deltaTopHeight: 0,
|
||||
onBeforeFetch(page) {},
|
||||
onFetch(page, rows) {},
|
||||
loader(param, success, error) {
|
||||
let opts = $(this).datagrid('options')
|
||||
if (!opts.url)
|
||||
return false
|
||||
if (opts.view.type == 'scrollview') {
|
||||
param.page = param.page || 1
|
||||
param.rows = param.rows || opts.pageSize
|
||||
}
|
||||
$.ajax({
|
||||
type: opts.method,
|
||||
url: opts.url,
|
||||
data: param,
|
||||
dataType: 'json',
|
||||
success(data) {
|
||||
success(data)
|
||||
},
|
||||
error() {
|
||||
error.apply(this, arguments)
|
||||
},
|
||||
})
|
||||
},
|
||||
})
|
||||
$.extend($.fn.datagrid.defaults.finder, {
|
||||
getRow(target, p) { // p can be row index or tr object
|
||||
let index = (typeof p == 'object') ? p.attr('datagrid-row-index') : p
|
||||
let data = $.data(target, 'datagrid').data
|
||||
let opts = $(target).datagrid('options')
|
||||
if (opts.view.type == 'scrollview') {
|
||||
let firstRows = data.firstRows || []
|
||||
if (index < firstRows.length) {
|
||||
return firstRows[index]
|
||||
}
|
||||
else {
|
||||
index -= opts.view.index
|
||||
}
|
||||
}
|
||||
return data.rows[index]
|
||||
},
|
||||
})
|
||||
|
||||
let scrollview = $.extend({}, $.fn.datagrid.defaults.view, {
|
||||
type: 'scrollview',
|
||||
index: 0,
|
||||
r1: [],
|
||||
r2: [],
|
||||
rows: [],
|
||||
render(target, container, frozen) {
|
||||
let state = $.data(target, 'datagrid')
|
||||
let opts = state.options
|
||||
let rows = this.rows || []
|
||||
if (!rows.length) {
|
||||
return
|
||||
}
|
||||
let fields = $(target).datagrid('getColumnFields', frozen)
|
||||
|
||||
if (frozen) {
|
||||
if (!(opts.rownumbers || (opts.frozenColumns && opts.frozenColumns.length))) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
let index = this.index
|
||||
let table = ['<div class="datagrid-btable-top"></div>', '<table class="datagrid-btable" cellspacing="0" cellpadding="0" border="0"><tbody>']
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
let css = opts.rowStyler ? opts.rowStyler.call(target, index, rows[i]) : ''
|
||||
let classValue = ''
|
||||
let styleValue = ''
|
||||
if (typeof css == 'string') {
|
||||
styleValue = css
|
||||
}
|
||||
else if (css) {
|
||||
classValue = css.class || ''
|
||||
styleValue = css.style || ''
|
||||
}
|
||||
let cls = `class="datagrid-row ${index % 2 && opts.striped ? 'datagrid-row-alt ' : ' '}${classValue}"`
|
||||
let style = styleValue ? `style="${styleValue}"` : ''
|
||||
let rowId = `${state.rowIdPrefix}-${frozen ? 1 : 2}-${index}`
|
||||
table.push(`<tr id="${rowId}" datagrid-row-index="${index}" ${cls} ${style}>`)
|
||||
table.push(this.renderRow.call(this, target, fields, frozen, index, rows[i]))
|
||||
table.push('</tr>')
|
||||
|
||||
// render the detail row
|
||||
if (opts.detailFormatter) {
|
||||
table.push('<tr style="display:none;">')
|
||||
if (frozen) {
|
||||
table.push(`<td colspan=${fields.length + (opts.rownumbers ? 1 : 0)} style="border-right:0">`)
|
||||
}
|
||||
else {
|
||||
table.push(`<td colspan=${fields.length}>`)
|
||||
}
|
||||
table.push('<div class="datagrid-row-detail">')
|
||||
if (frozen) {
|
||||
table.push(' ')
|
||||
}
|
||||
else {
|
||||
table.push(opts.detailFormatter.call(target, index, rows[i]))
|
||||
}
|
||||
table.push('</div>')
|
||||
table.push('</td>')
|
||||
table.push('</tr>')
|
||||
}
|
||||
|
||||
index++
|
||||
}
|
||||
table.push('</tbody></table>')
|
||||
table.push('<div class="datagrid-btable-bottom"></div>')
|
||||
|
||||
$(container).html(table.join(''))
|
||||
},
|
||||
|
||||
renderRow(target, fields, frozen, rowIndex, rowData) {
|
||||
let opts = $.data(target, 'datagrid').options
|
||||
|
||||
let cc = []
|
||||
if (frozen && opts.rownumbers) {
|
||||
let rownumber = rowIndex + 1
|
||||
// if (opts.pagination){
|
||||
// rownumber += (opts.pageNumber-1)*opts.pageSize;
|
||||
// }
|
||||
cc.push(`<td class="datagrid-td-rownumber"><div class="datagrid-cell-rownumber">${rownumber}</div></td>`)
|
||||
}
|
||||
for (let i = 0; i < fields.length; i++) {
|
||||
let field = fields[i]
|
||||
let col = $(target).datagrid('getColumnOption', field)
|
||||
if (col) {
|
||||
let value = rowData[field] // the field value
|
||||
let css = col.styler ? (col.styler(value, rowData, rowIndex) || '') : ''
|
||||
let classValue = ''
|
||||
let styleValue = ''
|
||||
if (typeof css == 'string') {
|
||||
styleValue = css
|
||||
}
|
||||
else if (cc) {
|
||||
classValue = css.class || ''
|
||||
styleValue = css.style || ''
|
||||
}
|
||||
let cls = classValue ? `class="${classValue}"` : ''
|
||||
let style = col.hidden ? `style="display:none;${styleValue}"` : (styleValue ? `style="${styleValue}"` : '')
|
||||
|
||||
cc.push(`<td field="${field}" ${cls} ${style}>`)
|
||||
|
||||
if (col.checkbox) {
|
||||
style = ''
|
||||
}
|
||||
else if (col.expander) {
|
||||
style = 'text-align:center;height:16px;'
|
||||
}
|
||||
else {
|
||||
style = styleValue
|
||||
if (col.align) { style += `;text-align:${col.align};` }
|
||||
if (!opts.nowrap) {
|
||||
style += ';white-space:normal;height:auto;'
|
||||
}
|
||||
else if (opts.autoRowHeight) {
|
||||
style += ';height:auto;'
|
||||
}
|
||||
}
|
||||
|
||||
cc.push(`<div style="${style}" `)
|
||||
if (col.checkbox) {
|
||||
cc.push('class="datagrid-cell-check ')
|
||||
}
|
||||
else {
|
||||
cc.push(`class="datagrid-cell ${col.cellClass}`)
|
||||
}
|
||||
cc.push('">')
|
||||
|
||||
if (col.checkbox) {
|
||||
cc.push(`<input type="checkbox" name="${field}" value="${value != undefined ? value : ''}">`)
|
||||
}
|
||||
else if (col.expander) {
|
||||
// cc.push('<div style="text-align:center;width:16px;height:16px;">');
|
||||
cc.push('<span class="datagrid-row-expander datagrid-row-expand" style="display:inline-block;width:16px;height:16px;cursor:pointer;" />')
|
||||
// cc.push('</div>');
|
||||
}
|
||||
else if (col.formatter) {
|
||||
cc.push(col.formatter(value, rowData, rowIndex))
|
||||
}
|
||||
else {
|
||||
cc.push(value)
|
||||
}
|
||||
|
||||
cc.push('</div>')
|
||||
cc.push('</td>')
|
||||
}
|
||||
}
|
||||
return cc.join('')
|
||||
},
|
||||
|
||||
bindEvents(target) {
|
||||
let state = $.data(target, 'datagrid')
|
||||
let dc = state.dc
|
||||
let opts = state.options
|
||||
let body = dc.body1.add(dc.body2)
|
||||
let clickHandler = ($.data(body[0], 'events') || $._data(body[0], 'events')).click[0].handler
|
||||
body.unbind('click').bind('click', (e) => {
|
||||
let tt = $(e.target)
|
||||
let tr = tt.closest('tr.datagrid-row')
|
||||
if (!tr.length) { return }
|
||||
if (tt.hasClass('datagrid-row-expander')) {
|
||||
let rowIndex = Number.parseInt(tr.attr('datagrid-row-index'))
|
||||
if (tt.hasClass('datagrid-row-expand')) {
|
||||
$(target).datagrid('expandRow', rowIndex)
|
||||
}
|
||||
else {
|
||||
$(target).datagrid('collapseRow', rowIndex)
|
||||
}
|
||||
$(target).datagrid('fixRowHeight')
|
||||
}
|
||||
else {
|
||||
clickHandler(e)
|
||||
}
|
||||
e.stopPropagation()
|
||||
})
|
||||
},
|
||||
|
||||
onBeforeRender(target) {
|
||||
let state = $.data(target, 'datagrid')
|
||||
let opts = state.options
|
||||
let dc = state.dc
|
||||
let view = this
|
||||
|
||||
opts._emptyMsg = opts.emptyMsg // store the emptyMsg value
|
||||
opts.emptyMsg = '' // erase it to prevent from displaying it
|
||||
state.data.firstRows = state.data.rows
|
||||
state.data.rows = []
|
||||
|
||||
dc.body1.add(dc.body2).empty()
|
||||
this.rows = [] // the rows to be rendered
|
||||
this.r1 = this.r2 = [] // the first part and last part of rows
|
||||
|
||||
init()
|
||||
createHeaderExpander()
|
||||
|
||||
function init() {
|
||||
opts.rowHeight = $(target).datagrid('getRowHeight')
|
||||
let pager = $(target).datagrid('getPager')
|
||||
pager.each(function () {
|
||||
$(this).pagination('options').onSelectPage = function (pageNum, pageSize) {
|
||||
opts.pageNumber = pageNum || 1
|
||||
opts.pageSize = pageSize
|
||||
pager.pagination('refresh', {
|
||||
pageNumber: pageNum,
|
||||
pageSize,
|
||||
})
|
||||
$(target).datagrid('gotoPage', opts.pageNumber)
|
||||
}
|
||||
})
|
||||
// erase the onLoadSuccess event, make sure it can't be triggered
|
||||
state.onLoadSuccess = opts.onLoadSuccess
|
||||
opts.onLoadSuccess = function () {}
|
||||
if (!opts.remoteSort) {
|
||||
let onBeforeSortColumn = opts.onBeforeSortColumn
|
||||
opts.onBeforeSortColumn = function (name, order) {
|
||||
let result = onBeforeSortColumn.call(this, name, order)
|
||||
if (result == false) {
|
||||
return false
|
||||
}
|
||||
state.data.rows = state.data.firstRows
|
||||
}
|
||||
}
|
||||
dc.body2.unbind('.datagrid')
|
||||
setTimeout(() => {
|
||||
dc.body2.unbind('.datagrid').bind('scroll.datagrid', (e) => {
|
||||
if (state.onLoadSuccess) {
|
||||
opts.onLoadSuccess = state.onLoadSuccess // restore the onLoadSuccess event
|
||||
state.onLoadSuccess = undefined
|
||||
state.originalRows = $.extend(true, [], state.data.firstRows)
|
||||
}
|
||||
if (view.scrollTimer) {
|
||||
clearTimeout(view.scrollTimer)
|
||||
}
|
||||
view.scrollTimer = setTimeout(() => {
|
||||
view.scrolling.call(view, target)
|
||||
}, 50)
|
||||
})
|
||||
dc.body2.triggerHandler('scroll.datagrid')
|
||||
}, 0)
|
||||
}
|
||||
function createHeaderExpander() {
|
||||
if (!opts.detailFormatter) { return }
|
||||
|
||||
var t = $(target)
|
||||
let hasExpander = false
|
||||
let fields = t.datagrid('getColumnFields', true).concat(t.datagrid('getColumnFields'))
|
||||
for (let i = 0; i < fields.length; i++) {
|
||||
let col = t.datagrid('getColumnOption', fields[i])
|
||||
if (col.expander) {
|
||||
hasExpander = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!hasExpander) {
|
||||
if (opts.frozenColumns && opts.frozenColumns.length) {
|
||||
opts.frozenColumns[0].splice(0, 0, { field: '_expander', expander: true, width: 24, resizable: false, fixed: true })
|
||||
}
|
||||
else {
|
||||
opts.frozenColumns = [[{ field: '_expander', expander: true, width: 24, resizable: false, fixed: true }]]
|
||||
}
|
||||
|
||||
var t = dc.view1.children('div.datagrid-header').find('table')
|
||||
let td = $(`<td rowspan="${opts.frozenColumns.length}"><div class="datagrid-header-expander" style="width:24px;"></div></td>`)
|
||||
if ($('tr', t).length == 0) {
|
||||
td.wrap('<tr></tr>').parent().appendTo($('tbody', t))
|
||||
}
|
||||
else if (opts.rownumbers) {
|
||||
td.insertAfter(t.find('td:has(div.datagrid-header-rownumber)'))
|
||||
}
|
||||
else {
|
||||
td.prependTo(t.find('tr:first'))
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
view.bindEvents(target)
|
||||
}, 0)
|
||||
}
|
||||
},
|
||||
|
||||
onAfterRender(target) {
|
||||
$.fn.datagrid.defaults.view.onAfterRender.call(this, target)
|
||||
let dc = $.data(target, 'datagrid').dc
|
||||
let footer = dc.footer1.add(dc.footer2)
|
||||
footer.find('span.datagrid-row-expander').css('visibility', 'hidden')
|
||||
},
|
||||
|
||||
scrolling(target) {
|
||||
let state = $.data(target, 'datagrid')
|
||||
let opts = state.options
|
||||
let dc = state.dc
|
||||
if (!opts.finder.getRows(target).length) {
|
||||
this.reload.call(this, target)
|
||||
}
|
||||
else {
|
||||
if (!dc.body2.is(':visible')) { return }
|
||||
let headerHeight = dc.view2.children('div.datagrid-header').outerHeight()
|
||||
|
||||
let topDiv = dc.body2.children('div.datagrid-btable-top')
|
||||
let bottomDiv = dc.body2.children('div.datagrid-btable-bottom')
|
||||
if (!topDiv.length || !bottomDiv.length) { return }
|
||||
let top = topDiv.position().top + topDiv._outerHeight() - headerHeight
|
||||
let bottom = bottomDiv.position().top - headerHeight
|
||||
top = Math.floor(top)
|
||||
bottom = Math.floor(bottom)
|
||||
|
||||
if (top > dc.body2.height() || bottom < 0) {
|
||||
this.reload.call(this, target)
|
||||
}
|
||||
else if (top > 0) {
|
||||
var page = Math.floor(this.index / opts.pageSize)
|
||||
this.getRows.call(this, target, page, function (rows) {
|
||||
this.page = page
|
||||
this.r2 = this.r1
|
||||
this.r1 = rows
|
||||
this.index = (page - 1) * opts.pageSize
|
||||
this.rows = this.r1.concat(this.r2)
|
||||
this.populate.call(this, target)
|
||||
})
|
||||
}
|
||||
else if (bottom < dc.body2.height()) {
|
||||
if (state.data.rows.length + this.index >= state.data.total) {
|
||||
return
|
||||
}
|
||||
var page = Math.floor(this.index / opts.pageSize) + 2
|
||||
if (this.r2.length) {
|
||||
page++
|
||||
}
|
||||
this.getRows.call(this, target, page, function (rows) {
|
||||
this.page = page
|
||||
if (!this.r2.length) {
|
||||
this.r2 = rows
|
||||
}
|
||||
else {
|
||||
this.r1 = this.r2
|
||||
this.r2 = rows
|
||||
this.index += opts.pageSize
|
||||
}
|
||||
this.rows = this.r1.concat(this.r2)
|
||||
this.populate.call(this, target)
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
reload(target) {
|
||||
let state = $.data(target, 'datagrid')
|
||||
let opts = state.options
|
||||
let dc = state.dc
|
||||
let top = $(dc.body2).scrollTop() + opts.deltaTopHeight
|
||||
let index = Math.floor(top / opts.rowHeight)
|
||||
let page = Math.floor(index / opts.pageSize) + 1
|
||||
|
||||
this.getRows.call(this, target, page, function (rows) {
|
||||
this.page = page
|
||||
this.index = (page - 1) * opts.pageSize
|
||||
this.rows = rows
|
||||
this.r1 = rows
|
||||
this.r2 = []
|
||||
this.populate.call(this, target)
|
||||
dc.body2.triggerHandler('scroll.datagrid')
|
||||
})
|
||||
},
|
||||
|
||||
getRows(target, page, callback) {
|
||||
let state = $.data(target, 'datagrid')
|
||||
let opts = state.options
|
||||
let index = (page - 1) * opts.pageSize
|
||||
|
||||
// if possible display the empty message
|
||||
opts.emptyMsg = opts._emptyMsg
|
||||
if (this.setEmptyMsg) {
|
||||
this.setEmptyMsg(target)
|
||||
}
|
||||
|
||||
if (index < 0) { return }
|
||||
if (opts.onBeforeFetch.call(target, page) == false) { return }
|
||||
|
||||
let rows = (state.data.firstRows || []).slice(index, index + opts.pageSize)
|
||||
if (rows.length && (rows.length == opts.pageSize || index + rows.length == state.data.total)) {
|
||||
opts.onFetch.call(target, page, rows)
|
||||
callback.call(this, rows)
|
||||
}
|
||||
else {
|
||||
let param = $.extend({}, opts.queryParams, {
|
||||
page,
|
||||
rows: opts.pageSize,
|
||||
})
|
||||
if (opts.sortName) {
|
||||
$.extend(param, {
|
||||
sort: opts.sortName,
|
||||
order: opts.sortOrder,
|
||||
})
|
||||
}
|
||||
if (opts.onBeforeLoad.call(target, param) == false)
|
||||
return
|
||||
|
||||
$(target).datagrid('loading')
|
||||
let result = opts.loader.call(target, param, (data) => {
|
||||
$(target).datagrid('loaded')
|
||||
var data = opts.loadFilter.call(target, data)
|
||||
opts.onFetch.call(target, page, data.rows)
|
||||
if (data.rows && data.rows.length) {
|
||||
callback.call(opts.view, data.rows)
|
||||
}
|
||||
else {
|
||||
opts.onLoadSuccess.call(target, data)
|
||||
}
|
||||
}, function () {
|
||||
$(target).datagrid('loaded')
|
||||
opts.onLoadError.apply(target, arguments)
|
||||
})
|
||||
if (result == false) {
|
||||
$(target).datagrid('loaded')
|
||||
if (!(state.data.firstRows || []).length) {
|
||||
opts.onFetch.call(target, page, state.data.firstRows)
|
||||
opts.onLoadSuccess.call(target, state.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
populate(target) {
|
||||
let state = $.data(target, 'datagrid')
|
||||
let opts = state.options
|
||||
let dc = state.dc
|
||||
let rowHeight = opts.rowHeight
|
||||
let maxHeight = opts.maxDivHeight
|
||||
|
||||
if (this.rows.length) {
|
||||
opts.view.render.call(opts.view, target, dc.body2, false)
|
||||
opts.view.render.call(opts.view, target, dc.body1, true)
|
||||
|
||||
let body = dc.body1.add(dc.body2)
|
||||
let topDiv = body.children('div.datagrid-btable-top')
|
||||
let bottomDiv = body.children('div.datagrid-btable-bottom')
|
||||
let topHeight = this.index * rowHeight
|
||||
let bottomHeight = state.data.total * rowHeight - this.rows.length * rowHeight - topHeight
|
||||
fillHeight(topDiv, topHeight)
|
||||
fillHeight(bottomDiv, bottomHeight)
|
||||
|
||||
state.data.rows = this.rows
|
||||
|
||||
let spos = dc.body2.scrollTop() + opts.deltaTopHeight
|
||||
if (topHeight > opts.maxVisibleHeight) {
|
||||
opts.deltaTopHeight = topHeight - opts.maxVisibleHeight
|
||||
fillHeight(topDiv, topHeight - opts.deltaTopHeight)
|
||||
}
|
||||
else {
|
||||
opts.deltaTopHeight = 0
|
||||
}
|
||||
if (bottomHeight > opts.maxVisibleHeight) {
|
||||
fillHeight(bottomDiv, opts.maxVisibleHeight)
|
||||
}
|
||||
else if (bottomHeight == 0) {
|
||||
let lastCount = state.data.total % opts.pageSize
|
||||
if (lastCount) {
|
||||
fillHeight(bottomDiv, dc.body2.height() - lastCount * rowHeight)
|
||||
}
|
||||
}
|
||||
|
||||
$(target).datagrid('setSelectionState')
|
||||
dc.body2.scrollTop(spos - opts.deltaTopHeight)
|
||||
|
||||
opts.pageNumber = this.page
|
||||
let pager = $(target).datagrid('getPager')
|
||||
if (pager.length) {
|
||||
let popts = pager.pagination('options')
|
||||
let displayMsg = popts.displayMsg
|
||||
let msg = displayMsg.replace(/\{from\}/, this.index + 1)
|
||||
msg = msg.replace(/\{to\}/, this.index + this.rows.length)
|
||||
pager.pagination('refresh', {
|
||||
pageNumber: this.page,
|
||||
displayMsg: msg,
|
||||
})
|
||||
popts.displayMsg = displayMsg
|
||||
}
|
||||
if (this.setEmptyMsg) {
|
||||
this.setEmptyMsg(target)
|
||||
}
|
||||
|
||||
opts.onLoadSuccess.call(target, {
|
||||
total: state.data.total,
|
||||
rows: this.rows,
|
||||
})
|
||||
}
|
||||
function fillHeight(div, height) {
|
||||
let count = Math.floor(height / maxHeight)
|
||||
let leftHeight = height - maxHeight * count
|
||||
if (height < 0) {
|
||||
leftHeight = 0
|
||||
}
|
||||
let cc = []
|
||||
for (let i = 0; i < count; i++) {
|
||||
cc.push(`<div style="height:${maxHeight}px"></div>`)
|
||||
}
|
||||
cc.push(`<div style="height:${leftHeight}px"></div>`)
|
||||
$(div).html(cc.join(''))
|
||||
}
|
||||
},
|
||||
|
||||
updateRow(target, rowIndex, row) {
|
||||
let opts = $.data(target, 'datagrid').options
|
||||
let rows = $(target).datagrid('getRows')
|
||||
let rowData = opts.finder.getRow(target, rowIndex)
|
||||
let oldStyle = _getRowStyle(rowIndex)
|
||||
$.extend(rowData, row)
|
||||
let newStyle = _getRowStyle(rowIndex)
|
||||
let oldClassValue = oldStyle.c
|
||||
let styleValue = newStyle.s
|
||||
let classValue = `datagrid-row ${rowIndex % 2 && opts.striped ? 'datagrid-row-alt ' : ' '}${newStyle.c}`
|
||||
|
||||
function _getRowStyle(rowIndex) {
|
||||
let css = opts.rowStyler ? opts.rowStyler.call(target, rowIndex, rowData) : ''
|
||||
let classValue = ''
|
||||
let styleValue = ''
|
||||
if (typeof css == 'string') {
|
||||
styleValue = css
|
||||
}
|
||||
else if (css) {
|
||||
classValue = css.class || ''
|
||||
styleValue = css.style || ''
|
||||
}
|
||||
return { c: classValue, s: styleValue }
|
||||
}
|
||||
function _update(frozen) {
|
||||
let fields = $(target).datagrid('getColumnFields', frozen)
|
||||
let tr = opts.finder.getTr(target, rowIndex, 'body', (frozen ? 1 : 2))
|
||||
let checked = tr.find('div.datagrid-cell-check input[type=checkbox]').is(':checked')
|
||||
tr.html(this.renderRow.call(this, target, fields, frozen, rowIndex, rowData))
|
||||
tr.attr('style', styleValue).removeClass(oldClassValue).addClass(classValue)
|
||||
if (checked) {
|
||||
tr.find('div.datagrid-cell-check input[type=checkbox]')._propAttr('checked', true)
|
||||
}
|
||||
}
|
||||
|
||||
_update.call(this, true)
|
||||
_update.call(this, false)
|
||||
$(target).datagrid('fixRowHeight', rowIndex)
|
||||
},
|
||||
|
||||
// insertRow: function(target, index, row){
|
||||
// var state = $.data(target, 'datagrid');
|
||||
// var data = state.data;
|
||||
|
||||
// if (index == undefined || index == null) index = data.rows.length;
|
||||
// if (index > data.rows.length) index = data.rows.length;
|
||||
// $.fn.datagrid.defaults.view.insertRow.call(this, target, index, row);
|
||||
// if (data.firstRows && index <= data.firstRows.length){
|
||||
// data.firstRows.splice(index, 0, row);
|
||||
// }
|
||||
// },
|
||||
insertRow(target, index, row) {
|
||||
let state = $.data(target, 'datagrid')
|
||||
let opts = state.options
|
||||
let data = state.data
|
||||
|
||||
let total = $(target).datagrid('getData').total
|
||||
if (index == null) { index = total }
|
||||
if (index > total) { index = total }
|
||||
if (data.firstRows && index <= data.firstRows.length) {
|
||||
data.firstRows.splice(index, 0, row)
|
||||
}
|
||||
data.total++
|
||||
|
||||
let rows = this.r1.concat(this.r2)
|
||||
if (index < this.index) {
|
||||
this.reload.call(this, target)
|
||||
}
|
||||
else if (index <= this.index + rows.length) {
|
||||
rows.splice(index - this.index, 0, row)
|
||||
this.r1 = rows.splice(0, opts.pageSize)
|
||||
if (this.r2.length) {
|
||||
this.r2 = rows.splice(0, opts.pageSize)
|
||||
}
|
||||
this.rows = this.r1.concat(this.r2)
|
||||
this.populate.call(this, target)
|
||||
state.dc.body2.triggerHandler('scroll.datagrid')
|
||||
}
|
||||
},
|
||||
|
||||
// deleteRow: function(target, index){
|
||||
// var data = $(target).datagrid('getData');
|
||||
// $.fn.datagrid.defaults.view.deleteRow.call(this, target, index);
|
||||
// if (data.firstRows){
|
||||
// data.firstRows.splice(index, 1);
|
||||
// }
|
||||
// },
|
||||
deleteRow(target, index) {
|
||||
let state = $.data(target, 'datagrid')
|
||||
let data = state.data
|
||||
let opts = state.options
|
||||
data.total--
|
||||
if (data.firstRows) {
|
||||
if (index < data.firstRows.length) {
|
||||
data.firstRows.splice(index, 1)
|
||||
if (data.total) {
|
||||
this.reload.call(this, target)
|
||||
}
|
||||
else {
|
||||
// $(target).datagrid('loadData', [])
|
||||
state.data.rows = []
|
||||
$(state.dc.body1).empty()
|
||||
$(state.dc.body2).empty()
|
||||
if (this.setEmptyMsg) {
|
||||
this.setEmptyMsg.call(this, target)
|
||||
}
|
||||
}
|
||||
// this.reload.call(this, target);
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
let rows = this.r1.concat(this.r2)
|
||||
if (index < this.index) {
|
||||
this.reload.call(this, target)
|
||||
}
|
||||
else if (index < this.index + rows.length) {
|
||||
rows.splice(index - this.index, 1)
|
||||
this.r1 = rows.splice(0, opts.pageSize)
|
||||
if (this.r1.length < opts.pageSize) {
|
||||
this.reload.call(this, target)
|
||||
}
|
||||
else {
|
||||
this.r2 = []
|
||||
this.rows = this.r1.concat(this.r2)
|
||||
this.populate.call(this, target)
|
||||
state.dc.body2.triggerHandler('scroll.datagrid')
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
$.fn.datagrid.methods.baseUpdateRow = $.fn.datagrid.methods.updateRow
|
||||
$.fn.datagrid.methods.baseGetRowIndex = $.fn.datagrid.methods.getRowIndex
|
||||
$.fn.datagrid.methods.baseScrollTo = $.fn.datagrid.methods.scrollTo
|
||||
$.fn.datagrid.methods.baseGotoPage = $.fn.datagrid.methods.gotoPage
|
||||
$.fn.datagrid.methods.baseSetSelectionState = $.fn.datagrid.methods.setSelectionState
|
||||
$.extend($.fn.datagrid.methods, {
|
||||
getRowHeight(jq) {
|
||||
let opts = jq.datagrid('options')
|
||||
if (!opts.rowHeight) {
|
||||
let d = $('<div style="position:absolute;top:-1000px;width:100px;height:100px;padding:5px"><table><tr class="datagrid-row"><td>cell</td></tr></table></div>').appendTo('body')
|
||||
let rowHeight = d.find('tr').outerHeight()
|
||||
d.remove()
|
||||
opts.rowHeight = rowHeight
|
||||
}
|
||||
return opts.rowHeight
|
||||
},
|
||||
updateRow(jq, param) {
|
||||
return jq.each(function () {
|
||||
let opts = $(this).datagrid('options')
|
||||
let row = opts.finder.getRow(this, param.index)
|
||||
if (row) {
|
||||
$(this).datagrid('baseUpdateRow', param)
|
||||
}
|
||||
else {
|
||||
let firstRows = $(this).datagrid('getData').firstRows || []
|
||||
if (param.index < firstRows.length) {
|
||||
$.extend(firstRows[param.index], param.row)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
getRowIndex(jq, row) {
|
||||
let opts = jq.datagrid('options')
|
||||
if (opts.view.type == 'scrollview') {
|
||||
let data = jq.datagrid('getData')
|
||||
let firstRows = data.firstRows || []
|
||||
if (typeof row == 'object') {
|
||||
var index = $.easyui.indexOfArray(firstRows, row)
|
||||
}
|
||||
else {
|
||||
var index = $.easyui.indexOfArray(firstRows, opts.idField, row)
|
||||
}
|
||||
if (index >= 0) {
|
||||
return index
|
||||
}
|
||||
else {
|
||||
index = jq.datagrid('baseGetRowIndex', row)
|
||||
return (index == -1) ? -1 : index + opts.view.index
|
||||
}
|
||||
}
|
||||
else {
|
||||
return jq.datagrid('baseGetRowIndex', row)
|
||||
}
|
||||
},
|
||||
getRow(jq, index) {
|
||||
return jq.datagrid('options').finder.getRow(jq[0], index)
|
||||
},
|
||||
gotoPage(jq, param) {
|
||||
return jq.each(function () {
|
||||
let target = this
|
||||
let opts = $(target).datagrid('options')
|
||||
if (opts.view.type == 'scrollview') {
|
||||
let page, callback
|
||||
if (typeof param == 'object') {
|
||||
page = param.page
|
||||
callback = param.callback
|
||||
}
|
||||
else {
|
||||
page = param
|
||||
}
|
||||
opts.view.getRows.call(opts.view, target, page, function (rows) {
|
||||
this.page = page
|
||||
this.index = (page - 1) * opts.pageSize
|
||||
this.rows = rows
|
||||
this.r1 = rows
|
||||
this.r2 = []
|
||||
this.populate.call(this, target)
|
||||
$(target).data('datagrid').dc.body2.scrollTop(this.index * opts.rowHeight - opts.deltaTopHeight)
|
||||
if (callback) {
|
||||
callback.call(target, page)
|
||||
}
|
||||
})
|
||||
}
|
||||
else {
|
||||
$(target).datagrid('baseGotoPage', param)
|
||||
}
|
||||
})
|
||||
},
|
||||
scrollTo(jq, param) {
|
||||
return jq.each(function () {
|
||||
let target = this
|
||||
let opts = $(target).datagrid('options')
|
||||
let index, callback
|
||||
if (typeof param == 'object') {
|
||||
index = param.index
|
||||
callback = param.callback
|
||||
}
|
||||
else {
|
||||
index = param
|
||||
}
|
||||
let view = opts.view
|
||||
if (view.type == 'scrollview') {
|
||||
if (index >= view.index && index < view.index + view.rows.length) {
|
||||
$(target).datagrid('baseScrollTo', index)
|
||||
if (callback) {
|
||||
callback.call(target, index)
|
||||
}
|
||||
}
|
||||
else if (index >= 0) {
|
||||
let page = Math.floor(index / opts.pageSize) + 1
|
||||
$(target).datagrid('gotoPage', {
|
||||
page,
|
||||
callback() {
|
||||
setTimeout(() => {
|
||||
$(target).datagrid('baseScrollTo', index)
|
||||
if (callback) {
|
||||
callback.call(target, index)
|
||||
}
|
||||
}, 0)
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
else {
|
||||
$(target).datagrid('baseScrollTo', index)
|
||||
if (callback) {
|
||||
callback.call(target, index)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
setSelectionState(jq) {
|
||||
return jq.each(function () {
|
||||
let target = this
|
||||
let opts = $(target).datagrid('options')
|
||||
if (opts.view.type == 'scrollview') {
|
||||
$(target).datagrid('baseSetSelectionState')
|
||||
let state = $(target).data('datagrid')
|
||||
if ((state.data.firstRows || []).length != state.checkedRows.length) {
|
||||
let dc = state.dc
|
||||
dc.header1.add(dc.header2).find('input[type=checkbox]')._propAttr('checked', false)
|
||||
}
|
||||
}
|
||||
else {
|
||||
$(target).datagrid('baseSetSelectionState')
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
$.extend($.fn.datagrid.methods, {
|
||||
fixDetailRowHeight(jq, index) {
|
||||
return jq.each(function () {
|
||||
let opts = $.data(this, 'datagrid').options
|
||||
let dc = $.data(this, 'datagrid').dc
|
||||
let tr1 = opts.finder.getTr(this, index, 'body', 1).next()
|
||||
let tr2 = opts.finder.getTr(this, index, 'body', 2).next()
|
||||
// fix the detail row height
|
||||
if (tr2.is(':visible')) {
|
||||
tr1.css('height', '')
|
||||
tr2.css('height', '')
|
||||
let height = Math.max(tr1.height(), tr2.height())
|
||||
tr1.css('height', height)
|
||||
tr2.css('height', height)
|
||||
}
|
||||
dc.body2.triggerHandler('scroll')
|
||||
})
|
||||
},
|
||||
getExpander(jq, index) { // get row expander object
|
||||
let opts = $.data(jq[0], 'datagrid').options
|
||||
return opts.finder.getTr(jq[0], index).find('span.datagrid-row-expander')
|
||||
},
|
||||
// get row detail container
|
||||
getRowDetail(jq, index) {
|
||||
let opts = $.data(jq[0], 'datagrid').options
|
||||
let tr = opts.finder.getTr(jq[0], index, 'body', 2)
|
||||
return tr.next().find('div.datagrid-row-detail')
|
||||
},
|
||||
expandRow(jq, index) {
|
||||
return jq.each(function () {
|
||||
let opts = $(this).datagrid('options')
|
||||
let dc = $.data(this, 'datagrid').dc
|
||||
let expander = $(this).datagrid('getExpander', index)
|
||||
if (expander.hasClass('datagrid-row-expand')) {
|
||||
expander.removeClass('datagrid-row-expand').addClass('datagrid-row-collapse')
|
||||
let tr1 = opts.finder.getTr(this, index, 'body', 1).next()
|
||||
let tr2 = opts.finder.getTr(this, index, 'body', 2).next()
|
||||
tr1.show()
|
||||
tr2.show()
|
||||
$(this).datagrid('fixDetailRowHeight', index)
|
||||
if (opts.onExpandRow) {
|
||||
// var row = $(this).datagrid('getRows')[index];
|
||||
let row = $(this).datagrid('getRow', index)
|
||||
opts.onExpandRow.call(this, index, row)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
collapseRow(jq, index) {
|
||||
return jq.each(function () {
|
||||
let opts = $(this).datagrid('options')
|
||||
let dc = $.data(this, 'datagrid').dc
|
||||
let expander = $(this).datagrid('getExpander', index)
|
||||
if (expander.hasClass('datagrid-row-collapse')) {
|
||||
expander.removeClass('datagrid-row-collapse').addClass('datagrid-row-expand')
|
||||
let tr1 = opts.finder.getTr(this, index, 'body', 1).next()
|
||||
let tr2 = opts.finder.getTr(this, index, 'body', 2).next()
|
||||
tr1.hide()
|
||||
tr2.hide()
|
||||
dc.body2.triggerHandler('scroll')
|
||||
if (opts.onCollapseRow) {
|
||||
let row = $(this).datagrid('getRows')[index]
|
||||
opts.onCollapseRow.call(this, index, row)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,76 +1,143 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>DataGrid Virtual Scrolling - jQuery EasyUI Demo</title>
|
||||
<link rel="stylesheet" type="text/css" href="https://www.jeasyui.com/easyui/themes/default/easyui.css">
|
||||
<link rel="stylesheet" type="text/css" href="https://www.jeasyui.com/easyui/themes/icon.css">
|
||||
<script type="text/javascript" src="https://www.jeasyui.com/easyui/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="https://www.jeasyui.com/easyui/jquery.easyui.min.js"></script>
|
||||
<script type="text/javascript" src="https://www.jeasyui.com/easyui/datagrid-scrollview.js"></script>
|
||||
<meta charset="UTF-8">
|
||||
<title>DataGrid VirtualScrollView + UUID + CheckedMap</title>
|
||||
<link rel="stylesheet" type="text/css" href="http://www.jeasyui.com/easyui/themes/default/easyui.css">
|
||||
<link rel="stylesheet" type="text/css" href="http://www.jeasyui.com/easyui/themes/icon.css">
|
||||
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
|
||||
<script src="http://www.jeasyui.com/easyui/jquery.easyui.min.js"></script>
|
||||
<script src="http://www.jeasyui.com/easyui/datagrid-scrollview.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h2>DataGrid Virtual Scroll View Demo</h2>
|
||||
<p>Drag the vertical scroll and release it to navigate to the desired page.</p>
|
||||
|
||||
<div style="margin-bottom:10px">
|
||||
<select onchange="load(this.value)">
|
||||
<option value="remote">Load Remote Data</option>
|
||||
<option value="local">Load Local Data</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<table id="tt" title="DataGrid - VirtualScrollView" style="width:700px;height:300px" data-options="
|
||||
view:scrollview,rownumbers:true,singleSelect:true,
|
||||
url:'datagrid27_getdata.php',
|
||||
idField:'inv',autoRowHeight:false,pageSize:50">
|
||||
<thead>
|
||||
<tr>
|
||||
<th field="inv" width="80">Inv No</th>
|
||||
<th field="date" width="100">Date</th>
|
||||
<th field="name" width="80">Name</th>
|
||||
<th field="amount" width="80" align="right">Amount</th>
|
||||
<th field="price" width="80" align="right">Price</th>
|
||||
<th field="cost" width="100" align="right">Cost</th>
|
||||
<th field="note" width="110">Note</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
$('#tt').datagrid();
|
||||
|
||||
<div class="toolbar">
|
||||
<a href="javascript:void(0)" onclick="generateData(50)" class="easyui-linkbutton">生成50条数据</a>
|
||||
<a href="javascript:void(0)" onclick="generateData(200)" class="easyui-linkbutton">生成200条数据</a>
|
||||
<a href="javascript:void(0)" onclick="checkAllGlobal()" class="easyui-linkbutton">全选</a>
|
||||
<a href="javascript:void(0)" onclick="uncheckAllGlobal()" class="easyui-linkbutton">取消全选</a>
|
||||
<a href="javascript:void(0)" onclick="debugCheckedMap()" class="easyui-linkbutton">调试选中状态</a>
|
||||
<a href="javascript:void(0)" onclick="getCheckedData()" class="easyui-linkbutton">获取选中数据</a>
|
||||
</div>
|
||||
|
||||
<table id="tt" class="easyui-datagrid" style="width:800px;height:400px"
|
||||
data-options="
|
||||
idField:'mx_xh',
|
||||
view:scrollview,
|
||||
singleSelect:false,
|
||||
autoRowHeight:false,
|
||||
pageSize:30,
|
||||
checkOnSelect:false,
|
||||
selectOnCheck:true
|
||||
">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-options="field:'ck',checkbox:true"></th>
|
||||
<th field="subid" width="150">SubID</th>
|
||||
<th field="mx_xh" width="150">MX_XH</th>
|
||||
<th field="inv" width="100">Inv No</th>
|
||||
<th field="name" width="100">Name</th>
|
||||
<th field="amount" width="80">Amount</th>
|
||||
<th field="price" width="80">Price</th>
|
||||
<th field="cost" width="100">Cost</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
|
||||
<div id="selCount" style="margin-top:10px;color:blue;font-weight:bold;">已选:0</div>
|
||||
|
||||
<script>
|
||||
let allRows = [];
|
||||
let checkedMap = new Set();
|
||||
let suppressCheckEvents = false;
|
||||
|
||||
function uuid() {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
let r = Math.random()*16|0, v = c=='x'?r:(r&0x3|0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
|
||||
function getCheckedData(){
|
||||
if(isCheckAll){
|
||||
// 返回全部数据
|
||||
console.log( $('#tt').datagrid('getData').firstRows);
|
||||
}else{
|
||||
console.log( $('#tt').datagrid('getChecked'));
|
||||
}
|
||||
}
|
||||
|
||||
function loadInitialData() {
|
||||
let rows = [];
|
||||
for (let i = 1; i <= 100; i++) {
|
||||
rows.push({
|
||||
subid: uuid(),
|
||||
mx_xh: 'MX-' + String(i).padStart(3, '0'), // 顺序编号,3位补零
|
||||
inv: 'INV-' + i,
|
||||
name: 'Person ' + i,
|
||||
amount: Math.floor(Math.random() * 100),
|
||||
price: Math.floor(Math.random() * 100),
|
||||
cost: Math.floor(Math.random() * 10000)
|
||||
});
|
||||
function loadLocal(){
|
||||
var rows = [];
|
||||
for(var i=1; i<=8000; i++){
|
||||
var amount = Math.floor(Math.random()*1000);
|
||||
var price = Math.floor(Math.random()*1000);
|
||||
rows.push({
|
||||
inv: 'Inv No '+i,
|
||||
date: $.fn.datebox.defaults.formatter(new Date()),
|
||||
name: 'Name '+i,
|
||||
amount: amount,
|
||||
price: price,
|
||||
cost: amount*price,
|
||||
note: 'Note '+i
|
||||
});
|
||||
}
|
||||
$('#tt').datagrid('loadData', rows);
|
||||
}
|
||||
allRows = rows;
|
||||
$('#tt').datagrid('loadData', { total: rows.length, rows: rows });
|
||||
}
|
||||
|
||||
|
||||
function generateData(count){
|
||||
let newRows = [];
|
||||
let startIndex = allRows.length + 1;
|
||||
for(let i=0;i<count;i++){
|
||||
newRows.push({
|
||||
subid: '',
|
||||
mx_xh: uuid(),
|
||||
inv: 'INV-'+(startIndex+i),
|
||||
name: 'Person '+(startIndex+i),
|
||||
amount: Math.floor(Math.random()*100),
|
||||
price: Math.floor(Math.random()*100),
|
||||
cost: Math.floor(Math.random()*10000)
|
||||
});
|
||||
}
|
||||
allRows = allRows.concat(newRows);
|
||||
$('#tt').datagrid('loadData', { total: allRows.length, rows: allRows });
|
||||
}
|
||||
|
||||
function updateSelCount(){
|
||||
$('#selCount').text('已选:'+checkedMap.size);
|
||||
}
|
||||
|
||||
let isCheckAll = false
|
||||
$(function(){
|
||||
loadInitialData();
|
||||
|
||||
$('#tt').datagrid({
|
||||
onCheck: function(index, row){
|
||||
},
|
||||
onUncheck: function(index, row){
|
||||
isCheckAll = false
|
||||
},
|
||||
onCheckAll: function(){
|
||||
isCheckAll = true
|
||||
},
|
||||
onUncheckAll: function(){
|
||||
console.log("===onUncheckAll===")
|
||||
isCheckAll = false
|
||||
},
|
||||
onFetch: function(page, rows) {
|
||||
setTimeout(() => {
|
||||
if(isCheckAll){
|
||||
$('#tt').datagrid("checkAll")
|
||||
}
|
||||
})
|
||||
},
|
||||
onLoadSuccess: function(data) {
|
||||
},
|
||||
onLoadError: function() {
|
||||
}
|
||||
function load(mode){
|
||||
if (mode == 'local'){
|
||||
loadLocal();
|
||||
} else {
|
||||
$('#tt').datagrid({
|
||||
url:'datagrid27_getdata.php'
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style type="text/css">
|
||||
.datagrid-header-rownumber,.datagrid-cell-rownumber{
|
||||
width:40px;
|
||||
}
|
||||
</style>
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user