InputManJSのツリービュー機能で階層形式のドロップダウンリストを作成する

日本仕様の入力用JavaScriptコントロールセット「InputManJS(インプットマンJS)」の「V5J」ではリスト項目を階層表示するツリービュー機能が追加されています。この記事では、GcComboBox(コンボ)コントロールを例にツリービュー機能を利用する方法を紹介します。

コンボコントロールのツリービュー機能

開発環境の準備とInputManJSの参照

今回は開発環境として以下を使用します。

作成するファイルは以下の4つです。

index.htmlページ本体。このページの要素としてGcComboBoxを配置します
app.jsGcComboBoxを作成するコードを記載します
data.jsGcComboBoxに連結するデータを記載します
styles.cssこのサンプルで使用する各要素のスタイル設定を行うためのコードを設定します

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

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

  • css/gc.inputman-js.css
  • scripts/gc.inputman-js.ja.js

InputManJSライブラリの参照設定をHTMLファイルに追加します。InputManJSのモジュールに加えて、上記の「app.js」、「data.js」、「style.css」への参照も追加します。
※ CDNから参照する場合はコメントアウトされている部分とライブラリの参照先を入れ替えてください。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>InputManJSのツリービュー機能</title>

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

    <!-- CDNからライブラリを参照する場合 -->
    <!-- <link rel="stylesheet" href="https://cdn.mescius.com/inputmanjs/hosted/css/gc.inputman-js.css">
    <script src="https://cdn.mescius.com/inputmanjs/hosted/scripts/gc.inputman-js.ja.js"></script> -->

    <link rel="stylesheet" href="css/style.css" />
    <script src="scripts/data.js"></script>
    <script src="scripts/app.js"></script>
</head>
<body>
    <div id="combobox" class="normal">
        <h3>GcComboBoxコントロール</h3>
        ・・・ 中略 ・・・
    </div>
</body>
</html>

「app.js」と「style.css」は次のとおりです。今回は5種類の機能を実装したツリービューをそれぞれ紹介するので、それにあわせてコンボコントロールも5つ生成します(コード中の省略箇所は後述します)。
※ ライセンスキーを設定しない場合トライアル版を示すメッセージが表示されます。ライセンスキーの入手や設定方法についてはこちらをご覧ください。

// ライセンスキーの設定
// GC.InputMan.LicenseKey = 'ここにInputManJSのライセンスキーを設定します';

