[jQuery] 把jqGrid修改為響應式表格

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)

jqgrid change pointer to hand(stackoverflow)

Disable row select in jqGrid on right click (stackoverflow)