WijmoのFlexGridでページング時の新規データ挿入位置を制御する

2026年8月5日にリリースされた「Wijmo(ウィジモ)」の最新バージョン「2026J v1.1」では、データグリッドコントロール「FlexGrid(フレックスグリッド)」に新規アイテムを追加する際に挿入位置を制御できる2つのAPI(newItemIndexプロパティ・insertAtメソッド)が追加されました。これにより、ページング中のアイテム追加の動作がカスタマイズしやすくなりました。

本記事では、これら2つのAPIの使い方を簡単なサンプルを用いて解説します。

WijmoのFlexGridでページング中のアイテム追加を改善する

アイテムの挿入位置を制御するAPI

今回ご紹介するAPIは以下の2つです。
どちらもグリッドのデータ管理機能を担うCollectionViewクラスのAPIです。

newItemIndexプロパティ

ユーザーがグリッドの新規行テンプレートを使ってアイテムを追加する際の挿入位置を指定することが可能です。新規アイテムはデフォルトでデータ配列の末尾に追加されるため、ページング機能を使用しているグリッドにおいては、途中のページでアイテム追加を行うと、追加したアイテムが最終ページへ移動する動作となります。newItemIndexプロパティを使用することで、表示ページの新規行テンプレートのある位置にそのままアイテムを追加する動作を容易に実現することができます。

insertAtメソッド

コードからアイテムを追加する際に位置を指定して挿入することが可能です。従来から提供されているaddNewメソッドを用いたアイテム追加では、アイテムがデータ末尾に追加されるため、任意の位置に挿入するためには独自実装が必要でした。insertAtメソッドを使用することで、標準機能を使ってこれを実現できるようになりました。

サンプルの概要

今回作成するサンプルプログラムでは、newItemIndexプロパティ、およびinsertAtメソッドの特徴がわかるよう、以下の機能を実装します。

  • ページング機能を使ったデータ表示
  • 新規行テンプレートを使用したアイテム追加
  • コンテキストメニューからのアイテム追加

開発環境の準備

この記事では以下の開発環境を使用します。

今回作成するファイルは次の4つです。

index.htmlページ本体。要素としてFlexGridとCollectionViewNavigatorを配置します
scripts/app.jsFlexGridの生成と各機能の実装コードを記載します
scripts/data.jsFlexGridに連結するデータを記載します
css/styles.cssこのサンプルで使用する各要素のスタイルを設定するコードを記載します

Wijmoの参照設定

FlexGridコントロールをはじめとしたWijmoのコントロールを使用するには、専用のモジュールを環境にインストールする必要があります。CDNを参照したり、npmなどから入手したりする方法もありますが、今回は環境に直接モジュールを配置していきます。あらかじめWijmoの製品版かトライアル版をご用意ください。トライアル版は以下より無償で入手可能です。

製品版、またはトライアル版をダウンロードしたら、ZIPファイルを解凍し、以下のファイルを環境にコピーします。

  • scripts/wijmo.grid.min.js
  • scripts/wijmo.input.min.js
  • scripts/wijmo.min.js
  • scripts/cultures/wijmo.culture.ja.min.js
  • css/wijmo.min.css

※ なお、npmを使ってWijmoの参照を行う場合は、ヘルプの「特定のパッケージをインストールする」に記載しているように、wijmo.gridパッケージに対してinstallコマンドを実行するだけでwijmo.gridが依存するパッケージも自動的にインストールされます。

サンプルの作成

ページング機能を使ってFlexGridにデータを表示する