document.addEventListener('DOMContentLoaded', () => {
    // InputManJSコントロールのデザインの指定
    GC.InputMan.appearanceStyle = GC.InputMan.AppearanceStyle.Modern;

    // 対象コントロールの切替
    ・・・ 中略 ・・・

    // GcComboBoxコントロールの生成
    const combo1 = setCombo1();
    const combo2 = setCombo2();
    const combo3 = setCombo3();
    const combo4 = setCombo4();
    const combo5 = setCombo5();

    // GcComboBoxコントロールの表示切替
    ・・・ 中略 ・・・

// GcComboBoxコントロールの生成:基本的なツリービュー
function setCombo1() {
    ・・・ 中略 ・・・
}

// GcComboBoxコントロールの生成:親ノードの選択禁止
function setCombo2() {
    ・・・ 中略 ・・・
}

// GcComboBoxコントロールの生成:複数選択(親子の連携解除)
function setCombo3() {
    ・・・ 中略 ・・・
}

// GcComboBoxコントロールの生成:複数選択(選択値の構成)
function setCombo4() {
    ・・・ 中略 ・・・
}

// GcComboBoxコントロールの生成:テンプレートの利用
function setCombo5() {
    ・・・ 中略 ・・・
}
/* テンプレートのスタイル */
.template-parent-item {
    display: flex;
    align-items: center;
    font-weight: bold;
    height: 100%;
}
.template-item {
    display: flex;
}
.template-item > * {
    display: flex;
    justify-content: center;
    align-items: center;
}
.image img {
    width: 40px;
}
.name {
    justify-content: initial;
    padding-left: 10px;
}
.name ruby {
    font-size: 18px;
    font-weight: bold;
    color: #2676c0;
}
.name rt {
    font-weight: initial;
    color: black;
    padding-top: 2px;
    padding-bottom: 4px;
}

/* InputManJS以外のスタイル */
.selection {
    border: 1px solid silver;
    border-radius: 5px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 10px;
    height: 30px;
    width: 375px;
}
label{
    padding-right: 20px;
}
.setting{
    border: 1px solid silver;
    border-radius: 4px;
    margin-bottom:10px;
    height: 30px;
    width: 270px;
}
#combobox {
    border: 1px solid silver;
    padding-left: 35px;
    padding-bottom: 30px;
    margin-bottom:10px;
    width: 340px;
}
.normal{
    /* 「テンプレートの利用」以外の場合の高さ */
    height: 280px;
}
.template{
    /* 「テンプレートの利用」の場合の高さ */
    height: 360px;
}

ツリービューのデータ構造

「data.js」に記述するデータは、childrenプロパティを使って各データ項目が親子関係を持つように設定します。このプロパティ名の「children」は、IComboBoxDropDownTree インターフェイスのchildrenMemberPathプロパティの既定値ですが、必要に応じて任意に変更することが可能です。

また、ドロップダウンリストを開く時に子階層を展開するかどうかをexpandedプロパティで指定しています。プロパティ名の「expanded」もIComboBoxDropDownTree インターフェイスのexpandedMemberPathプロパティの既定値で、任意に変更することができます。

下記の「employees1」はシンプルな親子階層のデータで、「employees2」はドロップダウンリスト用のテンプレートを使うために少しリッチなデータになっています。

const employees1 = [{
    name: '東京本社',
    expanded: true,
    children: [{
        name: '第一営業',
        children: ['森上 偉久馬', '加藤 泰江'],
        expanded: true
    },
    {
        name: '第二営業',
        children: ['葛城 孝史'],
        expanded: true
    }]
},
{
    name: '大阪支社',
    expanded: true,
    children: [{
        name: '営業開発',
        children: ['川村 匡', '松沢 誠一'],
        expanded: true
    },
    {
        name: '営業一',
        children: ['成宮 真紀'],
        expanded: true
    }]
}];

const employees2 = [{
    name: '東京本社',
    type: 'parent1',
    expanded: true,
    children: [{
        name: '第一営業',
        type: 'parent2',
        expanded: true,
        children: [{
            name: '森上 偉久馬',
            lastKana: 'モリウエ',
            firstKana: 'イクマ',
            lastName: '森上',
            firstName: '偉久馬',
            image: 'https://demo.mescius.jp/inputmanjs/demos/ja/samples/comboBox/itemTemplate/img/man1.png'
        },
        {
            name: '加藤 泰江',
            lastKana: 'カトウ',
            firstKana: 'ヤスエ',
            lastName: '加藤',
            firstName: '泰江',
            image: 'https://demo.mescius.jp/inputmanjs/demos/ja/samples/comboBox/itemTemplate/img/woman1.png'
        }]
    },
    {
        name: '第二営業',
        type: 'parent2',
        expanded: true,
        children: [{
            name: '葛城 孝史',
            lastKana: 'カツラギ',
            firstKana: 'コウシ',
            lastName: '葛城',
            firstName: '孝史',
            image: 'https://demo.mescius.jp/inputmanjs/demos/ja/samples/comboBox/itemTemplate/img/man2.png'
        }]
    }]
},
{
    name: '大阪支社',
    type: 'parent1',
    expanded: true,
    children: [{
        name: '営業開発',
        type: 'parent2',
        expanded: true,
        children: [{
            name: '川村 匡',
            lastKana: 'カワムラ',
            firstKana: 'タダシ',
            lastName: '川村',
            firstName: '匡',
            image: 'https://demo.mescius.jp/inputmanjs/demos/ja/samples/comboBox/itemTemplate/img/man3.png'
        },
        {
            name: '松沢 誠一',
            lastKana: 'マツザワ',
            firstKana: 'セイイチ',
            lastName: '松沢',
            firstName: '誠一',
            image: 'https://demo.mescius.jp/inputmanjs/demos/ja/samples/comboBox/itemTemplate/img/man4.png'
        }]
    },
    {
        name: '営業一',
        type: 'parent2',
        expanded: true,
        children: [{
            name: '成宮 真紀',
            lastKana: 'ナルミヤ',
            firstKana: 'マキ',
            lastName: '成宮',
            firstName: '真紀',
            image: 'https://demo.mescius.jp/inputmanjs/demos/ja/samples/comboBox/itemTemplate/img/woman2.png'
        }]
    }]
}];

GcComboBoxコントロールを作成する

それではGcComboBoxコントロールのツリービュー機能を実装していきます。GcComboBoxコントロールのその他の機能については、デモAPIリファレンスをご参照いただければと思います。

前述の「index.html」のGcComboBoxコントロールで省略されていた部分には、下記の<select>タグを記述します。これによりGcComboBoxコントロールの各種ツリービュー機能を指定(切り替え)できるようになります。

・・・(中略)・・・
    <div id="combobox" class="normal">
        <h3>GcComboBoxコントロール</h3>
        <select id="comboSetting" class="setting">
            <option selected>基本的なツリービュー</option>
            <option>親ノードの選択禁止</option>
            <option>複数選択(親子の連携解除)</option>
            <option>複数選択(選択値:親ノード+子ノード)</option>
            <option>複数選択(選択値:親ノードのみ)</option>
            <option>複数選択(選択値:子ノードのみ)</option>
            <option>テンプレートの利用</option>
        </select>
        <select id="gcComboBox1"></select>
        <select id="gcComboBox2"></select>
        <select id="gcComboBox3"></select>
        <select id="gcComboBox4"></select>
        <select id="gcComboBox5"></select>
    </div>
・・・(中略)・・・

「app.js」の省略部分には、上記の<select>タグの動作を実装するためのコードを記述します。各項目を選択したときの動作については、該当する箇所で詳しく説明します。

// GcComboBoxコントロールの表示切替
combo1.visible = true; // 初期表示
document.querySelector('#comboSetting').addEventListener('change', (e) => {
    combo1.visible = false;
    combo2.visible = false;
    combo3.visible = false;
    combo4.visible = false;
    combo5.visible = false;
    document.querySelector('#combobox').className="normal";
    switch (e.target.selectedIndex) {
        case 0:
            // 基本的なツリービュー
            combo1.text = null;
            combo1.visible = true;
            break;
        case 1:
            // 親ノードの選択禁止
            combo2.text = null;
            combo2.visible = true;
            break;
        case 2:
            // 親子の連携解除
            combo3.text = null;
            combo3.visible = true;
            break;
        case 3:
            // 複数選択(選択値:親ノード+子ノード)
            combo4.dropDownTree.valueConsistsOf = GC.InputMan.ValueConsistsOf.All;
            combo4.text = null;
            combo4.visible = true;
            break;
        case 4:
            // 複数選択(選択値:親ノードのみ)
            combo4.dropDownTree.valueConsistsOf = GC.InputMan.ValueConsistsOf.NonLeafPriority;
            combo4.text = null;
            combo4.visible = true;
            break;
        case 5:
            // 複数選択(選択値:子ノードのみ)
            combo4.dropDownTree.valueConsistsOf = GC.InputMan.ValueConsistsOf.LeafPriority;
            combo4.text = null;
            combo4.visible = true;
            break;
        case 6:
            // テンプレートの利用
            combo5.text = null;
            combo5.visible = true;
            document.querySelector('#combobox').className="template";
            break;
    }
});

基本的なツリービュー

GcComboBoxコントロールのドロップダウンリストをツリービュー形式で表示するには、コンストラクタ内でComboBoxConfigインターフェイスdropDownTypeプロパティをGC.InputMan.ComboDropDownType.Treeに設定します。

また、ツリービュー形式にするには、itemsプロパティに設定するデータが「ツリービューのデータ構造」で解説した親子構造になっていることも必要です。

・・・(中略)・・・
// GcComboBoxコントロールの生成:基本的なツリービュー
function setCombo1() {
    const combo1 = new GC.InputMan.GcComboBox(
        document.getElementById('gcComboBox1'),
        {
            items: employees1,
            displayMemberPath: 'name',
            valueMemberPath: 'name',
            width: 300,
            // ツリービュー形式
            dropDownType: GC.InputMan.ComboDropDownType.Tree,
        });
    combo1.visible = false;
    return combo1;
}
・・・(中略)・・・

ドロップダウンリストを表示して「第一営業」を選択すると次のようになります。

コンボコントロールでツリービュー表示

親ノードの選択禁止

ドロップダウンリストをツリービュー形式にする場合、子ノードだけを選択できるようにしたいことがあります。その場合には、GcComboBoxコントロールのコンストラクタ内でComboBoxConfigインターフェイスdropDownTreeConfig.selectableNodeTypeプロパティをGC.InputMan.TreeViewNodeType.Leafに設定します。

・・・(中略)・・・
// GcComboBoxコントロールの生成:親ノードの選択禁止
function setCombo2() {
    const combo2 = new GC.InputMan.GcComboBox(
        document.getElementById('gcComboBox2'),
        {
            items: employees1,
            displayMemberPath: 'name',
            valueMemberPath: 'name',
            width: 300,
            // ツリービュー形式
            dropDownType: GC.InputMan.ComboDropDownType.Tree,
            // 親ノード選択禁止
            dropDownTreeConfig: {
                selectableNodeType: GC.InputMan.TreeViewNodeType.Leaf
            }
        });
    combo2.visible = false;
    return combo2;
}
・・・(中略)・・・

ドロップダウンリストを表示して「第一営業」を選択すると、子階層が折り畳まれて次のようになります。このときテキストエリアには何も表示されません。

親ノードの選択禁止

複数選択(親子の連携解除)

ドロップダウンリストで複数項目の選択を許可している場合、親ノードと子ノードの連携を解除することが可能です。既定の状態では、親ノードを選択すると対応するすべての子ノードも自動的に選択されます。また、同じ親を持つすべての子ノードが選択されると対応する親ノードが自動的に選択状態になります。親子の連携を解除すると、選択した親ノードまたは子ノードだけが選択状態になり、親子間の連携動作は行われなくなります。

複数項目の選択許可は、GcComboBoxコントロールのコンストラクタ内でComboBoxConfigインターフェイスisMultiSelectプロパティをtrueに設定することで実現します。

複数選択時の親子間の連携を解除する場合は、ComboBoxConfigインターフェイスのdropDownTreeConfig.flatプロパティをtrueに設定します。

「app.js」ファイルのsetCombo3関数に下記のコードを記述することで、複数選択を許可した場合に親子の連携を解除したときの動作を確認できます。

・・・(中略)・・・
// GcComboBoxコントロールの生成:複数選択(親子の連携解除)
function setCombo3() {
    const combo3 = new GC.InputMan.GcComboBox(
        document.getElementById('gcComboBox3'),
        {
            items: employees1,
            displayMemberPath: 'name',
            valueMemberPath: 'name',
            width: 300,
            // ツリービュー形式
            dropDownType: GC.InputMan.ComboDropDownType.Tree,
            // 親子の連携解除
            dropDownTreeConfig: {
                flat: true
            },
            // 複数選択
            isMultiSelect: true,
            checkOnClick: true,
            multipleItemSeparator: '  |  '
        });
    combo3.visible = false;
    return combo3;
}
・・・(中略)・・・

複数選択を許可した場合に親子連携を解除すると、次のような動作になります。

親子の連携が有効な既定の状態では、対応する親ノードまたは子ノードも自動的に選択状態になります。

複数選択(選択値の構成)

GcComboBoxコントロールでは、複数選択を許可したときにテキストエリアに設定する内容を次の3種類から指定することができます。

  • 親ノード+子ノード
  • 親ノードのみ
  • 子ノードのみ

テキストエリアに表示する内容を指定するdropDownTree.valueConsistsOfプロパティは読み取り専用ではないため、GcComboBoxコントロールのコンストラクタ内ではなく、コントロールのインスタンスを使って動的に切り替えることができます。

複数選択を許可したツリービュー形式のGcComboBoxコントロールを生成するコードは次のとおりです。

・・・(中略)・・・
// GcComboBoxコントロールの生成:複数選択(選択値の構成)
function setCombo4() {
    const combo4 = new GC.InputMan.GcComboBox(
        document.getElementById('gcComboBox4'),
        {
            items: employees1,
            displayMemberPath: 'name',
            valueMemberPath: 'name',
            width: 300,
            // ツリービュー形式
            dropDownType: GC.InputMan.ComboDropDownType.Tree,
            // 複数選択
            isMultiSelect: true,
            checkOnClick: true,
            multipleItemSeparator: '  |  '
        });
    combo4.visible = false;
    return combo4;
}
・・・(中略)・・・

複数選択(選択値:親ノード+子ノード)

GcComboBoxコントロールのdropDownTree.valueConsistsOfプロパティをGC.InputMan.ValueConsistsOf.Allに設定すると、テキストエリアには選択した親ノードと子ノードの両方が表示されます。

・・・(中略)・・・
// GcComboBoxコントロールの表示切替
combo1.visible = true; // 初期表示
document.querySelector('#comboSetting').addEventListener('change', (e) => {
    ・・・ 中略 ・・・
    switch (e.target.selectedIndex) {
        ・・・ 中略 ・・・
        case 3:
            // 複数選択(選択値:親ノード+子ノード)
            combo4.dropDownTree.valueConsistsOf = GC.InputMan.ValueConsistsOf.All;
            combo4.text = null;
            combo4.visible = true;
            break;
        ・・・ 中略 ・・・
    }
});
・・・(中略)・・・

ドロップダウンリストを表示して「第一営業」を選択すると、次のように親ノードと子ノードの両方がテキストエリアに表示されます。

複数選択(選択値:親ノード+子ノード)

複数選択(選択値:親ノードのみ

GcComboBoxコントロールのdropDownTree.valueConsistsOfプロパティをGC.InputMan.ValueConsistsOf.NonLeafPriorityに設定すると、テキストエリアには選択した親ノードだけが表示され、選択されている子ノードは表示されません。

・・・(中略)・・・
// GcComboBoxコントロールの表示切替
combo1.visible = true; // 初期表示
document.querySelector('#comboSetting').addEventListener('change', (e) => {
    ・・・ 中略 ・・・
    switch (e.target.selectedIndex) {
        ・・・ 中略 ・・・
        case 5:
            // 複数選択(選択値:子ノードのみ)
            combo4.dropDownTree.valueConsistsOf = GC.InputMan.ValueConsistsOf.LeafPriority;
            combo4.text = null;
            combo4.visible = true;
            break;
        ・・・ 中略 ・・・
    }
});
・・・(中略)・・・

ドロップダウンリストを表示して「第一営業」を選択すると、次のように親ノードだけがテキストエリアに表示されます。

複数選択(選択値:親ノードのみ)

複数選択(選択値:子ノードのみ

GcComboBoxコントロールのdropDownTree.valueConsistsOfプロパティをGC.InputMan.ValueConsistsOf.LeafPriorityに設定すると、テキストエリアには選択した子ノードだけが表示され、選択されている親ノードは表示されません。

・・・(中略)・・・
// GcComboBoxコントロールの表示切替
combo1.visible = true; // 初期表示
document.querySelector('#comboSetting').addEventListener('change', (e) => {
    ・・・ 中略 ・・・
    switch (e.target.selectedIndex) {
        ・・・ 中略 ・・・
        case 5:
            // 複数選択(選択値:子ノードのみ)
            combo4.dropDownTree.valueConsistsOf = GC.InputMan.ValueConsistsOf.LeafPriority;
            combo4.text = null;
            combo4.visible = true;
            break;
        ・・・ 中略 ・・・
    }
});
・・・(中略)・・・

ドロップダウンリストを表示して「第一営業」を選択すると、次のように子ノードだけがテキストエリアに表示されます。

複数選択(選択値:子ノードのみ)

テンプレートの利用

GcComboBoxコントロールではテンプレート機能を使用することで、項目に画像を表示したり、多段形式で表示することができますが、ツリービューでも同様にテンプレート機能が使用できます。

GcComboBoxコントロールのドロップダウンリストのテンプレートは、コンストラクタ内でComboBoxConfigインターフェイスdropDownTreeConfig.itemTemplateプロパティに設定します。

「data.js」に記述したemployees2では、各階層を判別するためにtypeプロパティを設定しています。下記コードの「item.type === 'parent1'」は第1階層のノードを表し、「item.type === 'parent2'」は第2階層のノードを表しています。そして第3階層のノードのデータにはtypeプロパティを設定していません。

これにより、第1階層と第2階層のノードにはnameプロパティに設定した文字列を表示し、第3階層のノードにはlastNameプロパティとfirstNameプロパティで設定した氏名、lastKanaプロパティとfirstKanaプロパティで設定したフリガナ、およびimageプロパティで設定した画像を表示することができます。

・・・(中略)・・・
// GcComboBoxコントロールの生成:テンプレートの利用
function setCombo5() {
    const combo5 = new GC.InputMan.GcComboBox(
        document.getElementById('gcComboBox5'),
        {
            items: employees2,
            displayMemberPath: 'name',
            valueMemberPath: 'name',
            width: 300,
            itemHeight: 45,
            // ツリービュー形式
            dropDownType: GC.InputMan.ComboDropDownType.Tree,
            dropDownTreeConfig: {
                // テンプレートの作成
                itemTemplate: (item) => {
                    const container = document.createElement("div");
                    if (item.type === 'parent1') {
                        container.classList.add("template-parent-item");
                        container.innerHTML = `<span>${item.name}</span>`
                    } else if (item.type === 'parent2') {
                        container.classList.add("template-parent-item");
                        container.innerHTML = `<span>${item.name}</span>`
                    } else {
                        container.classList.add("template-item");
                        container.innerHTML = `
                            <div class="image"><img src="${item.image}"></div>
                            <div class="name">
                                <ruby>${item.lastName}<rt>${item.lastKana}</rt></ruby> 
                                <ruby>${item.firstName}<rt>${item.firstKana}</rt></ruby>
                            </div>`;
                    }
                    return container;
                }
            }
        });
    combo5.visible = false;
    return combo5;
}
・・・(中略)・・・

上記のコードを使って作成したGcComboBoxコントロールのドロップダウンリストで「森上 偉久馬」さんを選択すると、次のようになります。

テンプレートの利用

Webサイトではテンプレートを使ったツリービュー表示のデモをご用意していますので、そちらもご参照いただければと思います。また、テンプレートの基本的な利用法についてはこちらをご覧ください。

今回ご紹介したGcComboBoxコントロールのツリービュー機能は以下のデモアプリケーションでも確認できます(“Run Project”をクリックするとデモが起動します)。

さいごに

今回はInputManJSに含まれるGcComboBox(コンボ)コントロールのツリービュー機能について解説しました。ツリービュー機能はGcTagBox(タグボックス)コントロールでも利用可能ですので、詳しくはデモをご覧ください。

InputManJSは、リッチテキスト、テキスト、マスク、日付時刻、数値、コンボなど用途別に最適化された入力用コントロールを収録したJavaScript製品です。Webアプリケーションにおけるストレスフリーのきめ細かい入力フォームの開発に、ぜひInputManJSをご検討いただければと思います。

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

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

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