作成日: 2026/02/03 最終更新日: 2026/02/13
文書種別
制限事項
状況
回避方法あり
詳細
FlexGridで下記の例のような実装を行い、複数の列ヘッダーの一番下の列ヘッダーを固定した場合に、横スクロールを行うと列ヘッダーが崩れます。
(例)
・getMergedRangeを拡張してヘッダセルの結合/セル結合を実装
・allowPinning = 'ColumnRange'を設定し、列を固定できるようにする
・2段構成のヘッダ(1段目は結合あり、2段目は結合なし)
こちらのサンプルに「grid.allowPinning = "ColumnRange";」を追加して、Country列をピンで固定後、横スクロールを行うことで再現します。
(例)
・getMergedRangeを拡張してヘッダセルの結合/セル結合を実装
・allowPinning = 'ColumnRange'を設定し、列を固定できるようにする
・2段構成のヘッダ(1段目は結合あり、2段目は結合なし)
こちらのサンプルに「grid.allowPinning = "ColumnRange";」を追加して、Country列をピンで固定後、横スクロールを行うことで再現します。
回避方法
以下の2つの手順を実装します。
1.getMergedRangeで結合範囲を分割する
固定された境界で固定領域と非固定領域を別々の範囲として返すようにします。
2.formatItemを使用して視覚的な連続性を維持する
固定セルの幅を動的に拡張し、表示されている非固定列をカバーすることで、単一の結合セルのように見せます。
【CSS】
.wj-flexgrid {
max-height: 200px;
width: 400px;
}
/* ===== WORKAROUND: 固定列の Z インデックスを修正 ===== */
/* これにより、結合されたヘッダーの固定部分がスクロールするコンテンツを覆います */
.wj-colheaders .wj-frozen-col-left {
z-index: 2 !important;
}
/* ===== WORKAROUND: 固定境界でマージされたヘッダーをクリップする ===== */
/* 固定部分には完全なコンテンツが表示され、非固定部分はクリップされます */
.wj-colheaders .wj-cell.merged-header-frozen {
overflow: visible;
z-index: 3 !important;
}
.wj-colheaders .wj-cell.merged-header-scrollable {
/* スクロール可能な部分のテキストを非表示にします。
固定された部分にはすでにテキストが表示されています */
color: transparent;
}
【JavaScript】
// テストデータ生成
var count = 50;
var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(',');
var data = [];
for (var i = 0; i < count; i++) {
data.push({
id: i,
country: countries[i % countries.length],
date: new Date(2014, i % 12, i % 28),
amount: Math.random() * 10000,
active: i % 4 === 0
});
}
// グリッド生成
var grid = new wijmo.grid.FlexGrid('#grid');
grid.itemsSource = data;
grid.allowPinning = "ColumnRange";
// 列ヘッダに行追加
// ===== WORKAROUND: 中央揃えのために wj-colgroup クラスを追加する =====
var headerRow = new wijmo.grid.Row();
// headerRow.cssClassAll = 'wj-colgroup wj-align-center';
grid.columnHeaders.rows.insert(0, headerRow);
// 列ヘッダの1列目と5列目に同値をセット
for (var i = 0; i < grid.columns.length; i++) {
if (i == 0 || i == 4) {
grid.columnHeaders.setCellData(0, i, grid.columnHeaders.getCellData(1, i));
}
}
// 列ヘッダ1行目の2~4列に同値を設定
for (var i = 1; i < 4; i++) {
grid.columnHeaders.setCellData(0, i, "結合");
}
// MergeManagerを作成
// 5.20203.766からMergeManagerのコンストラクタ引数のGridが非推奨となりました
// var mm = new wijmo.grid.MergeManager(grid);
var mm = new wijmo.grid.MergeManager();
// 結合するセルの範囲
var ranges = [
new wijmo.grid.CellRange(0, 2, 1, 2),
new wijmo.grid.CellRange(2, 2, 3, 2)
];
// ===== WORKAROUND: 回避策: 固定された境界処理を使用した getMergedRange =====
mm.getMergedRange = function (panel, r, c, clip) {
if (panel.cellType == wijmo.grid.CellType.Cell) {
for (var i = 0; i < ranges.length; i++) {
if (ranges[i].contains(r, c)) {
return ranges[i];
}
}
}
else if (panel.cellType == wijmo.grid.CellType.ColumnHeader) {
// Id列と後ろの列は縦に結合
if (c == 0 || c == 4) {
return new wijmo.grid.CellRange(0, c, 1, c);
}
// 結合列 (1行目の1-3列)
if (r == 0 && (c == 1 || c == 2 || c == 3)) {
var cols = panel.columns;
var frozenCols = cols.frozen;
// 固定列なし - 完全な結合範囲を返す
if (frozenCols <= 0) {
return new wijmo.grid.CellRange(0, 1, 0, 3);
}
// 固定された境界を処理する
if (cols.isFrozen(c)) {
// 固定部分: 範囲内の 1 列目から最後の固定列までを結合します
var lastFrozenInRange = Math.min(3, frozenCols - 1);
if (lastFrozenInRange >= 1) {
return new wijmo.grid.CellRange(0, 1, 0, lastFrozenInRange);
}
return null;
} else {
// 非固定部分: 最初の非固定部分から3番目までマージ
var firstNonFrozen = Math.max(1, frozenCols);
if (firstNonFrozen <= 3) {
return new wijmo.grid.CellRange(0, firstNonFrozen, 0, 3);
}
return null;
}
}
}
else if (panel.cellType == wijmo.grid.CellType.TopLeft) {
return new wijmo.grid.CellRange(0, 0, 1, 0);
}
return null;
};
grid.mergeManager = mm;
// ===== WORKAROUND: formatItem を使用して固定ヘッダーを視覚的に拡張します =====
grid.formatItem.addHandler(function(s, e) {
if (e.panel.cellType == wijmo.grid.CellType.ColumnHeader && e.row == 0) {
var cols = s.columns;
var frozenCols = cols.frozen;
// これが「結合」結合範囲(列1~3)の一部であるかどうかを確認します。
if (e.col >= 1 && e.col <= 3 && frozenCols > 0 && frozenCols <= 3) {
if (cols.isFrozen(e.col)) {
// これはマージされたヘッダーの固定部分です
wijmo.addClass(e.cell, 'merged-header-frozen');
// 表示されている非固定列の表示幅を計算します
var scrollLeft = s.scrollPosition.x;
var extraWidth = 0;
// 結合範囲内でまだ表示されている非固定列の幅を追加します
for (var c = frozenCols; c <= 3; c++) {
var col = cols[c];
if (col && col.isVisible) {
var colLeft = col.pos + scrollLeft;
var colRight = colLeft + col.renderWidth;
var frozenRight = cols[frozenCols - 1].pos + cols[frozenCols - 1].renderWidth;
// 列が表示されている場合(固定領域と重なるか、固定領域の右側にある場合)
if (colRight > frozenRight) {
var visibleLeft = Math.max(colLeft, frozenRight);
var visibleWidth = colRight - visibleLeft;
if (visibleWidth > 0) {
extraWidth += visibleWidth;
}
}
}
}
// 固定セルの幅を拡張して、目に見える非固定領域をカバーします。
if (extraWidth > 0) {
var currentWidth = parseFloat(e.cell.style.width) || e.cell.offsetWidth;
e.cell.style.width = (currentWidth + extraWidth) + 'px';
// グリッド境界で延長部分をクリップする
e.cell.style.overflow = 'hidden';
}
} else {
// これは非固定(スクロール可能)部分です
wijmo.addClass(e.cell, 'merged-header-scrollable');
}
}
}
});