LoginSignup
7
9

More than 5 years have passed since last update.

jqGridの小技たち1(行結合、列結合)

Last updated at Posted at 2015-12-16

業務で使っているのですが、毎回忘れるのでメモ。

バージョン

  • jquery:2.1.1
  • jquery-ui:1.11.1
  • jqGrid:4.6.0

ヘッダに改行を入れる

単純にcolNamesの指定の中で
タグを埋め込めばOKですが、これだけだと改行した部分が表示されないので、以下のようにヘッダの高さを調整する必要があります。

testGrid.js
colNames: ['long<br />text', 'Status']
testGrid.html
<style type="text/css">  
<!--
.ui-jqgrid .ui-jqgrid-htable th {
    height: 70px;
}
.ui-jqgrid .ui-jqgrid-htable th div {
    height: 35px;
}
-->
</style>
※リストが複数ある場合は先頭にIDを指定してあげるとそのリストにのみ適用されます

ヘッダの列結合

結合はできるのですが、2行になってしまうようです。今回はそれでいいやと思って詳しくは調べていません。

setGroupHeadersを使用します。

testGrid.js
    $("#list").jqGrid({
     省略
    });
    $("#list").jqGrid('setGroupHeaders', {
        useColSpanStyle: true,
        groupHeaders: [
          { startColumnName: 'content1', numberOfColumns: 4, titleText: 'content group' },
        ]
    });
  • useColSpanStyle:2行になるので、これをtrueにすると他の行を自動で行結合してくれます
  • startColumnName:どの列から結合するか。colModelで指定したnameを指定します
  • numberOfColumns:何列結合するか
  • titleText:結合列ヘッダに表示する文字列

こちらを参考にしました。
Common rules

データの列結合

colModelの指定の中で、cellattrにcolspanを指定してあげればOKです。
ただし、結合する先頭列にcolspan、結合される列にはdisplay:noneを指定する必要があります。

testGrid.js
colModel: [
            {
                name: 'content1', index: 'content1', width: 100, align: 'center', hidden: false,
                cellattr: function (rowId, tv, rawObject, cm, rdata) {
                    if (rdata.type == 'aaa') { return ' colspan=2' }
                    else if (rdata.type == 'bbb') { return ' colspan=4' }
                }
            },
            {
                name: 'content2', index: 'content2', width: 80, align: 'center', hidden: false,
                cellattr: function(rowId, tv, rawObject, cm, rdata) {
                    if (rdata.type == 'aaa' || rdata.type == 'bbb') { return ' style="display:none;"' }
                }
            },

この場合、type列が'aaa'の場合は2列結合、'bbb'の場合は4列結合しています。
cellattrの中で自由に条件指定できるのはありがたいですね。

こちらを参考にしました。
stackOverFlow - How to merge cells in jqGrid 4.0 -

データの行結合

静的データでは簡単なのかもしれないが、Ajax等で動的にデータを取得している場合はやや面倒。

afterInsertRowで行追加処理をする前にbeforeProcessingでデータを確認する必要があります。
今回の要件の場合、上の行と同じ値だったら結合するという内容でした。
あんまり綺麗なソースじゃありませんが。。。

testGrid.js

var rowStyleList = new Array();

/**
 * グリッドを作成する
 */
function createGrid() {
    $("#list").jqGrid({
     省略

        /**
         * 行追加の前に呼ばれる処理
         */
        beforeProcessing: function () {
            // 行スタイルリストの作成
            createRowStyleList();
        },
        /**
         * 行生成
         */
        afterInsertRow: function (rowid, aData) {
            $("#list").setColProp('column1', {
                cellattr: function (rowId, value, rowObject, colModel, arrData) {
                    // スタイル設定
                    if (rowStyleList.length != 0) {
                        return rowStyleList[rowId - 1][1];
                    }
                }
            });
        },
     省略
    });
}

/**
 * 行スタイルリストを作成する
 */
function createRowStyleList() {

    var rowIDs = $("#list").getDataIDs(); // データ取得
    var prevColumn1 = '';  // 前の行のデータ
    var spanCount = 1;  // 結合行数
    var combTopId = 0;  // 結合の先頭行番号

    var styleList = new Array();

    // 行解析
    var len = rowIDs.length;
    for (var i = 0; i < len; i++) {
        var item = rowIDs[i];
        var column1 = $("#list").getCell(item, 'column1');

        if (prevColumn1 == column1) {
            // 前の行と同じ場合
            spanCount++;
            var rowInfoList = new Array(3); // 0:結合先頭行番号、1:スタイル、2:結合行数(結合先頭行のみ)
            rowInfoList[0] = combTopId + 1;
            rowInfoList[1] = ' style=display:none; '; // 同じなので表示しない
            rowInfoList[2] = 0;
            styleList[i] = rowInfoList;

            if (i + 1 == len) {
                // 最終行の場合
                var rowLastList = new Array(3);
                rowLastList[0] = combTopId + 1;
                rowLastList[1] = ' rowspan=' + spanCount;
                rowLastList[2] = spanCount;
                styleList[combTopId] = rowLastList;
            }
        }
        else {
            // 前の行と違う
            if (i != 0) {
                // 先頭行でない場合
                if (spanCount != 1) {
                    // 複数行の場合
                    var rowInfoList = new Array(3);
                    rowInfoList[0] = combTopId + 1;
                    rowInfoList[1] = ' rowspan=' + spanCount;  // 結合1行目
                    rowInfoList[2] = spanCount;
                    styleList[combTopId] = rowInfoList;

                    if (i + 1 == len) {
                        // 最終行の場合
                        var rowLastList = new Array(3);
                        rowLastList[0] = i + 1;
                        rowLastList[1] = '';
                        rowLastList[2] = 0;
                        styleList[i] = rowLastList;
                    }
                }
                else {
                    // 単一行の場合
                    var rowInfoList = new Array(3);
                    rowInfoList[0] = i;
                    rowInfoList[1] = '';
                    rowInfoList[2] = 0;
                    styleList[i - 1] = rowInfoList;

                    if (i + 1 == len) {
                        // 最終行の場合
                        var rowLastList = new Array(3);
                        rowLastList[0] = i + 1;
                        rowLastList[1] = '';
                        rowLastList[2] = 0;
                        styleList[i] = rowLastList;
                    }
                }

                spanCount = 1;
            }

            combTopId = i;
        }
        prevColumn1 = column1;
    }

    rowStyleList = styleList;
}

※ソースそのまま貼れないので一部抜粋しています。そのままでは動作しないかもしれません。なんとなく伝われば。

ちなみにデータ数が多いと結合されるのに気持ち時間がかかります。
もっと簡単にできる方法があればご指南ください。

(2017/09/21追加)ヘッダの列結合に伴う列のズレ修正

最近遭遇して解決できたので追記。
ヘッダの列結合をしたはいいものの、なぜかヘッダ列とデータ列の列幅がずれて表示されてしまいました。
ネットにはそれっぽい情報はあったのですが解決できず、調べたところ以下で解決できました。

<style type="text/css">
<!--
#gview_list .ui-jqgrid-htable{
    table-layout: auto;
}
-->
</style>

#gview_***の部分は適時自分のリスト名に書き換えてください。

7
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
9