Excelライクを瞬時に実現!SpreadJS V14Jのリボンコンテナを使う – カスタム編 –

WebアプリケーションのクライアントサイドでExcelライクなUIを実現できる高性能JavaScriptライブラリ「SpreadJS(スプレッドJS)」。以下の記事では、最新版の「V14J」で搭載された新コンポーネント「リボンコンテナ」について、その基本的な用法と機能をご紹介しました。

今回はこの続編として、同コンポーネントのリボンメニューやコンテキストメニューをカスタマイズする方法をご紹介します。

おさらい「リボンコンテナ」とは

最初に少しだけ前回のおさらいをしたいと思います。「リボンコンテナ」はスプレッドシートに加え、リボンメニューや数式バー、コンテキストメニューやステータスバーといったUIを一挙に備える非常に便利なコンポーネントです。たった数行のコードを記述するだけで、以下のようにExcelライクな画面をあっという間に構築することが可能になっています。



このリボンコンテナは「SpreadJSデザイナ」をベースに開発されたコンポーネントとなっており、初期状態では同デザイナの機能がそのまま使えるようになっています。リボンメニューに表示されている「セル型」や「ドロップダウン」といった機能はその一例です。

今回の記事では、このリボンメニューやスプレッドシート上に表示されるコンテキストメニューの内容をカスタマイズして、既存のボタンや項目を削除したり、独自のメニューや機能を追加したりする方法をご紹介します。

カスタマイズの概要

前回の記事では以下のようなコードを使ったリボンコンテナの初期化方法をご紹介しました。

// リボンコンテナを初期化します
var ribbonContainer = new GC.Spread.Sheets.Designer.Designer(domHost, null, spread);

この際、コンストラクタには3つの引数が設定されています。その概要は以下の通りです。

第1引数リボンコンテナのホストとなるDOM要素
第2引数リボンコンテナのレイアウトを示すJSONオブジェクト
第3引数リボンコンテナのシート部に統合するSpreadJSのインスタンス

前回、第2引数には”null”を設定していましたが、かわりにカスタマイズ情報を設定することでリボンコンテナのリボンメニューやコンテキストメニューの内容を変更することが可能になります。以下はそのコード例です。

// カスタマイズ情報を設定します
var config = /* JSON形式によるカスタマイズ情報を記述します */;

// リボンコンテナを初期化します
var ribbonContainer = new GC.Spread.Sheets.Designer.Designer(domHost,config,spread);

この際、変数”config”にはリボンメニューやコンテキストメニューで表示する全ての項目のレイアウト情報が含まれている必要がありますが、それらを1から記述する必要はありません。次の手順に従ってリボンコンテナのデフォルトレイアウト情報をコピーし、そこから必要な分だけ変更を行うことで、素早くカスタマイズを実施できます。

デフォルトレイアウト情報のコピー手順:

  1. SpreadJSの製品パッケージを開き、以下のフォルダに移動します。
    \SpreadJS\RibbonContainer
  2. RibbonContainerフォルダにあるdefault_config.jsonファイルを任意のテキストエディターで開き、その内容をコピーします。
  3. 自身の開発コードに任意の変数(上記サンプルコードの変数”config”に相当する変数)を用意します。
  4. 手順2でコピーした内容を手順3で用意した変数の値として設定します。

この手順が実施済みであることを前提として、次の項からはカスタマイズの詳細についてご紹介します。

リボンメニュー/コンテキストメニュー項目の削除

もっとも簡単なカスタマイズ例として、この項ではリボンメニューやコンテキストメニューから既存の項目を削除する方法についてご紹介します。やりかたは非常にシンプルです。デフォルトのレイアウト情報から削除したい項目に対応するオブジェクトを探して削除します。

