405 lines
14 KiB
JavaScript
405 lines
14 KiB
JavaScript
$.extend($.fn.datagrid.defaults, {
|
|
onBeforeFetch: function(page){},
|
|
onFetch: function(page, rows){}
|
|
});
|
|
|
|
var bufferview = $.extend({}, $.fn.datagrid.defaults.view, {
|
|
onAfterRender : function(target){
|
|
},
|
|
render: function(target, container, frozen){
|
|
var state = $.data(target, 'datagrid');
|
|
var opts = state.options;
|
|
var rows = this.rows || [];
|
|
if (!rows.length) {
|
|
return;
|
|
}
|
|
var fields = $(target).datagrid('getColumnFields', frozen);
|
|
|
|
if (frozen){
|
|
if (!(opts.rownumbers || (opts.frozenColumns && opts.frozenColumns.length))){
|
|
return;
|
|
}
|
|
}
|
|
|
|
var index = parseInt(opts.finder.getTr(target,'','last',(frozen?1:2)).attr('datagrid-row-index'))+1 || 0;
|
|
if(index >= state.data.total){
|
|
return;
|
|
}
|
|
|
|
var table = ['<table class="datagrid-btable" cellspacing="0" cellpadding="0" border="0"><tbody>'];
|
|
for(var i=0; i<rows.length; i++) {
|
|
// get the class and style attributes for this row
|
|
var css = opts.rowStyler ? opts.rowStyler.call(target, index, rows[i]) : '';
|
|
var classValue = '';
|
|
var styleValue = '';
|
|
if (typeof css == 'string'){
|
|
styleValue = css;
|
|
} else if (css){
|
|
classValue = css['class'] || '';
|
|
styleValue = css['style'] || '';
|
|
}
|
|
|
|
var cls = 'class="datagrid-row ' + (index % 2 && opts.striped ? 'datagrid-row-alt ' : ' ') + classValue + '"';
|
|
var style = styleValue ? 'style="' + styleValue + '"' : '';
|
|
var 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+2) + ' 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>');
|
|
|
|
$(container).append(table.join(''));
|
|
},
|
|
|
|
renderRow : function(target, fields, frozen, rowIndex, rowData) { //method backup from the source
|
|
var opts = $.data(target, "datagrid").options,
|
|
cc = [],
|
|
rowSpanField = typeof opts.columns[0]['rowSpanField'] !== 'undefined' ? opts.columns[0]['rowSpanField'] : '',
|
|
rowSpan = rowSpanField !== '' && typeof rowData[rowSpanField]['numRows'] !== 'undefined' ? rowData[rowSpanField]['numRows'] : 1;
|
|
|
|
if (frozen && opts.rownumbers) {
|
|
var _726 = rowIndex + 1;
|
|
if (opts.pagination) {
|
|
_726 += (opts.pageNumber - 1) * opts.pageSize;
|
|
}
|
|
cc.push("<td class=\"datagrid-td-rownumber\"><div class=\"datagrid-cell-rownumber\">" + _726 + "</div></td>");
|
|
}
|
|
|
|
for (var i = 0; i < fields.length; i++) {
|
|
var _727 = fields[i];
|
|
var col = $(target).datagrid("getColumnOption", _727);
|
|
if (col) {
|
|
var _728 = rowData[_727];
|
|
var css = col.styler ? (col.styler(_728, rowData, rowIndex, col) || "") : "";
|
|
var _729 = "";
|
|
var _72a = "";
|
|
if (typeof css == "string") {
|
|
_72a = css;
|
|
} else {
|
|
if (css) {
|
|
_729 = css["class"] || "";
|
|
_72a = css["style"] || "";
|
|
}
|
|
}
|
|
var cls = _729 ? "class=\"" + _729 + ( frozen ? 'frozen-td' : '' ) + "\"" : ( frozen ? 'class="frozen-td"' : '' );
|
|
var _72b = col.hidden ? "style=\"display:none;" + _72a + "\"" : (_72a ? "style=\"" + _72a + "\"" : "");
|
|
cc.push("<td field=\"" + _727 + "\" " + cls + " " + _72b + ">");
|
|
var _72b = "";
|
|
if (!col.checkbox) {
|
|
if (col.align) {
|
|
_72b += "text-align:" + col.align + ";";
|
|
}else if (col.expander){
|
|
style = "text-align:center;height:16px;";
|
|
}
|
|
if (!opts.nowrap) {
|
|
_72b += "white-space:normal;height:auto;";
|
|
} else {
|
|
if (opts.autoRowHeight) {
|
|
_72b += "height:auto;";
|
|
}
|
|
}
|
|
}
|
|
cc.push("<div style=\"" + _72b + "\" ");
|
|
cc.push(col.checkbox ? "class=\"datagrid-cell-check\"" : "class=\"datagrid-cell " + col.cellClass + "\"");
|
|
cc.push(">");
|
|
|
|
if (col.checkbox) {
|
|
cc.push("<input type=\"checkbox\" " + (rowData.checked ? "checked=\"checked\"" : ""));
|
|
cc.push(" name=\"" + _727 + "\" value=\"" + (_728 != undefined ? _728 : "") + "\">");
|
|
}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){
|
|
// console.log('bufferview.renderRow():', col);
|
|
cc.push(col.formatter(_728, rowData, rowIndex));
|
|
// cc.push(col.formatter(_728, rowData, rowIndex, col));
|
|
} else {
|
|
cc.push(_728);
|
|
}
|
|
|
|
cc.push("</div>");
|
|
cc.push("</td>");
|
|
}
|
|
}
|
|
return cc.join("");
|
|
},
|
|
|
|
bindEvents: function(target){
|
|
var state = $.data(target, 'datagrid');
|
|
var dc = state.dc;
|
|
var opts = state.options;
|
|
var body = dc.body1.add(dc.body2);
|
|
var clickHandler = ($.data(body[0],'events')||$._data(body[0],'events')).click[0].handler;
|
|
body.unbind('click').bind('click', function(e){
|
|
var tt = $(e.target);
|
|
var tr = tt.closest('tr.datagrid-row');
|
|
if (!tr.length){return}
|
|
if (tt.hasClass('datagrid-row-expander')){
|
|
var rowIndex = 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: function(target){
|
|
var state = $.data(target, 'datagrid');
|
|
var opts = state.options;
|
|
var dc = state.dc;
|
|
var view = this;
|
|
this.renderedCount = 0;
|
|
this.rows = [];
|
|
|
|
dc.body1.add(dc.body2).empty();
|
|
init();
|
|
createHeaderExpander();
|
|
|
|
function init(){
|
|
// erase the onLoadSuccess event, make sure it can't be triggered
|
|
state.onLoadSuccess = opts.onLoadSuccess;
|
|
opts.onLoadSuccess = function(){};
|
|
setTimeout(function(){
|
|
dc.body2.unbind('.datagrid').bind('scroll.datagrid', function(e){
|
|
if (state.onLoadSuccess){
|
|
opts.onLoadSuccess = state.onLoadSuccess; // restore the onLoadSuccess event
|
|
state.onLoadSuccess = undefined;
|
|
}
|
|
if (view.scrollTimer){
|
|
clearTimeout(view.scrollTimer);
|
|
}
|
|
view.scrollTimer = setTimeout(function(){
|
|
scrolling.call(view);
|
|
}, 50);
|
|
});
|
|
dc.body2.triggerHandler('scroll.datagrid');
|
|
}, 0);
|
|
}
|
|
|
|
function scrolling(){
|
|
if (getDataHeight() < dc.body2.height() && view.renderedCount < state.data.total){
|
|
this.getRows.call(this, target, function(rows){
|
|
this.rows = rows;
|
|
this.populate.call(this, target);
|
|
dc.body2.triggerHandler('scroll.datagrid');
|
|
});
|
|
} else if (dc.body2.scrollTop() >= getDataHeight() - dc.body2.height()){
|
|
this.getRows.call(this, target, function(rows){
|
|
this.rows = rows;
|
|
this.populate.call(this, target);
|
|
});
|
|
}
|
|
}
|
|
|
|
function getDataHeight(){
|
|
var h = 0;
|
|
dc.body2.children('table.datagrid-btable').each(function(){
|
|
h += $(this).outerHeight();
|
|
});
|
|
if (!h){
|
|
h = view.renderedCount * 25;
|
|
}
|
|
return h;
|
|
}
|
|
|
|
function createHeaderExpander(){
|
|
if (!opts.detailFormatter){return}
|
|
|
|
var t = $(target);
|
|
var hasExpander = false;
|
|
var fields = t.datagrid('getColumnFields',true).concat(t.datagrid('getColumnFields'));
|
|
for(var i=0; i<fields.length; i++){
|
|
var 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');
|
|
var 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(function(){
|
|
view.bindEvents(target);
|
|
},0);
|
|
}
|
|
},
|
|
|
|
getRows: function(target, callback){
|
|
var state = $.data(target, 'datagrid');
|
|
var opts = state.options;
|
|
var page = Math.floor(this.renderedCount/opts.pageSize) + 1;
|
|
|
|
if (this.renderedCount >= state.data.total){return;}
|
|
if (opts.onBeforeFetch.call(target, page) == false){return}
|
|
|
|
var index = (page-1)*opts.pageSize;
|
|
var rows = state.data.rows.slice(index, index+opts.pageSize);
|
|
if (rows.length){
|
|
opts.onFetch.call(target, page, rows);
|
|
callback.call(this, rows);
|
|
} else {
|
|
var param = $.extend({}, opts.queryParams, {
|
|
page: Math.floor(this.renderedCount/opts.pageSize)+1,
|
|
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');
|
|
var result = opts.loader.call(target, param, function(data){
|
|
$(target).datagrid('loaded');
|
|
var data = opts.loadFilter.call(target, data);
|
|
opts.onFetch.call(target, page, data.rows);
|
|
if (data.rows && data.rows.length){
|
|
state.data.rows = state.data.rows.concat(data.rows);
|
|
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.rows.length){
|
|
opts.onFetch.call(target, page, state.data.rows);
|
|
opts.onLoadSuccess.call(target, state.data);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
populate: function(target){
|
|
var state = $.data(target, 'datagrid');
|
|
var opts = state.options;
|
|
var dc = state.dc;
|
|
if (this.rows.length){
|
|
this.renderedCount += this.rows.length;
|
|
this.render.call(this, target, dc.body2, false);
|
|
this.render.call(this, target, dc.body1, true);
|
|
opts.onLoadSuccess.call(target, {
|
|
total: state.data.total,
|
|
rows: this.rows
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
$.extend($.fn.datagrid.methods, {
|
|
fixDetailRowHeight: function(jq, index){
|
|
return jq.each(function(){
|
|
var opts = $.data(this, 'datagrid').options;
|
|
var dc = $.data(this, 'datagrid').dc;
|
|
var tr1 = opts.finder.getTr(this, index, 'body', 1).next();
|
|
var tr2 = opts.finder.getTr(this, index, 'body', 2).next();
|
|
// fix the detail row height
|
|
if (tr2.is(':visible')){
|
|
tr1.css('height', '');
|
|
tr2.css('height', '');
|
|
var height = Math.max(tr1.height(), tr2.height());
|
|
tr1.css('height', height);
|
|
tr2.css('height', height);
|
|
}
|
|
dc.body2.triggerHandler('scroll');
|
|
});
|
|
},
|
|
getExpander: function(jq, index){ // get row expander object
|
|
var opts = $.data(jq[0], 'datagrid').options;
|
|
return opts.finder.getTr(jq[0], index).find('span.datagrid-row-expander');
|
|
},
|
|
// get row detail container
|
|
getRowDetail: function(jq, index){
|
|
var opts = $.data(jq[0], 'datagrid').options;
|
|
var tr = opts.finder.getTr(jq[0], index, 'body', 2);
|
|
return tr.next().find('div.datagrid-row-detail');
|
|
},
|
|
expandRow: function(jq, index){
|
|
return jq.each(function(){
|
|
var opts = $(this).datagrid('options');
|
|
var dc = $.data(this, 'datagrid').dc;
|
|
var expander = $(this).datagrid('getExpander', index);
|
|
if (expander.hasClass('datagrid-row-expand')){
|
|
expander.removeClass('datagrid-row-expand').addClass('datagrid-row-collapse');
|
|
var tr1 = opts.finder.getTr(this, index, 'body', 1).next();
|
|
var 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];
|
|
opts.onExpandRow.call(this, index, row);
|
|
}
|
|
}
|
|
});
|
|
},
|
|
collapseRow: function(jq, index){
|
|
return jq.each(function(){
|
|
var opts = $(this).datagrid('options');
|
|
var dc = $.data(this, 'datagrid').dc;
|
|
var expander = $(this).datagrid('getExpander', index);
|
|
if (expander.hasClass('datagrid-row-collapse')){
|
|
expander.removeClass('datagrid-row-collapse').addClass('datagrid-row-expand');
|
|
var tr1 = opts.finder.getTr(this, index, 'body', 1).next();
|
|
var tr2 = opts.finder.getTr(this, index, 'body', 2).next();
|
|
tr1.hide();
|
|
tr2.hide();
|
|
dc.body2.triggerHandler('scroll');
|
|
if (opts.onCollapseRow){
|
|
var row = $(this).datagrid('getRows')[index];
|
|
opts.onCollapseRow.call(this, index, row);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|