保持行顺序和行宽,free-jqGrid
Persisting Row order and row width, free-jqGrid
您好,我一直在尝试将每个用户的列顺序和宽度保存到数据库中。我实现了它可以正确保存和加载数据。但是,网格不会更改以反映 colModel。我关注了这个 awnser 一切似乎都正常工作,网格根本不反映更改的 colModel。我没有收到任何错误,并且数据已正确保存和提取,因此我们将不胜感激任何帮助或建议。谢谢。
经过进一步调查,我更改了代码以使用本地存储而不是 ajax 调用,这有效。所以问题是让页面等待响应。
我在下面包含了我的代码。首先是参考答案 .
中提供的功能
var $grid = $("#ProjectTable"),
cm = [
{name: 'FieldProjectId', width: 10, align: 'center', key: true, search: false, hidden: true},
{name: 'Edit', width: 30, search: false, sortable: false, align: 'center'},
{name: 'Name', width: 100, index: 'Name', editable: true},
{name: 'Code', width: 50, index: 'Code', editable: true},
{name: 'Manager', width: 100, index: 'Manager', editable: true},
{name: 'StartDate', width: 65, index: 'StartDate', search: true, formatter : 'date', formatoptions: { srcformat: 'm/d/Y', newformat: 'd/m/Y'}, editable: true,editoptions : { dataInit: function (elem) { $(elem).datepicker({
changeMonth: true,
changeYear: true,
showWeek: true,
onSelect : function () { $('#ProjectTable')[0].triggerToolbar(); }
}).keyup(function(e) {
if (e.keyCode == 8 || e.keyCode == 46) {
$.datepicker._clearDate(this);
}
});
}}, searchoptions: { dataInit: function (elem) { $(elem).datepicker({
changeMonth: true,
changeYear: true,
showWeek: true,
onSelect : function () { $('#ProjectTable')[0].triggerToolbar(); }
}).keyup(function(e) {
if (e.keyCode == 8 || e.keyCode == 46) {
$.datepicker._clearDate(this);
}
});
} }},
{name: 'CompletedDate', width: 65, index: 'CompletedDate', formatter : 'date', formatoptions: { srcformat: 'm/d/Y', newformat: 'd/m/Y'}, editable: true, editoptions : { dataInit: function (elem) { $(elem).datepicker({
changeMonth: true,
changeYear: true,
showWeek: true,
onSelect : function () { $('#ProjectTable')[0].triggerToolbar(); }
}).keyup(function(e) {
if (e.keyCode == 8 || e.keyCode == 46) {
$.datepicker._clearDate(this);
}
});
}}, sorttype:'date' , searchoptions: { dataInit: function (elem) { $(elem).datepicker({
changeMonth: true,
changeYear: true,
showWeek: true,
onSelect : function () { $('#ProjectTable')[0].triggerToolbar(); }
}).keyup(function(e) {
if (e.keyCode == 8 || e.keyCode == 46) {
$.datepicker._clearDate(this);
}
});
}}},
{name: 'Remark', width: 200, index: 'Remark', search: false, editable: true},
{name: 'Status', width: 95, index: 'Status', editable: true },
{name: 'Delete', width: 20, search: false, sortable: false, align: 'center'}
],
saveObjectInLocalStorage = function (storageItemName, object) {
$.ajax({
url: '<%= Url.Action("SaveColumnStatePreference", "SampleSelection") %>',
dataType: 'json',
type: 'POST',
data: {
grid: storageItemName,
columnsState: JSON.stringify(object)
},
success:function(data) {
},
error:function(XMLHttpRequest, textStatus, errorThrown){
console.log("Failed to save column state");
}
});
},
getObjectFromLocalStorage = function (storageItemName) {
$.ajax({
url: '<%= Url.Action("GetColumnStatePreference", "SampleSelection") %>',
dataType: 'json',
type: 'POST',
data: {
grid: storageItemName
},
success:function(data) {
if(data !== undefined)
{
alert(data.colState);
return $.parseJSON(data.colState);
}
},
error:function(XMLHttpRequest, textStatus, errorThrown){
console.log("Failed to recover column state");
}
});
},
myColumnStateName = function (grid) {
return window.location.pathname + "#" + grid[0].id;
},
idsOfSelectedRows = [],
getColumnNamesFromColModel = function () {
var colModel = this.jqGrid("getGridParam", "colModel");
return $.map(colModel, function (cm, iCol) {
// we remove "rn", "cb", "subgrid" columns to hold the column information
// independent from other jqGrid parameters
return $.inArray(cm.name, ["rn", "cb", "subgrid"]) >= 0 ? null : cm.name;
});
},
saveColumnState = function () {
var p = this.jqGrid("getGridParam"), colModel = p.colModel, i, l = colModel.length, colItem, cmName,
postData = p.postData,
columnsState = {
search: p.search,
page: p.page,
rowNum: p.rowNum,
sortname: p.sortname,
sortorder: p.sortorder,
cmOrder: getColumnNamesFromColModel.call(this),
selectedRows: idsOfSelectedRows,
colStates: {}
},
colStates = columnsState.colStates;
if (postData.filters !== undefined) {
columnsState.filters = postData.filters;
}
for (i = 0; i < l; i++) {
colItem = colModel[i];
cmName = colItem.name;
if (cmName !== "rn" && cmName !== "cb" && cmName !== "subgrid") {
colStates[cmName] = {
width: colItem.width,
hidden: colItem.hidden
};
}
}
saveObjectInLocalStorage(myColumnStateName(this), columnsState);
},
myColumnsState,
isColState,
restoreColumnState = function (colModel) {
var colItem, i, l = colModel.length, colStates, cmName,
columnsState = getObjectFromLocalStorage(myColumnStateName(this));
if (columnsState) {
colStates = columnsState.colStates;
for (i = 0; i < l; i++) {
colItem = colModel[i];
cmName = colItem.name;
if (cmName !== "rn" && cmName !== "cb" && cmName !== "subgrid") {
colModel[i] = $.extend(true, {}, colModel[i], colStates[cmName]);
}
}
}
return columnsState;
},
updateIdsOfSelectedRows = function (id, isSelected) {
var index = $.inArray(id, idsOfSelectedRows);
if (!isSelected && index >= 0) {
idsOfSelectedRows.splice(index, 1); // remove id from the list
} else if (index < 0) {
idsOfSelectedRows.push(id);
}
},
firstLoad = true;
myColumnsState = restoreColumnState.call($grid, cm);
isColState = myColumnsState !== undefined && myColumnsState !== null;
idsOfSelectedRows = isColState && myColumnsState.selectedRows !== undefined ? myColumnsState.selectedRows : [];
其次是 jqGrid 本身的代码。
$('#ProjectTable').jqGrid({
datatype: 'json',
url: '<%= Url.Action("projectGridData", "SampleSelection") %>',
mType: 'POST',
colNames: [
htmlDecode("<%=Atmis.EncodedLabel("Sample.Project.ProjectId", "ID") %>"),
"",
htmlDecode("<%=Atmis.EncodedLabel("Sample.Project.Name", "Name") %>"),
htmlDecode("<%=Atmis.EncodedLabel("Sample.Project.Code", "Code") %>"),
htmlDecode("<%=Atmis.EncodedLabel("Sample.Project.Manager", "Manager") %>"),
htmlDecode("<%=Atmis.EncodedLabel("Sample.Project.StartDate", "Start Date") %>"),
htmlDecode("<%=Atmis.EncodedLabel("Sample.Project.CompletionDate", "CompletionDate") %>"),
htmlDecode("<%=Atmis.EncodedLabel("Sample.Project.Remark", "Remark") %>"),
htmlDecode("<%=Atmis.EncodedLabel("Sample.Project.Status", "Status") %>"),
""
],
colModel: cm,
caption: htmlDecode("<%=Atmis.EncodedLabel("Sample.Project.Caption", "Project") %>"),
width: $('#tabs-projects').width() - 20,
sortname: 'FieldProjectId',
loadui: 'block',
rowNum: 20,
rowList: [10,25,50,100,200],
sortorder : 'desc',
headertitles:true,
ajaxGridOptions : {
beforeSend: function(xhr) {
$('#ProjectTable').closest('.ui-jqgrid').block({
centerX: false,
centerY: false,
message: $('#ProjectLoading'),
css: {
position: 'absolute',
padding: 0,
margin: 0,
width: 'auto',
top: '40%',
left: '45%',
textAlign: 'center',
cursor: 'wait'
},
overlayCSS: {
backgroundColor: '#524f4f',
opacity: 0.6,
cursor: 'wait'
}
});
},
complete: function(xhr) {
$('#ProjectTable').closest('.ui-jqgrid').unblock();
},
error: function(jqXHR, textStatus, errorThrown) {
$('#ProjectTable').closest('.ui-jqgrid').unblock();
}
},
resizeStop: function(width, index) {
saveColumnState.call($grid, $grid[0].p.remapColumns);
},
sortable: {
update: function(relativeColumnOrder){
saveColumnState.call($grid);
}
},
height: 'auto',
viewrecords: true,
toolbar: [true, "top"],
pager: $('#ProjectPager'),
postData: {
withLinks: true,
clientId: function() {
return $('#ClientId').val();
}
},
editData: {
clientId: function() {
return $('#ClientId').val();
}
},
beforeRequest: function () {
},
onclickSubmit: function (options, postData) {
return {
ClientId: $('#ClientId').val()
};
},
gridComplete: function () {
},
jsonReader:{
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
userdata: "userdata"
},
onSelectRow: function (id) {
// get data from the column 'userCode'
var selRowId = $(this).jqGrid('getGridParam', 'selrow');
var userCode = $(this).jqGrid('getCell', selRowId, 'FieldProjectId');
SelectedProjectID = userCode;
$('#tabs').tabs('enable', 1);
$('#tabs').tabs('enable', 3);
},
loadComplete: function (data){
var $this = $(this), p = $this.jqGrid("getGridParam"), i, count;
if (firstLoad) {
firstLoad = false;
if (isColState && myColumnsState.cmOrder != null && myColumnsState.cmOrder.length > 0) {
// We compares the values from myColumnsState.cmOrder array
// with the current names of colModel and remove wrong names. It could be
// required if the column model are changed and the values from the saved stated
// not corresponds to the
var fixedOrder = $.map(myColumnsState.cmOrder, function (name) {
return p.iColByName[name] === undefined ? null : name;
});
$this.jqGrid("remapColumnsByName", fixedOrder, true);
}
}
saveColumnState.call($this, this.p.remapColumns);
}
}
).filterToolbar();
很难在没有调试的情况下回答长代码的问题。尽管如此,我认为您的问题出在 restoreColumnState
的使用上,您在代码中以 同步方式 : myColumnsState = restoreColumnState.call($grid, cm);
调用它,但它调用 getObjectFromLocalStorage
异步工作。 jquery.ajax
的 success
回调返回的数据 return $.parseJSON(data.colState);
将被忽略。为了适应代码,您可以重写代码以使用 在 success
回调 .
中使用的状态创建整个网格
您好,我一直在尝试将每个用户的列顺序和宽度保存到数据库中。我实现了它可以正确保存和加载数据。但是,网格不会更改以反映 colModel。我关注了这个 awnser
经过进一步调查,我更改了代码以使用本地存储而不是 ajax 调用,这有效。所以问题是让页面等待响应。
我在下面包含了我的代码。首先是参考答案
var $grid = $("#ProjectTable"),
cm = [
{name: 'FieldProjectId', width: 10, align: 'center', key: true, search: false, hidden: true},
{name: 'Edit', width: 30, search: false, sortable: false, align: 'center'},
{name: 'Name', width: 100, index: 'Name', editable: true},
{name: 'Code', width: 50, index: 'Code', editable: true},
{name: 'Manager', width: 100, index: 'Manager', editable: true},
{name: 'StartDate', width: 65, index: 'StartDate', search: true, formatter : 'date', formatoptions: { srcformat: 'm/d/Y', newformat: 'd/m/Y'}, editable: true,editoptions : { dataInit: function (elem) { $(elem).datepicker({
changeMonth: true,
changeYear: true,
showWeek: true,
onSelect : function () { $('#ProjectTable')[0].triggerToolbar(); }
}).keyup(function(e) {
if (e.keyCode == 8 || e.keyCode == 46) {
$.datepicker._clearDate(this);
}
});
}}, searchoptions: { dataInit: function (elem) { $(elem).datepicker({
changeMonth: true,
changeYear: true,
showWeek: true,
onSelect : function () { $('#ProjectTable')[0].triggerToolbar(); }
}).keyup(function(e) {
if (e.keyCode == 8 || e.keyCode == 46) {
$.datepicker._clearDate(this);
}
});
} }},
{name: 'CompletedDate', width: 65, index: 'CompletedDate', formatter : 'date', formatoptions: { srcformat: 'm/d/Y', newformat: 'd/m/Y'}, editable: true, editoptions : { dataInit: function (elem) { $(elem).datepicker({
changeMonth: true,
changeYear: true,
showWeek: true,
onSelect : function () { $('#ProjectTable')[0].triggerToolbar(); }
}).keyup(function(e) {
if (e.keyCode == 8 || e.keyCode == 46) {
$.datepicker._clearDate(this);
}
});
}}, sorttype:'date' , searchoptions: { dataInit: function (elem) { $(elem).datepicker({
changeMonth: true,
changeYear: true,
showWeek: true,
onSelect : function () { $('#ProjectTable')[0].triggerToolbar(); }
}).keyup(function(e) {
if (e.keyCode == 8 || e.keyCode == 46) {
$.datepicker._clearDate(this);
}
});
}}},
{name: 'Remark', width: 200, index: 'Remark', search: false, editable: true},
{name: 'Status', width: 95, index: 'Status', editable: true },
{name: 'Delete', width: 20, search: false, sortable: false, align: 'center'}
],
saveObjectInLocalStorage = function (storageItemName, object) {
$.ajax({
url: '<%= Url.Action("SaveColumnStatePreference", "SampleSelection") %>',
dataType: 'json',
type: 'POST',
data: {
grid: storageItemName,
columnsState: JSON.stringify(object)
},
success:function(data) {
},
error:function(XMLHttpRequest, textStatus, errorThrown){
console.log("Failed to save column state");
}
});
},
getObjectFromLocalStorage = function (storageItemName) {
$.ajax({
url: '<%= Url.Action("GetColumnStatePreference", "SampleSelection") %>',
dataType: 'json',
type: 'POST',
data: {
grid: storageItemName
},
success:function(data) {
if(data !== undefined)
{
alert(data.colState);
return $.parseJSON(data.colState);
}
},
error:function(XMLHttpRequest, textStatus, errorThrown){
console.log("Failed to recover column state");
}
});
},
myColumnStateName = function (grid) {
return window.location.pathname + "#" + grid[0].id;
},
idsOfSelectedRows = [],
getColumnNamesFromColModel = function () {
var colModel = this.jqGrid("getGridParam", "colModel");
return $.map(colModel, function (cm, iCol) {
// we remove "rn", "cb", "subgrid" columns to hold the column information
// independent from other jqGrid parameters
return $.inArray(cm.name, ["rn", "cb", "subgrid"]) >= 0 ? null : cm.name;
});
},
saveColumnState = function () {
var p = this.jqGrid("getGridParam"), colModel = p.colModel, i, l = colModel.length, colItem, cmName,
postData = p.postData,
columnsState = {
search: p.search,
page: p.page,
rowNum: p.rowNum,
sortname: p.sortname,
sortorder: p.sortorder,
cmOrder: getColumnNamesFromColModel.call(this),
selectedRows: idsOfSelectedRows,
colStates: {}
},
colStates = columnsState.colStates;
if (postData.filters !== undefined) {
columnsState.filters = postData.filters;
}
for (i = 0; i < l; i++) {
colItem = colModel[i];
cmName = colItem.name;
if (cmName !== "rn" && cmName !== "cb" && cmName !== "subgrid") {
colStates[cmName] = {
width: colItem.width,
hidden: colItem.hidden
};
}
}
saveObjectInLocalStorage(myColumnStateName(this), columnsState);
},
myColumnsState,
isColState,
restoreColumnState = function (colModel) {
var colItem, i, l = colModel.length, colStates, cmName,
columnsState = getObjectFromLocalStorage(myColumnStateName(this));
if (columnsState) {
colStates = columnsState.colStates;
for (i = 0; i < l; i++) {
colItem = colModel[i];
cmName = colItem.name;
if (cmName !== "rn" && cmName !== "cb" && cmName !== "subgrid") {
colModel[i] = $.extend(true, {}, colModel[i], colStates[cmName]);
}
}
}
return columnsState;
},
updateIdsOfSelectedRows = function (id, isSelected) {
var index = $.inArray(id, idsOfSelectedRows);
if (!isSelected && index >= 0) {
idsOfSelectedRows.splice(index, 1); // remove id from the list
} else if (index < 0) {
idsOfSelectedRows.push(id);
}
},
firstLoad = true;
myColumnsState = restoreColumnState.call($grid, cm);
isColState = myColumnsState !== undefined && myColumnsState !== null;
idsOfSelectedRows = isColState && myColumnsState.selectedRows !== undefined ? myColumnsState.selectedRows : [];
其次是 jqGrid 本身的代码。
$('#ProjectTable').jqGrid({
datatype: 'json',
url: '<%= Url.Action("projectGridData", "SampleSelection") %>',
mType: 'POST',
colNames: [
htmlDecode("<%=Atmis.EncodedLabel("Sample.Project.ProjectId", "ID") %>"),
"",
htmlDecode("<%=Atmis.EncodedLabel("Sample.Project.Name", "Name") %>"),
htmlDecode("<%=Atmis.EncodedLabel("Sample.Project.Code", "Code") %>"),
htmlDecode("<%=Atmis.EncodedLabel("Sample.Project.Manager", "Manager") %>"),
htmlDecode("<%=Atmis.EncodedLabel("Sample.Project.StartDate", "Start Date") %>"),
htmlDecode("<%=Atmis.EncodedLabel("Sample.Project.CompletionDate", "CompletionDate") %>"),
htmlDecode("<%=Atmis.EncodedLabel("Sample.Project.Remark", "Remark") %>"),
htmlDecode("<%=Atmis.EncodedLabel("Sample.Project.Status", "Status") %>"),
""
],
colModel: cm,
caption: htmlDecode("<%=Atmis.EncodedLabel("Sample.Project.Caption", "Project") %>"),
width: $('#tabs-projects').width() - 20,
sortname: 'FieldProjectId',
loadui: 'block',
rowNum: 20,
rowList: [10,25,50,100,200],
sortorder : 'desc',
headertitles:true,
ajaxGridOptions : {
beforeSend: function(xhr) {
$('#ProjectTable').closest('.ui-jqgrid').block({
centerX: false,
centerY: false,
message: $('#ProjectLoading'),
css: {
position: 'absolute',
padding: 0,
margin: 0,
width: 'auto',
top: '40%',
left: '45%',
textAlign: 'center',
cursor: 'wait'
},
overlayCSS: {
backgroundColor: '#524f4f',
opacity: 0.6,
cursor: 'wait'
}
});
},
complete: function(xhr) {
$('#ProjectTable').closest('.ui-jqgrid').unblock();
},
error: function(jqXHR, textStatus, errorThrown) {
$('#ProjectTable').closest('.ui-jqgrid').unblock();
}
},
resizeStop: function(width, index) {
saveColumnState.call($grid, $grid[0].p.remapColumns);
},
sortable: {
update: function(relativeColumnOrder){
saveColumnState.call($grid);
}
},
height: 'auto',
viewrecords: true,
toolbar: [true, "top"],
pager: $('#ProjectPager'),
postData: {
withLinks: true,
clientId: function() {
return $('#ClientId').val();
}
},
editData: {
clientId: function() {
return $('#ClientId').val();
}
},
beforeRequest: function () {
},
onclickSubmit: function (options, postData) {
return {
ClientId: $('#ClientId').val()
};
},
gridComplete: function () {
},
jsonReader:{
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
userdata: "userdata"
},
onSelectRow: function (id) {
// get data from the column 'userCode'
var selRowId = $(this).jqGrid('getGridParam', 'selrow');
var userCode = $(this).jqGrid('getCell', selRowId, 'FieldProjectId');
SelectedProjectID = userCode;
$('#tabs').tabs('enable', 1);
$('#tabs').tabs('enable', 3);
},
loadComplete: function (data){
var $this = $(this), p = $this.jqGrid("getGridParam"), i, count;
if (firstLoad) {
firstLoad = false;
if (isColState && myColumnsState.cmOrder != null && myColumnsState.cmOrder.length > 0) {
// We compares the values from myColumnsState.cmOrder array
// with the current names of colModel and remove wrong names. It could be
// required if the column model are changed and the values from the saved stated
// not corresponds to the
var fixedOrder = $.map(myColumnsState.cmOrder, function (name) {
return p.iColByName[name] === undefined ? null : name;
});
$this.jqGrid("remapColumnsByName", fixedOrder, true);
}
}
saveColumnState.call($this, this.p.remapColumns);
}
}
).filterToolbar();
很难在没有调试的情况下回答长代码的问题。尽管如此,我认为您的问题出在 restoreColumnState
的使用上,您在代码中以 同步方式 : myColumnsState = restoreColumnState.call($grid, cm);
调用它,但它调用 getObjectFromLocalStorage
异步工作。 jquery.ajax
的 success
回调返回的数据 return $.parseJSON(data.colState);
将被忽略。为了适应代码,您可以重写代码以使用 在 success
回调 .