set jqgrid with responsive
前言
jqGrid是一款前端jQuery表格,用過後覺得太強大啦~~~
支援排序、分頁,可以讓用戶自己調整欄寬,也可以自己產生全選/複選Checkbox
更重要的是新增、修改、刪除畫面都自己產生好
修改畫面一叫出來也自動資料繫結完畢,讓工程師專心開發後端Web API,省去套畫面很多時間
※jqGrid也支援inline Edit模式
再更進階一點,還有subgrid、grouping....等等,用過後,我之後任何後台系統的CRUD都改用jqGrid來呈現
除非新增、修改畫面太複雜(例如:ckeditor網頁編輯器、檔案上傳...等等)才另外做畫面
但是,這麼好用的套件有一個遺憾,就是預設不支援響應式網頁
如果瀏覽器視窗被用戶拉大縮小,jqGrid的寬度會仍舊維持不變,有時候還造成破版
好在網路上已經出現各種解法解決此問題,以下記錄本人讓jqGrid變得可支援響應式網頁使用的Code
實作
第一步要先把jqGrid的autowidh:true此項拿掉,autowidth:true原本用意要讓jqGrid的呈現為滿版寬度(父元素的寬度),但不知道它詳細計算邏輯如何
有時候呈現出來的寬度會破版或無法滿版(例如放在bootstrap的tab panel裡),所以必須拿掉或改成autowidth:false(預設值)
第二步呼叫jqGrid的setGridWidth方法,填入jqGrid所在的父容器寬度,共有三處需要添加:loadComplete事件、jqGrid初始化繪製完畢、當瀏覽器視窗大小改變時。
jqGrid('setGridWidth', jqGrid父容器的width,是否縮齊column width);
以下是範例程式碼
<html>
<head>
<!--引用jqGrid樣式表-->
<link rel="stylesheet" href="~/Content/css/ui.jqgrid.min.css" />
</head>
<body>
<div class="row">
<div class="col-xs-12">
<table id="grid-table"></table>
</div><!-- /.col -->
</div><!-- /.row -->
<!--引用jQuery函式庫-->
<script src="~/Content/js/jquery-2.1.4.min.js"></script>
<!--引用jqGrid.js-->
<script src="~/Content/js/jqGrid/jquery.jqGrid.min.js"></script>
<!--載入jqGrid中文語系-->
<script src="~/Content/js/jqGrid/grid.locale-tw.js"></script>
<script type="text/javascript">
$(function(){
const grid_selector = "#grid-table";
const pager_selector = grid_selector + "_toppager";
const $grid = jQuery(grid_selector);
function reSizejqGridWidth()
{
//重新抓jqGrid容器的新width
let newWidth = $grid.closest(".ui-jqgrid").parent().width();
//是否縮齊column(相當於shrinkToFit)
let shrinkToFit = true;
$grid.jqGrid("setGridWidth", newWidth, shrinkToFit);
}
//初始化jqGrid,我只挑幾個重點參數Demo
$grid.jqGrid({
datatype: "local",//小技巧,初始化jqGrid時,datatype設為local可以避免網頁一載入jqGrid就馬上對後端發出ajax request
toppager: true,
pager: pager_selector,
loadComplete: function () {
//Load完資料也要重新改變寬度才保險
reSizejqGridWidth();
},
height: "auto",//個人習慣把height設為auto或100%,資料多少筆高度就多少,如果height設為固定高度的話
//資料一多,jqGrid會出現直的捲軸
//autowidth: true,//autowidth有時候會造成破版或放在tab pane裡不會滿版,廢code得拿掉,由以下的parent_dom.width()取代
});
//setTimeout is for webkit only to give time for DOM changes and then redraw!!!
//本範例先執行jqGrid初始化,所以可不用setTimeout,否則有時候setTimeout還是必須的
//setTimeout(function () {
reSizejqGridWidth();
//}, 20);//end setTimeout
//當使用者改變瀏覽器視窗大小時
//resize to fit page size
$(window).on("resize", reSizejqGridWidth);
});
</script>
</body>
</html>
執行結果
※↑此解法當網頁寬度過窄時,jqGrid並不會出現水平捲軸,如果真的column數量太多的話,可以考慮下面解法
修改兩個地方
1.View的部份加入CSS
<style type="text/css">
/*預設已是overflow:auto,寫在網頁裡再次確保會出現scroller*/
.ui-jqgrid .ui-jqgrid-bdiv {
overflow:auto;
}
</style>
2.setGridWidth的最後參數設為false
$grid.jqGrid("setGridWidth", newWidth, false);
範例程式碼↓
<html>
<head>
<!--引用jqGrid樣式表-->
<link rel="stylesheet" href="~/Content/css/ui.jqgrid.min.css" />
<style type="text/css">
/*確保會出現scroller*/
.ui-jqgrid .ui-jqgrid-bdiv {
overflow:auto;
}
</style>
</head>
<body>
<div class="row">
<div class="col-xs-12">
<table id="grid-table"></table>
</div><!-- /.col -->
</div><!-- /.row -->
<!--引用jQuery函式庫-->
<script src="~/Content/js/jquery-2.1.4.min.js"></script>
<!--引用jqGrid.js-->
<script src="~/Content/js/jqGrid/jquery.jqGrid.min.js"></script>
<!--載入jqGrid中文語系-->
<script src="~/Content/js/jqGrid/grid.locale-tw.js"></script>
<script type="text/javascript">
$(function(){
const grid_selector = "#grid-table";
const pager_selector = grid_selector + "_toppager";
const $grid = jQuery(grid_selector);
function reSizejqGridWidth()
{
//重新抓jqGrid容器的新width
let newWidth = $grid.closest(".ui-jqgrid").parent().width();
//是否縮齊column(相當於shrinkToFit)
let shrinkToFit = false;
$grid.jqGrid("setGridWidth", newWidth, shrinkToFit);
}
//初始化jqGrid,我只挑幾個重點參數Demo
$grid.jqGrid({
datatype: "local",//小技巧,初始化jqGrid時,datatype設為local可以避免網頁一載入jqGrid就馬上對後端發出ajax request
toppager: true,
pager: pager_selector,
loadComplete: function () {
//Load完資料也要重新改變寬度才保險
reSizejqGridWidth();
},
height: "auto",//個人習慣把height設為auto或100%,資料多少筆高度就多少,如果height設為固定高度的話
//資料一多,jqGrid會出現直的捲軸
//autowidth: true,//autowidth有時候會造成破版或放在tab pane裡不會滿版,廢code得拿掉,由以下的parent_dom.width()取代
});
//setTimeout is for webkit only to give time for DOM changes and then redraw!!!
//本範例先執行jqGrid初始化,所以可不用setTimeout,否則有時候setTimeout還是必須的
//setTimeout(function () {
reSizejqGridWidth();
//}, 20);//end setTimeout
//當使用者改變瀏覽器視窗大小時
//resize to fit page size
$(window).on("resize", reSizejqGridWidth);
});
</script>
</body>
</html>
執行結果↓
上述為凍結pager解法,隨著捲軸移動,pager仍會固定住,只捲動header和資料列,不過整體仍然支援響應式網頁
讓水平捲軸出現還有另一種解法,就是在<table id="grid-table"></table>外面包覆一層<div>容器,然後設定它的樣式overflow:auto和固定寬度
<div style="width:800px;overflow:auto;">
<table id="grid-table"></table>
<div>
不過由於此種解法捲軸一往右捲動的話,整個pager、header、資料列都會跟著被捲動,不符合個人需求,就不深入介紹了↓
相關文章
Way to make jqGrid responsive on web browsers (stackoverflow 各種解法)
How to show horizontal scroll bar in jqgrid (stackoverflow)
補充1:
另一款和jqGrid同樣強大的前端表格plugin還有jsGrid
兩者功能大同小異,不過jsGrid在響應式網頁的支援比jqGrid較好
jsGrid相關文章:Use ajax to return data and itemCount in loadData function
補充2:
如何更改jqGrid Theme Change style of jqGrid(stackoverflow)