それでは、最初にベースとなる画面を作成していきます。前述のWijmoモジュールと「app.js」、「data.js」、「styles.css」への参照設定をHTMLファイルに追加します。
※ CDNから参照する場合はコメントアウトされている部分とライブラリの参照先を入れ替えてください。

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>FlexGridで新規アイテムの挿入位置を指定する</title>

    <!-- ローカルのライブラリを参照する場合 -->
    <link rel="stylesheet" href="css/wijmo.min.css" />
    <script src="scripts/wijmo.min.js"></script>
    <script src="scripts/wijmo.grid.min.js"></script>
    <script src="scripts/wijmo.input.min.js"></script>
    <script src="scripts/cultures/wijmo.culture.ja.min.js"></script>

    <!-- CDNからライブラリを参照する場合 -->
    <!-- <link rel="stylesheet" href="https://cdn.mescius.com/wijmo/5.20261.52/styles/wijmo.min.css" />
    <script src="https://cdn.mescius.com/wijmo/5.20261.52/controls/wijmo.min.js"></script>
    <script src="https://cdn.mescius.com/wijmo/5.20261.52/controls/wijmo.grid.min.js"></script>
    <script src="https://cdn.mescius.com/wijmo/5.20261.52/controls/wijmo.input.min.js"></script>
    <script src="https://cdn.mescius.com/wijmo/5.20261.52/controls/cultures/wijmo.culture.ja.min.js"></script> -->

    <link rel="stylesheet" href="css/styles.css">
    <script src="scripts/app.js"></script>
    <script src="scripts/data.js"></script>
</head>

<body>
    <div class="grid-container">
        <div id="thePager"></div>
        <div id="theGrid"></div>
    </div>
</body>

</html>

続いて「app.js」と「data.js」を作成します。
ページング機能はCollectionViewを介して提供される機能です。そのため、今回はあらかじめCollectionViewインスタンスを生成し、ソースデータとページングの設定を行ったうえで、FlexGridのitemsSourceプロパティに設定しています。また、ページを移動するためのUIとしてCollectionViewNavigatorを使用しています。
ページング機能の詳しい使用方法については製品サイトで公開している、以下のデモやヘルプをご参照ください。

※ ライセンスキーを設定しない場合トライアル版を示すメッセージが表示されます。ライセンスキーの入手や設定方法についてはこちらをご覧ください。

wijmo.setLicenseKey('ここにWijmoのライセンスキーを設定します');

document.readyState === 'complete' ? init() : window.onload = init;
function init() {

    // ページングの設定
    const collectionView = new wijmo.collections.CollectionView(data, {
        pageSize: 5,
    });

    const navigator = new wijmo.input.CollectionViewNavigator('#thePager', {
        byPage: true,
        headerFormat: '{currentPage:n0} / {pageCount:n0} ページ',
        cv: collectionView
    });

    // グリッドの生成
    const grid = new wijmo.grid.FlexGrid('#theGrid', {
        itemsSource: collectionView,
        autoGenerateColumns: false,
        alternatingRowStep: 0,
        imeEnabled: true,
        columns: [
            { binding: "category", header: '勘定科目', width: 100 },
            { binding: "name", header: '経費項目名', width: 190 },
            { binding: "code", header: 'コード', width: 100 },
        ]
    });

}
// データ
const data = [
  { category: "交通費", name: "電車代", code: "TRV-001" },
  { category: "交通費", name: "バス代", code: "TRV-002" },
  { category: "交通費", name: "タクシー代", code: "TRV-003" },
  { category: "交通費", name: "新幹線代", code: "TRV-004" },
  { category: "交通費", name: "航空券代", code: "TRV-005" },
  { category: "交通費", name: "レンタカー代", code: "TRV-006" },
  { category: "交通費", name: "高速道路料金", code: "TRV-007" },
  { category: "消耗品費", name: "日用品購入費", code: "SUP-001" },
  { category: "消耗品費", name: "事務用品購入費", code: "SUP-002" },
  { category: "消耗品費", name: "パソコン用品購入費", code: "SUP-003" },
  { category: "通信費", name: "電話料金", code: "COM-001" },
  { category: "通信費", name: "インターネット利用料", code: "COM-002" },
  { category: "通信費", name: "クラウドサービス利用料", code: "COM-003" },
  { category: "通信費", name: "宅配便送料", code: "COM-004" },
];

「styles.css」では各種要素のスタイルを定義します。

/* グリッドのスタイル */
#theGrid {
    border: 1px solid gray;
    inline-size: 432px;
}

/* ページナビゲータのスタイル */
#thePager {
    border: 1px solid gray;
    inline-size: 320px;
}

