デモで学ぶ業務アプリのUI開発(2) – BOM(部品表) –

メシウスのWebサイトではJavaScriptライブラリを活用した業務アプリのUIの実装サンプルを、ダウンロード可能なソースコード付きで多数公開しています。

本連載ではWebサイトで公開しているサンプルアプリケーションを例に、様々な業務アプリケーションのUIの実装のポイントを解説していきます。第2回となる本記事ではJavaScript UIライブラリ「Wijmo(ウィジモ)」の各種コントロールを使用した「BOM(Bill Of Materials:部品表)」デモの解説です。BOM(部品表)のデモは3種ありますが、今回は「BOM(部品表)1」をご紹介します。

BOM(部品表)1

利用しているコントロール

「BOM(部品表)1」デモでは、Wijmoの以下のコントロールを使用しています。

データの一覧表示にはFlexGridを使用し、FlexGridSearchを使用したデータ検索が可能です。
また、ListBoxを使用したグリッド列項目の表示/非表示の制御、Popupを使用してダイアログからのデータの編集も可能です。
さらに、FlexGridXlsxConverterを使用して、FlexGrid上のデータをExcelにエクスポートできます。

コントロール名利用目的イメージ
FlexGridSearchグリッド内のデータを検索します。FlexGridSearch
ListBoxグリッド列の表示/非表示を変更します。ListBox
FlexGridXlsxConverterグリッドをExcelにエクスポートします。FlexGridXlsxConverter
FlexGrid部品表のデータを表示します。FlexGrid
Popupポップアップエディタでグリッドのデータ編集を行います。Popup

各コントロールの解説

ここからは各コントロールのソースコード部分を抜粋し、ポイントとなる部分を解説します。

ListBox編

ListBoxではグリッド列の非表示を制御するため、itemsSourceプロパティにはグリッドの列の配列(flexGrid.columns)を割り当てています。(※1の部分)
また、※2の部分ではcheckedItemsChangedイベントを利用して、ListBox内のチェック状態とグリッド列の表示状態を連動させています。visbleCol変数にはListBox内のチェックの存在する項目のindexを保持したうえで、FlexGridの列ごとに該当のindexが存在しているかどうかをチェックし、列のvisibleプロパティを変更しています。

const list = new ListBox('#theListBox2', {
    displayMemberPath: 'header',
    checkedMemberPath: 'selected',
    itemsSource: flexGrid.columns, // ※1
    checkedItemsChanged: (sender) => { // ※2 
        let visbleCol = sender.checkedItems.map((item) => {
            return item.index;
        });
        flexGrid.columns.forEach((col, index) => {
            col.visible = visbleCol.includes(index);
        });
    }
});

Popup編

Popupコントロールを使用したポップアップエディタでカスタムフォームを表示し、行のデータを編集することができます。
ここではhitTestメソッドにより、ユーザーがグリッドのどこをクリックしたかを特定し、ht.panel == flexGrid.rowHeadersの部分で行ヘッダーがクリックされた時のみポップアップエディタが表示されるように設定しています。

// handle button clicks
flexGrid.addEventListener(flexGrid.hostElement, 'click', function (e) {
    var ht = flexGrid.hitTest(e);
    if (ht.panel == flexGrid.rowHeaders) {
        //
        // prepare form
        var item = flexGrid.rows[ht.row].dataItem;
        formControls.productCode.textContent = `${item.productCode} (${item.name})`;
        formControls.quantity.value = item.quantity;
        formControls.unitPrice.value = item.unitPrice;
        formControls.date.value = item.date;
        formControls.popup.show(true, function (e) {
            if (e.dialogResult == 'wj-hide-ok') {
                //
                // commit changes if the user pressed the OK button
                flexGrid.collectionView.editItem(item);
                item.quantity = formControls.quantity.value;
                item.unitPrice = formControls.unitPrice.value;
                item.date = formControls.date.value;
                flexGrid.collectionView.commitEdit();
            }
            //
            // return focus to the grid
            flexGrid.focus();
        });
    }
});

この動作については「ポップアップエディタ」のデモでも確認できるので、こちらもご覧ください。

