This commit is contained in:
oneao committed 2025-11-24 22:26:06 +08:00
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('&nbsp;')
}
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
+134 -67
View File
@@ -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>