/**
* yvan.yvgrid.js
* @author luoyifan
* 2019-07-12 10:17:00
*/
'use strict';
(function ($) {
//jqxgrid.edit.js 第136行,tab键跳转
//jqxgrid.js 第1947行,ensurecellvisible 列偏移
if (!jqxGrid) {
console.warn('no jqxGrid!!');
return;
}
$.fn.yvgrid = function (options, param) {
if (typeof options == 'string') {
var method = $.fn.yvgrid.methods[options];
if (method) {
var args = [this];
for (var i = 1; i < arguments.length; i++) {
args.push(arguments[i]);
}
return method.apply(this, args);
} else {
console.error('not found method:' + options);
}
}
options = options || {};
return this.each(function () {
var state = $.data(this, 'yvgrid');
if (state) {
$.extend(state.options, options);
} else {
$.data(this, 'yvgrid', {
options: $.extend({}, $.fn.yvgrid.defaults, options)
});
}
init(this, param);
});
};
function buildDataSource($dom, easyuiOpt, columns, data, jqxOption) {
var dataAdapter, source;
//计算 datafields
var datafields = [];
for (var i = 0; i < columns.length; i++) {
var row = {};
if (columns[i].dataField === '__NO__') {
continue;
}
if (columns[i].dataField === '__CB__') {
continue;
}
if ($.type(columns[i].dataField) === 'string') {
$.extend(row, {
name: columns[i].dataField,
type: 'string'
});
}
if ($.type(columns[i].type) === 'string') {
row.type = columns[i].type;
}
datafields.push(row);
}
if (easyuiOpt.editable && $.type(easyuiOpt.url) === 'string') {
//如果是可编辑表格,不能直接用 dataAdapter 读取(会有bug)
//bug 详情见 https://www.jqwidgets.com/community/topic/grid-resizing-everpresentrow/
console.error('可编辑表格,不能用 url 和 mtype 读取');
$.yvan.alert('可编辑表格,不能用 url 和 mtype 读取');
data = [];
}
//本地直接给数据
if ($.type(data) === 'array') {
source = {
localdata: data,
datatype: "array",
id: easyuiOpt.idField,
//datafields: datafields, //这里不能给定 fields ,给定了就无法动态计算列了
//beforeprocessing: function (root) { //本地数据 不支持分页数
// $dom.jqxGrid('source')._source.totalrecords = root.length;
//}
};
$.fn.yvgrid.filter.sourceFilterOption($dom, easyuiOpt, source, jqxOption);
$.fn.yvgrid.edit.sourceOption($dom, easyuiOpt, source);
dataAdapter = new $.jqx.dataAdapter(source);
} else {
source = {
type: easyuiOpt.mtype,
datatype: "json",
//datafields: datafields, //这里不能给定 fields ,给定了就无法动态计算列了
autoBind: false,
cache: false,
data: easyuiOpt.queryParams,
url: easyuiOpt.url,
id: easyuiOpt.idField,
beforeprocessing: function (root) {
if (root.pagination) {
//$dom.jqxGrid('source')._source.totalrecords = root.pagination.count;
source.totalrecords = parseInt(root.pagination.count);
} else if (root.data) {
//$dom.jqxGrid('source')._source.totalrecords = root.data.length;
source.totalrecords = root.data.length;
} else {
//$dom.jqxGrid('source')._source.totalrecords = 0;
source.totalrecords = 0;
}
}
};
if (easyuiOpt.sortable) {
$.extend(source, {
sort: function () {
$dom.jqxGrid('updatebounddata', 'sort');
},
});
}
$.fn.yvgrid.filter.sourceFilterOption($dom, easyuiOpt, source, jqxOption);
$.fn.yvgrid.edit.sourceOption($dom, easyuiOpt, source);
var adapterOpt = {
//contentType: 'application/json; charset=utf-8',
autoBind: false,
beforeSend: function (xhr, status) {
xhr.setRequestHeader("Authorization", $.cookie('auth'));
$dom.down('yvgridpage').pagination('loading');
},
loadError: function (xhr, status, error) {
console.log(error);
},
downloadComplete: function (root) {
return {
records: root.data
};
}
};
if (easyuiOpt.mtype === 'GET' || easyuiOpt.mtype === 'get') {
adapterOpt.contentType = 'application/json; charset=utf-8';
}
dataAdapter = new $.jqx.dataAdapter(source, adapterOpt);
}
return dataAdapter;
}
function buildColumns($dom, option) {
/*===== Columns ======*/
var columns = option.columns;
if ($.type(columns) === 'array' && $.type(columns[0]) === 'array') {
//easyui 的设置方法
columns = columns[0];
var columnsNew = [];
for (var i = 0; i < columns.length; i++) {
if (columns[i].hidden === true) {
continue;
}
var vv = columns[i];
var ret = {
dataField: vv.field,
text: vv.title,
type: vv.type || 'string'
};
if (vv.type === 'number') {
$.extend(ret, { cellsalign: 'right', cellsformat: 'd' });
}
if ($.type(vv.minwidth) !== 'undefined') {
ret.minwidth = vv.minwidth;
}
if ($.type(vv.sortable) === 'boolean') {
ret.sortable = vv.sortable;
}
if ($.type(vv.width) !== 'undefined') {
ret.width = vv.width;
} else {
if (option.autoSizeColumns) {
ret.width = 80;
}
}
if (vv.align) {
ret.cellsalign = vv.align;
} else {
ret.cellsalign = 'left';
}
if ((vv.editor && vv.editor.xtype === 'checkbox') || vv.type === 'bool') {
var onOff = { on: vv.on, off: vv.off };
if (vv.editor && vv.editor.xtype === 'checkbox' && $.type(vv.editor.on) === 'string' && $.type(vv.editor.off) === 'string') {
onOff.on = vv.editor.on;
onOff.off = vv.editor.off;
}
ret.cellsrenderer = (function (onOffValue) {
return function (row, columnfield, value, defaulthtml, columnproperties) {
if ($.trim(value) === onOffValue.on) {
return '
';
}
if ($.trim(value) === onOffValue.off) {
return '';
}
return '' + value + '
';
};
})(onOff);
}
if ($.type(vv.formatter) === 'function') {
ret.cellsrenderer = (function (formatter) {
return function (row, columnfield, value, defaulthtml, columnproperties, rowdata) {
value = formatter.call(this, value, rowdata);
if (!columnproperties) {
columnproperties = { cellsalign: 'left' };
}
return '' + value + '
';
};
})(vv.formatter);
} else if ($.type(vv.formatter) === 'array') {
ret.cellsrenderer = (function (formatter) {
return function (row, columnfield, value, defaulthtml, columnproperties) {
for (var i = 0; i < formatter.length; i++) {
if (formatter[i]['id'] === $.trim(value)) {
value = formatter[i]['text'];
break;
}
}
if (!columnproperties) {
columnproperties = { cellsalign: 'left' };
}
return '' + value + '
';
};
})(vv.formatter);
}
if (vv.titleAlign === 'left') {
ret.renderer = function (value) {
return '' + value + '
';
}
} else if (vv.titleAlign === 'right') {
ret.renderer = function (value) {
return '' + value + '
';
}
} else {
ret.renderer = function (value) {
return '' + value + '
';
}
}
$.fn.yvgrid.edit.columnOption(vv, ret);
$.fn.yvgrid.filter.columnFilterOption($dom, option, vv, ret);
columnsNew.push(ret);
}
columns = columnsNew;
}
if (option.checkbox) {
columns = [{
pinned: true,
exportable: false,
text: "",
width: 60,
columntype: 'bool',
resizable: false,
sortable: false,
filterable: false,
dataField: '__CB__',
editable: true,
cellsAlign: 'right',
align: 'right',
cellsrenderer: function (row, column, value) {
if (value) {
return '';
}
return '';
},
}].concat(columns);
}
if (option.rownumbers) {
columns = [{
pinned: true,
exportable: false,
text: "",
columntype: 'number',
resizable: false,
sortable: false,
filterable: false,
dataField: '__NO__',
editable: false,
cellsAlign: 'right',
align: 'right',
cellsrenderer: function (row, column, value) {
return '' + (value + 1) + '
';
},
createEverPresentRowWidget: function (datafield, htmlElement, popup, addCallback) {
var editor = $("*
").appendTo(htmlElement);
return editor;
},
initEverPresentRowWidget: function (datafield, htmlElement) {
},
getEverPresentRowWidgetValue: function (datafield, htmlElement, validate) {
},
resetEverPresentRowWidgetValue: function (datafield, htmlElement) {
}
}].concat(columns);
}
return columns;
}
function addRow($dom, row) {
return $dom.each(function () {
var target = this;
var $dom = $(target);
$dom.jqxGrid('addrow', null, row);
//$dom.jqxGrid('selectrow', 0);
//$dom.jqxGrid('beginrowedit', 0);
});
}
$.fn.yvgrid.methods = {
/**
* 添加数据行
*/
addRow: addRow,
appendRow: addRow,
/**
* 获取全部数据行
*/
getData: function ($dom) {
return $dom.jqxGrid('getrows');
},
/**
* 获取所有被勾选的数据
*/
getChecked: function ($dom) {
return $dom.jqxGrid('getrows').filter(function (item) {
return (item.__CB__);
});
},
/**
* 设置勾选的行(可以是ID数组,可以是ID)
*/
setChecked: function ($dom, ids) {
if ($.type(ids) === 'array') {
ids.forEach(function (id) {
$.fn.yvgrid.selection.setCheckboxById($dom, id, true);
});
}
$.fn.yvgrid.selection.setCheckboxById($dom, ids, true);
},
/**
* 清空所有被勾选的数据
*/
checkedClear: function ($dom) {
var rows = $dom.jqxGrid('getrows');
rows.forEach(function (r) {
$.fn.yvgrid.selection.setCheckbox($dom, r.boundindex, false);
});
},
/**
* 勾选所有行
*/
checkedAll: function ($dom) {
var rows = $dom.jqxGrid('getrows');
rows.forEach(function (r) {
$.fn.yvgrid.selection.setCheckbox($dom, r.boundindex, true);
});
},
/**
* 清空表格
*/
clear: function ($dom) {
$dom.jqxGrid('clear');
},
/**
* 获取全部数据行
*/
getRowData: function ($dom) {
return $dom.jqxGrid('getrows');
},
/**
* 刷新数据
*/
refresh: function (jq) {
return jq.each(function () {
$(this).jqxGrid('refresh');
});
},
/**
* 获取当前已被选的行的 rowid
*/
rowIndex: function ($dom) {
return $dom.jqxGrid('getselectedrowindex');
},
/**
* 获取当前行的 boundIndex
*/
rowBoundIndex: function ($dom) {
var rowIndex = $dom.jqxGrid('getselectedrowindex');
if ($.type(rowIndex) === 'undefined' || rowIndex < 0) {
return;
}
var rowid = $dom.jqxGrid('getrowid', rowIndex);
return $dom.jqxGrid('getrowboundindexbyid', rowid);
},
/**
* 在某个单元格上显示校验错误
*/
showError: function ($dom, rowBoundIndex, column, msg) {
if ($.type(rowBoundIndex) === 'undefined' || rowBoundIndex < 0) {
console.error('showError not assign rowBoundIndex');
return;
}
$dom.jqxGrid('showvalidationpopup', rowBoundIndex, column, msg);
},
/**
* 更改数据源, 或重新从后台拉取数据
*/
reload: function (jq, option) {
var hasChangeParamters = ($.type(option) === 'object');
if (!hasChangeParamters) {
return jq.jqxGrid('updatebounddata');
}
return jq.each(function () {
var target = this;
var state = $.data(target, 'yvgrid');
var $dom = $(target);
option = $.extend(state.options, option);
var columns = buildColumns($dom, option);
var jqxOption = {};
var dataAdapter = buildDataSource($dom, option, columns, option.data, jqxOption);
$.extend(jqxOption, {
source: dataAdapter
});
//console.log('build source queryParams:', option.queryParams);
$dom.jqxGrid(jqxOption);
delete option.data;
//如果之前的页码大于0,就跳到第0页
var paginginformation = $dom.jqxGrid('getpaginginformation');
if (paginginformation.pagenum > 0) {
$dom.jqxGrid('gotopage', 0);
}
});
},
showLoading: function ($dom) {
$dom.jqxGrid('showloadelement');
},
hideLoading: function ($dom) {
$dom.jqxGrid('hideloadelement');
}
};
function init(target, context) {
var state = $.data(target, 'yvgrid');
var easyuiOpt = state.options;
var $dom = $(target);
state.editCount = 0;
var columns = buildColumns($dom, easyuiOpt);
/*===== 复制新的 option ======*/
var jqxOption = {
height: easyuiOpt.height,
width: easyuiOpt.width,
sorttogglestates: 0, //Disable column header click sort
keyboardnavigation: false,
columnsautoresize: false,
enabletooltips: true,
enablebrowserselection: true,
altrows: true,
clipboard: true,
columnsresize: true,
columns: columns,
virtualmode: true, //virtualmode/rendergridrows 不能挪动, 如果挪走可能会造成发多次 AJAX
rendergridrows: function (obj) {
var source = $dom.jqxGrid('source');
var localdata = source._source.localdata;
if (!localdata) {
return obj.data;
} else {
return localdata.slice(obj.startindex, obj.endindex);
}
},
rendered: function () {
//console.log('rendered', this, arguments);
},
handlekeyboardnavigation: function (event) {
var ret;
ret = $.fn.yvgrid.selection.handlekeyboardnavigation.call(this, event);
if (ret === true) {
return ret;
}
ret = $.fn.yvgrid.edit.handlekeyboardnavigation.call(this, event);
if (ret === true) {
return ret;
}
if ($.type(easyuiOpt.onKeyDown) === 'function') {
ret = easyuiOpt.onKeyDown.call(this.element, event);
if (ret === true) {
return ret;
}
}
}
};
/*===== 编辑状态 ======*/
$.fn.yvgrid.edit.gridOption($dom, easyuiOpt, jqxOption);
/*===== 数据源 ======*/
var dataAdapter = buildDataSource($dom, easyuiOpt, columns, easyuiOpt.data, jqxOption);
$.extend(jqxOption, {
source: dataAdapter
});
delete easyuiOpt.data;
/*===== 排序 ======*/
jqxOption.sortable = easyuiOpt.sortable;
/*===== 分页 ======*/
if (easyuiOpt.pagination === false) {
$.extend(jqxOption, {
pageable: false,
});
} else {
$dom.on('bindingcomplete', function () {
$(this).down('yvgridpage').pagination('loaded');
});
$.extend(jqxOption, {
pageable: true,
pagesize: easyuiOpt.pageSize,
pagesizeoptions: easyuiOpt.pageList,
pagerrenderer: function () {
var $grid = $(this.element);
var datainfo = $grid.jqxGrid('getdatainformation');
var paginginfo = datainfo.paginginformation;
var $dom = $('');
$dom.pagination({
pageNumber: paginginfo.pagenum + 1,
total: datainfo.rowscount,
pageSize: paginginfo.pagesize,
pageList: jqxOption.pagesizeoptions,
onSelectPage: function (pageNumber, pageSize) {
if ($(this).pagination("options").loading) {
$.yvan.msg('请不要操作过快');
$(this).pagination('refresh', {
pageNumber: paginginfo.pagenum + 1,
total: datainfo.rowscount,
pageSize: paginginfo.pagesize
});
return;
}
$grid.jqxGrid('gotopage', pageNumber - 1);
},
onRefresh: function () {
$grid.jqxGrid('gotopage', paginginfo.pagenum);
},
onChangePageSize: function (pageSize) {
if ($(this).pagination("options").loading) {
$.yvan.msg('请不要操作过快');
$(this).pagination('refresh', {
pageNumber: paginginfo.pagenum + 1,
total: datainfo.rowscount,
pageSize: paginginfo.pagesize
});
return;
}
$grid.jqxGrid({ pagesize: pageSize });
}
});
return $dom;
},
});
}
/*====== 工具栏 ======*/
if (easyuiOpt.hasOwnProperty('toolbar')) {
var toolbar = easyuiOpt.toolbar;
$.extend(jqxOption, {
showtoolbar: true,
rendertoolbar: function ($dom) {
if ($.type(toolbar) === 'array') {
$dom.power('renderEach', {
$target: $dom,
items: toolbar,
context: context
});
} else if ($.type(toolbar) === 'object') {
$dom.power('renderDispatch', {
$target: $dom,
item: toolbar,
context: context
});
}
},
});
if (toolbar.hasOwnProperty('height')) {
jqxOption.toolbarheight = toolbar.height || 38;
}
}
/*====== 选择模式 ======*/
$.fn.yvgrid.selection.gridOption($dom, easyuiOpt, jqxOption);
/*====== 过滤行 ======*/
$.fn.yvgrid.filter.gridOption($dom, easyuiOpt, jqxOption);
$dom.find('.jqx-grid-selectionarea').next('span').remove();
//execute DOM
$dom.jqxGrid(jqxOption);
$dom.on("columnclick", function (event) {
$(this).jqxGrid('autoresizecolumn', event.args.datafield, 'all');
});
$dom.on('rowdoubleclick', function (event) {
if ($.type(easyuiOpt.onDblClickRow) === 'function') {
easyuiOpt.onDblClickRow.call(this, event.args.rowindex, event);
}
});
//$dom.on("cellbeginedit", function (event) {
// $.fn.yvgrid.edit.cellbeginedit($dom, event);
//});
//$dom.on("cellendedit", function (event) {
// $.fn.yvgrid.edit.cellendedit($dom, event);
//});
//$dom.on("columnresized", function (event) {
// $.fn.yvgrid.edit.columnresized($dom, event);
//});
if (!easyuiOpt.border) {
$dom.css({
"border-style": 'none'
});
}
return $dom;
}
$.fn.power.defaults.xtype.yvgrid = function ($targetDOM, option, context) {
var id = $.yvan.createId('yvgrid');
var $dom = $('');
$targetDOM.append($dom);
return $dom.yvgrid(option, context);
};
$.fn.yvgrid.defaults = {
rownumbers: true,
checkbox: false,
width: '100%',
height: '100%',
pageSize: 20,
autoSizeColumns: true,
pageList: [20, 50, 100, 200, 500, 1000],
sortable: false,
filter: false,
pagination: true,
border: false,
editOnSelected: false,
editable: false
};
})(jQuery);