今回の部品表のデモでは、上記のポップアップエディタのデモで紹介している動作に加え、ポップアップのタイトルの調整(※1)やInputNumberで数量のstep調整(※2)、単価部分に書式を設定する(※3)などの処理を追加し、より視覚的にわかりやすいポップアップエディタにしています。

formControls.productCode.textContent = `${item.productCode} (${item.name})`; //※1
 
・・・(中略)
 
var formControls = {
    popup: new Popup('#popup'),
        productCode: document.getElementById('productCode'),
        quantity: new InputNumber('#quantity', { min: 0, step: 10 }), //※2
        date: new InputDate('#date'),
        unitPrice: new InputNumber('#unitPrice', { min: 0, format: 'c0' }), //※3

FlexGrid編

部品表らしいヘッダーを再現するため、列ヘッダーに対して行の追加とヘッダーセルの編集を行っています。加えて、2行分で表示する必要のないセルを持つ列(IDや日付など)についてはallowMergingプロパティを利用して、列ヘッダーセルをマージしています。

allowMergingプロパティで列ヘッダーセルをマージ
function setHeader() {
    var extraRow = new Row();
    extraRow.allowMerging = true;
    // 行を一行追加
    var panel = flexGrid.columnHeaders;
    panel.rows.splice(0, 0, extraRow);
   
    for (let colIndex = 1; colIndex <= 5; colIndex++) {
        //商品情報列部分
        panel.setCellData(0, colIndex, '商品情報');
    }
    for (let colIndex = 6; colIndex <= 7; colIndex++) {
        //サプライヤ情報部分
        panel.setCellData(0, colIndex, 'サプライヤ');
    }
    //2行分の列ヘッダーセルはマージする
    ['id', 'date', 'shipdate', 'others'].forEach(function (binding) {
        let col = flexGrid.getColumn(binding);
        col.allowMerging = true;
        panel.setCellData(0, col.index, col.header);
    });
}

また、列のcssClass/cssClassAllプロパティをそれぞれ利用することでデータセルおよびヘッダーセルの背景色を変更しています。

cssClass/cssClassAllプロパティでデータセルおよびヘッダーセルの背景色を変更
const flexGrid = new FlexGrid('#theGrid', {
    ・・・
    columns: [
        { binding: 'id', header: 'ID', visible: false, cssClass: 'idcol' },
        { binding: 'productCode', header: 'コード', cssClassAll: 'product' },
        { binding: 'name', header: '名称', cssClassAll: 'product' },
        ・・・
    ],

FlexGridSearch編

FlexGridSearchを使用することでFlexGrid内のデータを検索できるようになります。gridプロパティに対象となるFlexGridのインスタンスを設定します。

new FlexGridSearch('#theSearch', {
    placeholder: '検索',
    grid: flexGrid
});

上記のコードでは部分一致検索となりますが、以下のコードを加えることで完全一致検索に設定することも可能です。

new FlexGridSearch('#theSearch', {
    placeholder: '検索',
    grid: flexGrid,
    exactMatch: true
});

FlexGridXlsxConverter編

FlexGridXlsxConverterを利用して、FlexGrid上のデータをExcelに出力できます。includeColumnHeadersオプションを使用することで、列ヘッダーを含めて出力することができます。

document.getElementById('saveXlsx').addEventListener('click', () => {
    wjGridXlsx.FlexGridXlsxConverter.saveAsync(flexGrid, {
        includeColumnHeaders: document.querySelector('#exportIncludeColumnHeader').checked,
    }, 'FlexGrid.xlsx');
});

FlexGridSearchでフィルタリングしたデータのみを出力することもできます。

さいごに

今回はWijmoの各種コントロールを使用した「BOM(部品表)」デモの各種機能の実装のポイントを解説しました。製品サイトでは今回ご紹介したデモアプリケーションをブラウザ上で手軽にお試し可能で、加えてソースコード付きでダウンロードも可能です。さらに、BOM(部品表)のデモは今回ご紹介したものを含めて計3種あるので、他のデモも含めて是非チェックしてみてください

そのほか、製品サイトでは、Wijmoのトライアル版も公開しておりますので、こちらもご確認ください。

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

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