Requirements & Scenarios
Example table query is the most used and basic function in business system, but it is also the most common adjustment. Different users have different requirements for data. So after the system is formally used, as a development, they would like to sit on the business side and adjust according to their requirements. The location and width of columns need to be adjusted at most. It's very troublesome, and it's constantly changing. The best way to do this is to give the user the ability to adjust it and save it locally so that they don't have to adjust it every time.
Implementation Method
Because the projects on my side are all developed with easyui datagrid, which provides manual adjustment and dragging function for the width and location of each column, but does not provide the function of saving the modified attributes. Here we need to extend the datagrid, expand a new saving function, save the modified attributes to the browser's local storage, and add a new initial one. Read the attributes of localstorage to adjust when initialization, and you can achieve the desired functionality.
demo website http://221.224.21.30:2020/Orders/Index
code implementation
easyui datagrid drag adjustment column location function official has extended support https://www.jeasyui.com/extension/columns_ext.php The download address is available.
Now you also need to customize the functions for saving and loading extensions (columns-reset.js)
(function ($) {
function buildMenu(target) {
const state = $(target).data('datagrid');
//Freezing columns do not allow modification of attributes and locations
//const fields = $(target).datagrid('getColumnFields',true).concat($(target).datagrid('getColumnFields', false));
const fields = $(target).datagrid('getColumnFields');
if (!state.columnMenu) {
state.columnMenu = $('<div></div>').appendTo('body');
state.columnMenu.menu({
onClick: function (item) {
if (item.iconCls === 'tree-checkbox1') {
$(target).datagrid('hideColumn', item.name);
$(this).menu('setIcon', {
target: item.target,
iconCls: 'tree-checkbox0'
});
} else if (item.iconCls === 'tree-checkbox0') {
$(target).datagrid('showColumn', item.name);
$(this).menu('setIcon', {
target: item.target,
iconCls: 'tree-checkbox1'
});
} else if (item.iconCls === 'icon-save') {
//Save configuration
}
let opts = [];
for (let i = 0; i < fields.length; i++) {
const field = fields[i];
const col = $(target).datagrid('getColumnOption', field);
opts.push(col);
}
//Save the adjusted attributes to localstorage in
localStorage.setItem($(target).datagrid('options').id, JSON.stringify(opts));
}
});
state.columnMenu.menu('appendItem', {
text: 'Save configuration',
name: 'saveconfigitem',
iconCls: 'icon-save'
});
for (let i = 0; i < fields.length; i++) {
const field = fields[i];
const col = $(target).datagrid('getColumnOption', field);
if (col.title !== undefined)
state.columnMenu.menu('appendItem', {
text: col.title,
name: field,
iconCls: !col.hidden ? 'tree-checkbox1' : 'tree-checkbox0'
});
}
}
return state.columnMenu;
}
$.extend($.fn.datagrid.methods, {
columnMenu: function (jq) {
return buildMenu(jq[0]);
},
resetColumns: function (jq) {
return jq.each(function () {
const opts = $(this).datagrid('options');
const local = JSON.parse(localStorage.getItem(opts.id));
//Frozen columns do not participate in settings
//const fields = $(this).datagrid('getColumnFields', true).concat($(this).datagrid('getColumnFields', false));
//const fields = $(this).datagrid('getColumnFields');
if (local !== null) {
//load sort datagrid columns
let sortcolumns = [];
for (let i = 0; i < local.length; i++) {
const field = local[i].field;
const localboxwidth = local[i].boxWidth;
const localwidth = local[i].width;
const localhidden = local[i].hidden || false;
let col = $(this).datagrid('getColumnOption', field);
//Modify column widths and hidden attributes
col.boxWidth = localboxwidth;
col.width = localwidth;
col.hidden = localhidden;
sortcolumns.push(col);
}
$(this).datagrid({
columns: [sortcolumns]
}).datagrid('columnMoving');
}
});
}
});
})(jQuery);
columns-reset.js
//Initialization Definition datagrid
var $dg = $('#orders_datagrid');
$(() => {
//Definition datagrid structure
$dg.datagrid({
rownumbers: true,
checkOnSelect: false,
selectOnCheck: true,
idField: 'Id',
sortName: 'Id',
sortOrder: 'desc',
remoteFilter: true,
singleSelect: false,
url: '/Orders/GetDataAsync',
method: 'get',
onClickCell: onClickCell,
pagination: true,
striped: true,
onHeaderContextMenu: function (e, field) {
e.preventDefault();
$(this).datagrid('columnMenu').menu('show', {
left: e.pageX,
top: e.pageY
});
},
onBeforeLoad: function () {
//datagrid resize when jarvisWidgets resized.
const that = $(this);
$(window).on("resize.jarvisWidgets", () => {
that.datagrid('resize');
})
},
onLoadSuccess: function (data) {
editIndex = undefined;
},
onCheck: function () {
$("button[name*='deletebutton']").prop("disabled", false);
},
onUncheck: function () {
},
onSelect: function (index, row) {
order = row;
},
onBeginEdit: function (index, row) {
//const editors = $(this).datagrid('getEditors', index);
},
onEndEdit: function (index, row) {
editIndex = undefined;
},
onBeforeEdit: function (index, row) {
editIndex = index;
row.editing = true;
$("button[name*='deletebutton']").prop("disabled", false);
$("button[name*='cancelbutton']").prop("disabled", false);
$("button[name*='savebutton']").prop("disabled", false);
$(this).datagrid('refreshRow', index);
},
onAfterEdit: function (index, row) {
row.editing = false;
$(this).datagrid('refreshRow', index);
},
onCancelEdit: function (index, row) {
row.editing = false;
editIndex = undefined;
$("button[name*='deletebutton']").prop("disabled", false);
$("button[name*='savebutton']").prop("disabled", true);
$("button[name*='cancelbutton']").prop("disabled", true);
$(this).datagrid('refreshRow', index);
},
frozenColumns: [[
/*Open CheckBox Selection*/
{ field: 'ck', checkbox: true },
{
field: 'action',
title: '@Html.L("Command")',
width: 85,
sortable: false,
resizable: true,
formatter: function showdetailsformatter(value, row, index) {
if (!row.editing) {
return `<div class="btn-group">\
<button onclick="showdetailswindow('${row.Id}', ${index})" class="btn btn-default btn-xs" title="Check the details" ><i class="fa fa-pencil-square-o"></i> </button>\
<button onclick="deleteRow('${row.Id}',${index})" class="btn btn-default btn-xs" title="Delete records" ><i class="fa fa-trash-o"></i> </button>\
</div>`;
} else {
return `<button class="btn btn-default btn-xs" disabled title="Check the details" ><i class="fa fa-pencil-square-o"></i> </button>`;
}
}
}
]],
columns: [[
{ /*Id*/
field: 'Id',
title: '<span class="required">@Html.DisplayNameFor(model => model.Id)</span>',
width: 120,
sortable: true,
resizable: true,
hidden: true
},
{ /*Order number*/
field: 'OrderNo',
title: '<span class="required">@Html.DisplayNameFor(model => model.OrderNo)</span>',
width: 130,
hidden: false,
editor: {
type: 'textbox',
options: { prompt: '@Html.DisplayNameFor(model => model.OrderNo)', required: true, validType: 'length[12,12]' }
},
sortable: true,
resizable: true
},
{ /*Customers to whom the order belongs*/
field: 'Customer',
title: '<span class="required">@Html.DisplayNameFor(model => model.Customer)</span>',
width: 130,
hidden: false,
editor: {
type: 'textbox',
options: { prompt: '@Html.DisplayNameFor(model => model.Customer)', required: true, validType: 'length[0,30]' }
},
sortable: true,
resizable: true
},
{ /*Shipping Address*/
field: 'ShippingAddress',
title: '<span class="required">@Html.DisplayNameFor(model => model.ShippingAddress)</span>',
width: 300,
hidden: false,
editor: {
type: 'textbox',
options: { prompt: '@Html.DisplayNameFor(model => model.ShippingAddress)', required: true, validType: 'length[0,200]' }
},
sortable: true,
resizable: true
},
{ /*Remarks*/
field: 'Remark',
title: '@Html.DisplayNameFor(model => model.Remark)',
width: 260,
hidden: false,
editor: {
type: 'textbox',
options: { prompt: '@Html.DisplayNameFor(model => model.Remark)', required: false, validType: 'length[0,100]' }
},
sortable: true,
resizable: true
},
{ /*Order Date Default Day*/
field: 'OrderDate',
title: '<span class="required">@Html.DisplayNameFor(model => model.OrderDate)</span>',
width: 120,
align: 'right',
hidden: false,
editor: {
type: 'datebox',
options: { prompt: '@Html.DisplayNameFor(model => model.OrderDate)', required: true }
},
formatter: dateformatter,
sortable: true,
resizable: true
},
]]
}).datagrid('columnMoving')
.datagrid('resetColumns');
<script src="~/Scripts/easyui/plugins/columns-reset.js"></script>