/** * 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);