/* その他の要素のスタイル */
.grid-container {
  display: flex;
  flex-direction: column;
  margin: 20px;
  gap: 6px;
}

html {
    font-family: Meiryo;
}

この状態でサンプルを実行すると、以下のようにページングを有効にしたFlexGridが表示されます。

新規行テンプレートで挿入位置を指定する

次にFlexGridのallowAddNewプロパティをtrueに設定して「新規行テンプレート」を表示しましょう。

・・・(中略)・・・
// グリッドの生成
const grid = new wijmo.grid.FlexGrid('#theGrid', {
    itemsSource: collectionView,
    autoGenerateColumns: false,
    alternatingRowStep: 0,
    imeEnabled: true,
    allowAddNew: true,//新規行テンプレートを使用する
    columns: [
        { binding: "category", header: '勘定科目', width: 100 },
        { binding: "name", header: '経費項目名', width: 190 },
        { binding: "code", header: 'コード', width: 100 },
    ]
});

ユーザーが新規行テンプレートに値を入力することで、自動的にアイテムが追加されるようになりました。しかしながら、新規アイテムはデフォルトでデータ配列の末尾に追加されるため、途中のページを表示した状態でアイテムを追加すると、追加したアイテムが最終ページへ移動してしまいます。

この状態を回避するため、newItemIndexプロパティを使用して追加位置を指定します。
指定する値は、ページング中においては表示中のページ内における行番号として扱われるため、表示中のページ数から追加位置を算出するといった手間をかけることなく利用することが可能です。

ページ内の末尾に追加する場合

サンプルでは新規行テンプレートを一番下の行に表示しているため、pageSize-1を設定して、新規行テンプレートのすぐ上の行(ページ内の末尾)に追加されるようにしましょう。なお、pageSizeは1ページに表示するアイテムの数で、CollectionViewのプロパティから取得することも可能です。

また、グリッドはデフォルトで、値の入力完了時にEnterキーを押すと下の行に移動する動作となっていますが、新規アイテムの追加など、各列の値を連続して編集する場合にはやや不便です。今回は、Enterキーが入力された際の動作を指定するkeyActionEnterプロパティをNoneに設定して、下の行に移動しないようにしています。

・・・(中略)・・・
// ページングの設定
const collectionView = new wijmo.collections.CollectionView(data, {
    pageSize: 5,
    newItemIndex: 4,//ページ内の末尾に追加(pageSize-1)
});

・・・(中略)・・・

// グリッドの生成
const grid = new wijmo.grid.FlexGrid('#theGrid', {
    ・・・(中略)・・・
    keyActionEnter: wijmo.grid.KeyAction.None,//Enterキーで下の行に移動しないようにする
    allowAddNew: true,//新規行テンプレートを使用する
    ・・・(中略)・・・
});

新規行テンプレートのすぐ上の行に追加されるようになり、そのまま編集を継続できるようになりました。

ページ内の先頭に追加する場合

newRowAtTopプロパティをtrueに設定することで、新規行テンプレートを一番上の行に表示することも可能です。この場合、newItemIndexを0(ページ内の先頭)に設定することで、新規行テンプレートのすぐ下の行に追加することができます。

・・・(中略)・・・
// ページングの設定
const collectionView = new wijmo.collections.CollectionView(data, {
    pageSize: 5,
    newItemIndex: 0,//ページ内の先頭に追加
});

・・・(中略)・・・

// グリッドの生成
const grid = new wijmo.grid.FlexGrid('#theGrid', {
    ・・・(中略)・・・
    keyActionEnter: wijmo.grid.KeyAction.None,//Enterキーで下の行に移動しないようにする
    allowAddNew: true,//新規行テンプレートを使用する
    newRowAtTop: true,//新規行テンプレートを先頭に表示
    ・・・(中略)・・・
});

コードからのアイテム追加で挿入位置を指定する

次に、insertAtメソッドを使ってコードからアイテムを追加する例を見ていきましょう。
コンテキストメニューに「行を追加」というメニューを設け、選択中のセルのすぐ上に行を追加する独自機能を実装します。なお、コンテキストメニューの実装方法については以下の製品デモをご参照ください。

