BootstrapTable自定义列本地存储实践
需求:
开放BootstrapTable的自定义表格列功能,前端记录用户选择,即在用户不清理浏览器历史记录的情况下,始终显示用户上一次的配置。
分析:
因项目基于AngularJS1.5实现,过滤了一部分老旧版本浏览器。所以选择使用h5的LocalStorage来记录用户的配置隐藏的列。
1.查询Bootstrap Table API,配置项showColumns用来配置是否可配置显示/隐藏列。
showColumns: true, //显示下拉框勾选要显示的列
bootstrap-table.js源码中,对于showColumns为true时,监听事件如下:
if (this.options.showColumns) {
$keepOpen = this.$toolbar.find('.keep-open');
if (switchableCount <= this.options.minimumCountColumns) {
$keepOpen.find('input').prop('disabled', true);
}
$keepOpen.find('li').off('click').on('click', function (event) {
event.stopImmediatePropagation();
}).find('span').off('checkChange').on('checkChange', function () {
var ckeck = $(this).find('input').prop('checked');
$(this)[ckeck ? 'addClass' : 'removeClass']('active');
});
$keepOpen.find('input').off('click').on('click', function () {
var $this = $(this);
that.toggleColumn(getFieldIndex(that.columns,
$(this).data('field')), $this.prop('checked'), false);
that.trigger('column-switch', $(this).data('field'), $this.prop('checked'));
$this.parent('span').trigger('checkChange');
});
}
可知:通过代码触发的"click"事件,BootStrap Table会自己完成列的隐藏/显示操作。
//代码示例
$(".bootstrap-table ul.dropdown-menu").find('input[data-field="APPName"]').trigger("click");
2.基于Bootstrap Table DOM结构,可以遍历查询获取已经隐藏列的唯一标识field。
//代码示例
var aTmpConfig = [];
$(".bootstrap-table ul.dropdown-menu").find("input").each(function (i,v) {
if(!$(v).parent().hasClass("active")) {
aTmpConfig.push($(v).attr("data-field"));
}
});
3.查询Bootstrap Table API,有onLoadSuccess事件、onColumnSwitch事件和hideColumn(field)方法,即可在BsTable成功加载数据之后触发隐藏列操作;在点击列显示/隐藏开关时,触发保存userConfig数据。
onLoadSuccess | load-success.bs.table | data | Fires when remote data is loaded successfully.
onColumnSwitch | column-switch.bs.table | field, checked Fires when switch the column visible.
hideColumn | field | Hide the specified column.
······
//代码示例
onLoadSuccess: function () {
//get Config from LocalStorage
$scope.$broadcast('hideColumn'+ '#' + tid, sField);
},
······
4.查询Bootstrap Table API,有getHiddenColumns方法,获取所有隐藏的列。在保存userConfig时可使用该方法。
//附bootstrap-table.js源码
BootstrapTable.prototype.getHiddenColumns = function () {
return $.grep(this.columns, function (column) {
return !column.visible;
});
};
设计:
初始化:
在Bs.Table的onLoadSuccess事件里,判断浏览器是否支持LocalStorage且用户是否对该Bs.Table有隐藏列配置,即window.localStorage && window.localStorage.hasOwnProperty(tid+"BsTable");
获取该页面Bs.Table用户隐藏列唯一标识field,即window.localStorage.getItem(tid+"BsTable");
再通过Bs.Table的hideColumn方法或触发标签"click"事件循环隐藏列。
保存配置:
在用户离开页面或者配置显示、隐藏列时,通过Bs.Table的getHiddenColumns方法或遍历Bs.Table的DOM,获取所有隐藏列的field,存储在LocalStorage中,即window.localStorage.setItem(tid+"BsTable",sConfig)。
实现:
- LocalStorage 相关
var oStorage = {
_Storage: window.localStorage,
isSupportStorage: function () {
return this._Storage != undefined ? true : false;
},
hasItem: function (item) {
return this._Storage.hasOwnProperty(item);
},
getItem: function (item) {
return JSON.parse(this._Storage.getItem(item));
},
setItem: function (item,val) {
return this._Storage.setItem(item,JSON.stringify(val));
}
};
- Bs.Table配置(建议使用第一种)
//1.使用触发标签click事件隐藏列
······
showColumns: true, //enable show/hide columns menu
onLoadSuccess: function () {
//browser supported LocalStorage and has userConfig
if(oStorage.isSupportStorage() && oStorage.hasItem(tid+"BsTable")) {
//get userConfig from LocalStorage
var aUserConfHideCols = oStorage.getItem(tid+"BsTable");
aUserConfHideCols.forEach(function (sField) {
$(".bootstrap-table ul.dropdown-menu").find('input[data-field=' + sField
+ ']').trigger("click");
});
}
},
······
//2.使用BsTable hideColumn方法
//这个方法直接隐藏列,不会触发下拉框的"click"事件,下拉框里面列仍然为"显示"状态,需要再remove掉active类。
······
showColumns: true, //enable show/hide columns menu
onLoadSuccess: function () {
//browser supported LocalStorage and has userConfig
if(oStorage.isSupportStorage() && oStorage.hasItem(tid+"BsTable")) {
//get userConfig from LocalStorage
var aUserConfHideCols = oStorage.getItem(tid+"BsTable");
aUserConfHideCols.forEach(function (sField) {
$scope.$broadcast('hideColumn'+ '#' + tid, sField);
$(".bootstrap-table ul.dropdown-menu").find('input[data-field=' + sField
+ ']').parent().removeClass("active");
});
}
},
······
- 保存userConfig
//1.用户配置显示、隐藏列时保存userConfig
//1.1BsTable onColmunSwitch事件监听
······
onColumnSwitch: function () {
$scope.$broadcast('getHiddenColumns' + '#' + tid, function(aCols) {
var aTmpConfig = [];
aCols.forEach(function(col) {
aTmpConfig.push(col.field);
});
oStorage.setItem(tid + "BsTable", aTmpConfig);
});
},
······
//1.2DOM 事件监听
$(".bootstrap-table ul.dropdown-menu li").on("click",function () {
var aTmpConfig = [];
$(".bootstrap-table ul.dropdown-menu").find("input").each(function (i,v) {
if(!$(v).parent().hasClass("active")) {
aTmpConfig.push($(v).attr("data-field"));
}
});
oStorage.setItem(tid+"BsTable",aTmpConfig);
});
//2.在离开页面时保存userConfig
//这个无法实现,在'$destroy'的事件里,BsTable实例已经被销毁,getHiddenColumns方法没有正确的返回值。
//$scope.$on('$destroy',function() {
// $scope.$broadcast('getHiddenColumns'+ '#' + tid, function (aCols) {
// var aTmpConfig = [];
// aCols.forEach(function (col) {
// aTmpConfig.push(col.field);
// });
// oStorage.setItem(tid+"BsTable",aTmpConfig);
// });
//});
Finally.根据项目环境,选择方案如下:
var tid = *****; //项目中BsTable的唯一标识id
var oStorage = {
_Storage: window.localStorage,
isSupportStorage: function () {
return this._Storage != undefined ? true : false;
},
hasItem: function (item) {
return this._Storage.hasOwnProperty(item);
},
getItem: function (item) {
return JSON.parse(this._Storage.getItem(item));
},
setItem: function (item,val) {
return this._Storage.setItem(item,JSON.stringify(val));
}
};
······//此处省略BsTable其他配置BsTableOpt
var uConfigOpt = {
showColumns: true, //enable show/hide columns menu
onLoadSuccess: function () {
//browser supported LocalStorage and has userConfig
if(oStorage.isSupportStorage() && oStorage.hasItem(tid+"BsTable")) {
//get userConfig from LocalStorage
var aUserConfHideCols = oStorage.getItem(tid+"BsTable");
aUserConfHideCols.forEach(function (sField) {
$(".bootstrap-table ul.dropdown-menu").find('input[data-field=' + sField
+ ']').trigger("click");
});
}
},
onColumnSwitch: function () {
$scope.$broadcast('getHiddenColumns' + '#' + tid, function(aCols) {
var aTmpConfig = [];
aCols.forEach(function(col) {
aTmpConfig.push(col.field);
});
oStorage.setItem(tid + "BsTable", aTmpConfig);
});
}
}
$.extend(true,BsTableOpt,uConfigOpt);
续
---上述实现没有体现区分用户设置:即在同一pc上,由不同的用户访问该表格,对自定义列的配置是一样婶儿的,所以建议在保存storage时,key值增加userName信息。---