以下はデフォルト状態のリボンメニューから「セル型」部分を削除するコードの例です(わかりやすいように、コードの削除ではなくコメントアウトで表現しています)。

},
// 以下のオブジェクトを削除/コメントアウトして
// リボンメニューから「セル型」部分を削除します
// {
//     "label": "セル型",
//     "thumbnailClass": "ribbon-thumbnail-celltype",
//     "commandGroup": {
//         "children": [
//             {
//                 "commands": [
//                     "cellType",
//                     "cellDropdowns"
//                 ]
//             }
//         ]
//     }
// },
{
    "label": "スタイル",

このコードをリボンコンテナのレイアウト情報に適用すると、リボンメニューで以下のような変更を確認できます。

リボンメニュー項目の削除
リボンメニュー項目の削除例

また、コンテキストメニューにおける既存項目の削除も同様の方法で実現できます。以下はデフォルト状態のコンテキストメニューから「ソート」メニューを削除するコードの例です。

"separator",
"gc.spread.contextMenu.filter",
// 以下のオブジェクトを削除/コメントアウトして
// コンテキストメニューから「ソート」を削除します
// "sort",
"table",
"separator",

このコードをリボンコンテナに適用すると、コンテキストメニューで以下のような変更を確認できます。

コンテキストメニュー項目の削除
コンテキストメニュー項目の削除例

リボンメニュータブのカスタマイズ

リボンメニューは複数の「ボタン」と、それらをグルーピングした「タブ」で構成されています。リボンコンテナのカスタマイズではこういったタブの変更も可能です。この項ではタブの追加と削除についてご紹介します。

タブの削除

リボンメニューからタブを削除したい場合は前項でご紹介したボタンの削除と同様に、デフォルトのレイアウト情報から削除したい項目に対応するオブジェクトを探して削除します。以下は「挿入」タブを削除するコードの例です。

// 以下のオブジェクトを削除/コメントアウトして
// 「挿入」タブをリボンメニューから削除します
// {
//     "id": "insert",
//     "text": "挿入",
//     "buttonGroups": [
//         {
//             "label": "テーブル",
//             "thumbnailClass": "ribbon-thumbnail-table",
//             "commandGroup": {
//                 "commands": [
//
//        -------------- (中略) ----------------
//
//                     "sparklinesYearSparkline",
//                     "sparklinesRangeBlockSparkline"
//                 ]
//             }
//         }
//     ]
// },
{
    "id": "formulas",
    "text": "数式",
    "buttonGroups": [

このコードをリボンコンテナに適用すると、リボンメニューで以下のような変更を確認できます。

リボンメニューにおけるタブの削除
リボンメニューにおけるタブの削除例

タブの追加

リボンメニューにタブを追加する場合は、以下のような構造をもつJSONオブジェクトをレイアウト情報に追加します。

idプログラム上におけるタブのID情報
text表示上のタブ名称
buttonGroupsタブ内に展開するボタンやラベルの情報

以下に例を示します。下記のサンプルコードでは、リボンメニューに新しいタブ「自由なカスタマイズ」を追加し、その中でラベルの表示を行っています。

var config = {
    "ribbon": [
        // 独自タブを作成します
        {
            // タブのID情報を設定します
            id: "flexibleCustomize",
            // 表示上のタブ名称を設定します
            text: "自由なカスタマイズ",
            // タブ内に展開するボタンやラベルの情報を設定します
            buttonGroups: [
                {
                    // タブのラベル情報を設定します
                    label: "リボンコンテナでは、リボンの表示だけでなくタブの追加や非表示、ボタンの追加などを自由に行うことが可能です。",
                    // ボタン処理がある場合は以下のオブジェクト内で設定します
                    commandGroup: {}
                }
            ]
        },
        // 以下は既存のホームタブ定義です
        {
            "id": "home",
            "text": "ホーム",
            "buttonGroups": [

このコードをリボンコンテナに適用すると、リボンメニューで以下のようなタブが追加されていることを確認できます。

リボンメニューにおけるタブの追加
リボンメニューにおけるタブの追加例

リボンメニューボタンの追加

リボンコンテナのカスタマイズでは、新規に追加したタブや既存のタブに独自のボタンを追加することも可能になっています。ボタンの追加ではタブのレイアウト情報内にある”buttonGroups”オブジェクトを次の例のように記述します。以下は、リボンメニュー上に「保存ボタン」を追加するサンプルコードです。

{
  // 独自タブを作成します
  id: "settings",
  // 表示上のタブ名称を設定します
  text: "独自のボタン設定",
  // タブ内に展開するボタンやラベルの情報を設定します
  buttonGroups: [
    {
      // タブのラベル情報を設定します
      label: "ファイル保存のデモ",
      // ボタン処理がある場合は以下のオブジェクト内で設定します
      commandGroup: {
        // ボタン押下時に呼び出すコマンドを設定します
        commands: ["cmdSaveData"]
      }
    }
  ]
},

上記で”commands:”に設定しているのは、ボタン押下時に独自処理を実行するためのコマンドです。このコマンドは以下のようにして実装します。

// レイアウト情報のプロパティとしてコマンドを作成し追加します
config.commandMap = {
  // コマンド「cmdSaveData」を作成します
  cmdSaveData: {
    // ボタン上をマウスオーバーした際に表示されるキャプションを設定します
    title: "データを保存します",
    // ボタン下部に表示されるラベルを設定します
    text: "保存",
    // ボタン画像を参照するCSSクラスを設定します
    iconClass: "cmdSaveData",
    // リボン上で大きいサイズのボタン表示を行う場合は"true"に設定します
    bigButton: "true",
    // コマンド名を定義します
    commandName: "cmdSaveData",
    // コマンド実行時の処理を記述します
    execute: async (context, propertyName, fontItalicChecked) => {
      alert("データの保存に成功しました");
    }
  }
};

また、ボタンに設定する画像は以下のようにしてCSSファイルに定義します。

/* カスタムボタンのスタイル情報 */
.cmdSaveData {
    /* ボタン画像 (画像が配置してある任意の場所を指定してください)*/
    background-image: url('./saveData.png');
    /* ボタン画像のサイズ */
    background-size: 35px 35px;
}

このようにすることで以下のような独自のリボンメニューボタンが表示できるようになります。

リボンメニューにおけるボタンの追加
リボンメニューにおけるボタンの追加例

コンテキストメニュー項目の追加

リボンメニュー上のボタンと同様に、コンテキストメニューにも独自の項目を追加することが可能です。コンテキストメニュー項目の追加では、リボンコンテナのレイアウト情報内にある”contextMenu”オブジェクトを次の例のように記述します。以下は、リボンコンテナのコンテキストメニューにオリジナルの項目「カスタムメニュー」を追加するサンプルコードです。

"contextMenu": [
    // コンテキストメニューに「カスタムメニュー」を追加します
    "customContextMenu",
    // ここから下は既存のメニュー項目です
    "contextMenuCut",
    "contextMenuCopy",
    "contextMenuPaste",
    "designerPasteAll",
    

上記で設定した”customContextMenu”は、コンテキストメニュー上で項目が選択された場合に実行されるコマンドの名称です。リボンメニューでのボタン追加と同じように、この際のコマンドは以下のようにして実装できます。

// レイアウト情報のプロパティとしてコマンドを作成し追加します
config.commandMap = {
  // コマンド「customContextMenu」を作成します
  customContextMenu: {
    // コンテキストメニューで表示される項目名を設定します
    text: "カスタムメニュー",
    // コマンド名を定義します
    commandName: "customContextmenu",
    // コマンド実行時の処理を記述します
    execute: async (context, propertyName, fontItalicChecked) => {
      // customize operator
      alert("カスタムコンテキストメニューが実行されました");
    }
  }
};

この設定により、以下のような独自のコンテキストメニュー項目が表示できるようになります。

コンテキストメニュー項目の追加
コンテキストメニュー項目の追加例

実際の動作をデモで確認

ここまでにご紹介した方法を使いカスタマイズしたリボンコンテナのデモを以下に示します。



このデモで行ったカスタマイズの内訳は以下の通りです。

リボンメニュー

  • 独自タブの追加(「自由なカスタマイズ」と「独自のボタン設定」タブ)
  • 独自ボタンの追加(「独自のボタン設定」タブ内)
  • 既存のタブの削除(「挿入」タブを削除)
  • 既存ボタンの削除(ホームタブ内にある「セル型」グループを削除)

コンテキストメニュー

  • 独自メニューの追加(「カスタムメニュー」項目)
  • 既存メニューの削除(「ソート」を削除)

上記のデモではソースコードも閲覧できるようになっていますので、是非ご確認ください。

Tips: リボンコンテナを動的にカスタムする方法

今回はリボンコンテナのカスタマイズにあたり、変数にコピーした「default_config.json」の内容を編集する方法をご紹介していますが、以下のようにして既存のレイアウト情報にプログラムから動的にアクセスして、リボンコンテナをカスタマイズすることも可能です。

// 既存のレイアウト情報を取得します
var config = GC.Spread.Sheets.Designer.DefaultConfig;

// 「独自のボタン設定」タブ情報を作成します
var settingsTab = {​​​​​​​​
    // 独自タブを作成します
    id: "settings",
    // 表示上のタブ名称を設定します
    text: "独自のボタン設定",
    // タブ内に展開するボタンやラベルの情報を設定します
    buttonGroups: [
        {​​​​​​​​
            // タブのラベル情報を設定します
            label: "ファイル保存のデモ",
            // ボタン処理がある場合は以下のオブジェクト内で設定します
            commandGroup: {​​​​​​​​
                // ボタン押下時に呼び出すコマンドを設定します
                commands: ["cmdSaveData"]
            }​​​​​​​​
        }​​​​​​​​
    ]
}​​​​​​​​;

// 「自由なカスタマイズ」タブ情報を作成します
var flexibleTab = {
    // タブのID情報を設定します
    id: "flexibleCustomize",
    // 表示上のタブ名称を設定します
    text: "自由なカスタマイズ",
    // タブ内に展開するボタンやラベルの情報を設定します
    buttonGroups: [
        {
            // タブのラベル情報を設定します
            label: "リボンコンテナでは、リボンの表示だけでなくタブの追加や非表示、ボタンの追加などを自由に行うことが可能です。",
            // ボタン処理がある場合は以下のオブジェクト内で設定します
            commandGroup: {}
        }
    ]
};

// 独自のコマンド情報を作成します
config.commandMap = {
    // コマンド「cmdSaveData」を作成します
    cmdSaveData: {
        // ボタン上をマウスオーバーした際に表示されるキャプションを設定します
        title: "データを保存します",
        // ボタン下部に表示されるラベルを設定します
        text: "保存",
        // ボタン画像を参照するCSSクラスを設定します
        iconClass: "cmdSaveData",
        // リボン上で大きいサイズのボタン表示を行う場合は"true"に設定します
        bigButton: "true",
        // コマンド名を定義します
        commandName: "cmdSaveData",
        // コマンド実行時の処理を記述します
        execute: async (context, propertyName, fontItalicChecked) => {
            alert("データの保存に成功しました");
        }
    },
    // コマンド「customContextMenu」を作成します
    customContextMenu: {
        // コンテキストメニューで表示される項目名を設定します
        text: "カスタムメニュー",
        // コマンド名を定義します
        commandName: "customContextmenu",
        // コマンド実行時の処理を記述します
        execute: async (context, propertyName, fontItalicChecked) => {
        // customize operator
        alert("カスタムコンテキストメニューが実行されました");
        }
    }
};

// コンテキストメニューからソートを削除し、カスタムメニューを追加します
config.contextMenu.splice(config.contextMenu.indexOf("sort"), 1);
config.contextMenu.unshift("customContextMenu");
 
// セル型グループを削除します
config.ribbon[0].buttonGroups.splice(5, 1);
// 挿入タブを削除します
config.ribbon.splice(1, 1);

// 独自のタブを先頭に追加します
config.ribbon.unshift(settingsTab);
config.ribbon.unshift(flexibleTab);

この動作とプログラムコードの全体はこちらのデモでご確認いただけるようになっていますので、あわせてご確認ください。

まだまだ盛りだくさん「V14J」の機能をチェック

今回はSpreadJSの「V14J」で追加された新コンポーネント「リボンコンテナ」のカスタマイズ方法をご紹介しました。Excelライクなアプリケーションの効率的な開発にあたり、前回と今回ご紹介した内容がご参考となれば幸いです。

このリボンコンテナ以外にも「V14J」では様々な新機能が搭載されています。弊社Webサイトの製品ページでは、その詳しい紹介やデモの公開を行っていますので、是非、そちらもご確認ください。