「app.js」に以下のコードを追加しましょう。

・・・(中略)・・・
    
// コンテキストメニューの生成
const menu = new wijmo.input.Menu(document.createElement('div'), {
    displayMemberPath: 'header',
    selectedValuePath: 'cmd',
    itemsSource: [
        { header: '行を追加', cmd: 'addRow' }
    ],
    itemClicked: () => {
        if (menu.selectedValue == 'addRow') {
            //選択行の上にアイテムを追加する
            // const item = collectionView.insertAt(grid.selection.row);//先頭に新規行テンプレートが無い場合
            const item = collectionView.insertAt(grid.selection.row-1);//先頭に新規行テンプレートがある場合
            if (!item) return;
            collectionView.commitNew();
        }
    }
});

// グリッドのコンテキストメニューに設定
menu.owner = grid.hostElement;
grid.hostElement.addEventListener('contextmenu', (e) => {
    const ht = grid.hitTest(e.pageX, e.pageY);
    if (ht.cellType == wijmo.grid.CellType.Cell) {
        e.preventDefault();
        menu.show(e);
    }
}, true);

・・・(中略)・・・

MenuコントロールのitemClickedイベントのハンドラ内に、「行を追加」が実行された際の処理を記述しており、ここでinsertAtメソッドを使用しています。

insertAtメソッド第1引数(index)

第1引数では新規アイテムの挿入位置を指定します。この値は、前述のnewItemIndexプロパティと同様、ページング中においては表示中のページ内における行番号として扱われます。

今回は選択セルの上に行を追加するため、グリッドの選択範囲を表すselectionプロパティのrowの値を使用します。この際、selection.rowも表示中のページ内における行番号であるため、シンプルなコードで記述することが可能です。

ただし、今回のように新規行テンプレートを一番上に表示している場合は少し注意が必要です。selection.rowの値は新規行テンプレート分も含んだ行番号ですが、insertAtで指定する行番号には新規行テンプレート分が含まれないためです。これを考慮して、サンプルでは第1引数にgrid.selection.row-1を設定しています。

insertAtメソッド第2引数(item)

第2引数は追加するアイテムを設定するオプション引数です。今回は空の行を追加し、値はユーザーがグリッド上で入力する想定のため、第2引数は設定しません。

insertAtメソッド第3引数(commit)

第3引数は追加処理のコミットを実行するかどうかを設定するオプション引数です。今回は戻り値で成功を確認してからコミットする処理とするため、第3引数は設定しません。

サンプルを実行すると、以下の動画のように、コンテキストメニューから、選択している行の上にアイテムを追加できるようになります。

今回ご紹介した内容については以下のデモアプリケーションで確認できます(“Run Project”をクリックするとデモが起動します)。

さいごに

今回はWijmoのFlexGridにおいて、新規アイテムの挿入位置を指定する方法について解説しました。

ご紹介したnewItemIndexプロパティ、およびinsertAtメソッドは、お客様からのご要望を受けて追加されたAPIとなっています。弊社では日頃からお客様からお寄せいただいたご要望や技術的なお問い合わせを参考に、製品の機能追加や改善を検討しております。
便利になったAPIをぜひお試しください。

なお、製品サイトで公開している以下のデモアプリケーションでも、newItemIndexプロパティ、およびinsertAtメソッドの使い方を詳しくご紹介しておりますので、こちらもご参照ください。

グリッド:ページング/スクロール:新規項目の挿入位置

クライアント側でページングされたCollectionViewにおける、ページ基準の挿入を確認できます。

MESCIUS inc. Wijmoデモ > グリッド > ページング/スクロール > 新規項目の挿入位置

この他にもWijmoの各種コントロールの基本的な使い方や応用的な使い方の解説を連載記事として公開しています。ご活用いただけますと幸いです。

また、製品サイトではWijmoの機能を手軽に体験できるデモアプリケーションやトライアル版も公開しておりますので、こちらもご確認ください。

ご導入前の製品に関するご相談、ご導入後の各種サービスに関するご質問など、お気軽にお問合せください。

\  この記事をシェアする  /