Wijmo

FlexGrid入門

このページでは、WijmoのFlexGridコントロールを使い始める方法を示します。

はじめに

FlexGridをJavaScriptアプリケーションで使用する手順は以下のとおりです。

  1. Wijmoへの参照を追加します。
  2. Wijmoコントロールのホストとして機能するマークアップを追加します。
  3. JavaScriptを使用してWijmoコントロールを初期化します。
  4. (オプション)FlexGridコントロールの外観をカスタマイズするためのCSSを追加します。

これはFlexGridの自動列生成、列ソート、編集、クリップボードのサポートが含まれるデフォルト動作を作成します。

HTML
<div id="gsFlexGrid"></div>
JS
new wijmo.grid.FlexGrid('#gsFlexGrid', { itemsSource: data.getData(100) });
CSS
/* set default grid height and some shadow */ .wj-flexgrid { background-color: #fff; box-shadow: 4px 4px 10px 0 rgba(50, 50, 50, 0.75); height: 300px; margin-bottom: 12px; }

結果(ライブ):

列定義

「はじめに」の例では列を定義していなかったため、FlexGridが自動的に列を生成しました。

この例は、FlexGridのコンストラクタのoptionsパラメータを使用して列を定義する方法、またはグリッドのcolumnsコレクションに項目を追加する方法を示しています。

列を指定すると、表示する列とその順序を設定できます。 また、各列の幅、見出し、書式設定、配置などのプロパティも制御できます。

このケースでは、スターサイズ指定を使用して[Country]列の幅を設定しています。 これにより、[Country]列が拡張されてグリッドの使用可能な幅が満たされるため、空スペースがなくなります。 [Revenue]列ではformatプロパティが"n0"に設定されており、この列の数値が桁区切り文字付き、小数点なしになっています。

HTML
<b>コンストラクタのオプション</b> <div id="cdInitMethod"></div> <b>列のコレクション</b> <div id="cdColsCollection"></div>
JS
// initialize a grid using an 'options' object new wijmo.grid.FlexGrid('#cdInitMethod', { autoGenerateColumns: false, columns: [ { header: 'Country', binding: 'country', width: '*' }, { header: 'Date', binding: 'date' }, { header: 'Revenue', binding: 'amount', format: 'n0' }, { header: 'Active', binding: 'active' }, ], itemsSource: data.getData(100) }); // initialize a second grid by setting properties var fgColsCollection = new wijmo.grid.FlexGrid('#cdColsCollection'); fgColsCollection.autoGenerateColumns = false; fgColsCollection.itemsSource = data.getData(100); // add columns one by one var c = new wijmo.grid.Column(); c.binding = 'country'; c.header = 'Country'; c.width = '*'; fgColsCollection.columns.push(c); c = new wijmo.grid.Column(); c.binding = 'date'; c.header = 'Date'; fgColsCollection.columns.push(c); c = new wijmo.grid.Column(); c.binding = 'amount'; c.header = 'Revenue'; c.format = 'n0'; fgColsCollection.columns.push(c); c = new wijmo.grid.Column(); c.binding = 'active'; c.header = 'Active'; fgColsCollection.columns.push(c);

結果(ライブ):

コンストラクタのオプション
列のコレクション

選択モード

デフォルトでは、FlexGridではExcelと同様にマウスまたはキーボードを使用してセルの範囲を選択できます。 selectionModeプロパティを使用してこのデフォルトの動作を変更し、行、行の範囲、隣接していない行(リストボックスと同様)、または単一セルを選択できるようにするか、あるいはまったく選択できないようにするかを指定できます。

この例では、Wijmo MenuコントロールからselectionModeを選択できます。

HTML
<div id="smFlexGrid"></div> <select id="smMenu"> <option value="None">None</option> <option value="Cell">Cell</option> <option value="CellRange" selected>CellRange</option> <option value="Row">Row</option> <option value="RowRange">RowRange</option> <option value="ListBox">ListBox</option> </select>
JS
var smFlexGrid= new wijmo.grid.FlexGrid('#smFlexGrid', { itemsSource: data.getData(100) }); var smMenu = new wijmo.input.Menu('#smMenu', { itemClicked: function (s) { smFlexGrid.selectionMode = s.selectedValue; udpateMenuHeader(s, '選択モード'); } }); udpateMenuHeader(smMenu, '選択モード');

結果(ライブ):

行列固定

FlexGrid はExcelのようにスクロール時に行列を固定することができます。 固定されているセルは通常セルと同様に選択や編集をすることができます。

このサンプルでは最初の2行と列が固定されています。

HTML
<div id="fzFlexGrid"></div> <button id="btnFreeze" class="btn btn-default"> Unfreeze </button>
JS
var fzFlexGrid = new wijmo.grid.FlexGrid('#fzFlexGrid', { itemsSource: data.getData(100), frozenRows: 2, frozenColumns: 2 }); document.getElementById('btnFreeze').addEventListener('click', function (e) { if (fzFlexGrid.frozenRows) { fzFlexGrid.frozenRows = 0; fzFlexGrid.frozenColumns = 0; e.target.textContent = '列固定設定'; } else { fzFlexGrid.frozenRows = 2; fzFlexGrid.frozenColumns = 2; e.target.textContent = '列固定解除'; } });
CSS
/* frozen cells and frozen boundaries */ .wj-flexgrid .wj-cell.wj-frozen:not(.wj-header):not(.wj-group):not(.wj-state-selected):not(.wj-state-multi-selected) { background-color: #f8ffd6; } .wj-flexgrid .wj-cell.wj-frozen-row { border-bottom: 1px solid blue; } .wj-flexgrid .wj-cell.wj-frozen-col { border-right: 2px solid red; }

結果(ライブ):

編集

FlexGridは、Excelに似た迅速なセル内編集を組み込みでサポートしています。 表示モードと編集モードを切り替える[編集]ボタンを含む列を追加する必要はありません。

ユーザーはセルに文字を入力することによって編集を開始できます。 この場合、セルはクイック編集モードになります。 このモードでは、方向キーを押すと編集が終了し、選択が別のセルに移動します。

また、[F2]を押すかセルをダブルクリックすることによって編集を開始することもできます。 この場合、セルはフル編集モードになります。 このモードでは、方向キーを押すとセルテキスト内でキャレットが移動します。 編集を終了して別のセルに移動するためには、[Enter]、[Tab]、[Esc]のいずれかのキーを押す必要があります。

編集を終了するとき、データは適切な型に自動的に型変換されます。 ユーザーが無効なデータを入力した場合、編集はキャンセルされ、元のデータに戻ります。

グリッド、列、または行レベルで編集を無効にするには、グリッド、列、または行オブジェクトのisReadOnlyプロパティを使用します。 この例では、[ID]列が読み取り専用になっています。

HTML
<div id="eFlexGrid"></div>
JS
new wijmo.grid.FlexGrid('#eFlexGrid', { autoGenerateColumns: false, columns: [ { header: 'ID', binding: 'id', width: '*', isReadOnly: true }, // cannot edit { header: 'Country', binding: 'country' }, { header: 'Date', binding: 'date' }, { header: 'Revenue', binding: 'amount', format: 'n0' }, { header: 'Active', binding: 'active' }, ], itemsSource: data.getData(100) });

結果(ライブ):

グループ化

FlexGridは、ICollectionViewインタフェース(これは.NETのICollectionViewインタフェースと同一です)によってグループ化をサポートします。 グループ化を有効にするには、1つ以上のGroupDescriptionオブジェクトをCollectionView.groupDescriptionsプロパティに追加し、グリッドのshowGroupsプロパティをtrue(デフォルト値)に設定します。

GroupDescriptionオブジェクトは柔軟性が高く、値またはグループ化関数に基づいてデータをグループ化できます。 この例では、日付(年別)、金額(5,000超、500~5,000、500未満の3つの範囲別)、およびその他の項目(値別)でグループ化できます。 メニューを使用して各グループ化の効果を確認してください。

[Revenue]列にはグループ行の合計が表示されます。 このようにするには、列のaggregateプロパティを"Sum"に設定します。 列の値を編集すると、集計は自動的に更新されます。

HTML
<div id="gFlexGrid"></div> <select id="gMenu"> <option value="" selected>(グループ化なし)</option> <option value="country">Country</option> <option value="amount">Revenue</option> <option value="date">Date</option> <option value="country,date">Country、Date</option> <option value="country,amount">Country、Revenue</option> <option value="country,date,amount">Country、Date、Revenue</option> </select>
JS
var gFlexGrid = new wijmo.grid.FlexGrid('#gFlexGrid', { autoGenerateColumns: false, columns: [ { header: 'Country', binding: 'country', width: '*' }, { header: 'Date', binding: 'date' }, { header: 'Revenue', binding: 'amount', format: 'n0' } ], itemsSource: data.getData(100) }); var gMenu = new wijmo.input.Menu('#gMenu', { itemClicked: function (sender) { // clear any current groups var gds = gFlexGrid.collectionView.groupDescriptions; gds.clear(); // add new group var groupBy = sender.selectedValue; if (groupBy) { var groupNames = groupBy.split(','); for (var i = 0; i < groupNames.length; i++) { var groupName = groupNames[i]; if (groupName == 'date') { // group dates by year var groupDesc = new wijmo.collections.PropertyGroupDescription(groupName, function (item, prop) { return item.date.getFullYear(); }); gds.push(groupDesc); } else if (groupName == 'amount') { // group amounts in ranges var groupDesc = new wijmo.collections.PropertyGroupDescription(groupName, function (item, prop) { return item.amount >= 5000 ? '> 5,000' : item.amount >= 500 ? '500 to 5,000' : '< 500'; }); gds.push(groupDesc); } else { // group everything else by value var groupDesc = new wijmo.collections.PropertyGroupDescription(groupName); gds.push(groupDesc); } } } udpateMenuHeader(s, 'グループ化'); } }); udpateMenuHeader(gMenu, 'グループ化');

結果(ライブ):

フィルタリング

FlexGridは、ICollectionViewインタフェース(これは.NETのICollectionViewインタフェースと同一です)によってフィルタリングをサポートします。 フィルタリングを有効にするには、ビューに含めるオブジェクトを決定する関数をCollectionView.filterプロパティに設定します。

この例では、国のフィルタを作成し、入力コントロールからフィルタ値を取得します。

HTML
<div id="fFlexGrid"></div> <div class="input-group"> <span class="input-group-addon"> <i class="glyphicon glyphicon-filter"></i> </span> <input id="fFilter" type="text" class="form-control" placeholder="国のフィルタ" /> </div>
JS
var fFlexGrid = new wijmo.grid.FlexGrid('#fFlexGrid', { itemsSource: data.getData(100) }); // apply a filter to the grid's CollectionView var filterText = ''; fFlexGrid.collectionView.filter = function (item) { return filterText ? item.country.toLowerCase().indexOf(filterText) > -1 : true; } // refresh filter when text changes document.getElementById('fFilter').addEventListener('input', function (e) { filterText = e.target.value.toLowerCase(); fFlexGrid.collectionView.refresh(); });

結果(ライブ):

ページング

FlexGridは、IPagedCollectionViewインタフェース(これは.NETのIPagedCollectionViewインタフェースと同一です)によってページングをサポートします。 ページングを有効にするには、各ページに表示する項目数をIPagedCollectionView.pageSizeプロパティに設定し、ページを移動するためのUIを提供します。

この例では、JavaScriptを使用して1ページに10項目を表示しています。 ナビゲーションボタンが用意されており、ボタンをクリックするとIPagedCollectionViewメソッドが呼び出されます。 また、pageIndexプロパティとpageCountプロパティを使用して現在のページと総ページ数を表示しています。

HTML
<div id="pFlexGrid" style="height:auto"></div> <div class="btn-group" id="pPager"> <button id="btnPageFirst" class="btn btn-default"> <span class="glyphicon glyphicon-fast-backward"></span> </button> <button id="btnPagePrev" class="btn btn-default"> <span class="glyphicon glyphicon-step-backward"></span> </button> <button id="btnPageCurrent" class="btn btn-default" disabled style="width:100px"></button> <button id="btnPageNext" class="btn btn-default"> <span class="glyphicon glyphicon-step-forward"></span> </button> <button id="btnPageLast" class="btn btn-default"> <span class="glyphicon glyphicon-fast-forward"></span> </button> </div>
JS
var pFlexGrid = new wijmo.grid.FlexGrid('#pFlexGrid', { itemsSource: data.getData(100) }); // set page size to 10 var cvPaged = pFlexGrid.collectionView; cvPaged.pageSize = 10; cvPaged.pageChanged.addHandler(function () { updatePager(cvPaged); }); updatePager(cvPaged); // handle pager buttons onClick('btnPageFirst', function () { cvPaged.moveToFirstPage(); }); onClick('btnPagePrev', function () { cvPaged.moveToPreviousPage(); }); onClick('btnPageNext', function () { cvPaged.moveToNextPage(); }); onClick('btnPageLast', function () { cvPaged.moveToLastPage(); }); // disable/enable buttons and update display text for pager function updatePager(cv) { var firstPage = cv.pageIndex <= 0; disable('btnPageFirst', firstPage); disable('btnPagePrev', firstPage); var lastPage = cv.pageIndex >= cv.pageCount - 1; disable('btnPageNext', lastPage); disable('btnPageLast', lastPage); setText('btnPageCurrent', (cv.pageIndex + 1) + ' / ' + (cv.pageCount)); }

結果(ライブ):

マスター/詳細

ICollectionViewインタフェースはカレンシー(現在の項目)を組み込みでサポートしているため、FlexGridでマスター/詳細シナリオを実装できます。 currentItemを参照し、それをページの要素のバインディングソースとして使用できます。

現在のアイテムが変更されたときに、詳細ビューを更新する必要があることに注意してください。 そのためには、ハンドラーをICollectionView.currentChangedイベントにアタッチし、必要に応じて詳細ビューを更新します。

HTML
<div id="mdFlexGrid"></div> <dl class="dl-horizontal"> <dt>ID</dt> <dd id="mdCurId"></dd> <dt>Country</dt> <dd id="mdCurCountry"></dd> <dt>Date</dt> <dd id="mdCurDate"></dd> <dt>Revenue</dt> <dd id="mdCurRevenue"></dd> <dt>Active</dt> <dd id="mdCurActive"></dd> </dl>
JS
var mdFlexGrid = new wijmo.grid.FlexGrid('#mdFlexGrid', { selectionMode: 'Row', itemsSource: data.getData(100) }); // update detail pane now and when the current item changes updateDetails(); mdFlexGrid.collectionView.currentChanged.addHandler(updateDetails); // update the details when the CollectionView's currentItem changes function updateDetails() { var cv = mdFlexGrid.collectionView, item = cv.currentItem; setText('mdCurId', item.id); setText('mdCurCountry', item.country); setText('mdCurDate', wijmo.Globalize.format(item.date, 'd')); setText('mdCurRevenue', wijmo.Globalize.format(item.amount, 'c')); setText('mdCurActive', item.active); }

結果(ライブ):

ID
Country
Date
Revenue
Active

条件付きスタイル設定

FlexGridでは、formatItemイベントを使用してセルの内容を完全に制御できます。

この例では、'amount'列のセルの色を変更してセル値を反映するハンドラーをformatItemイベントに追加しています。 小さい数字は赤で表示され、大きい数字は緑で表示されます。

HTML
<div id="csFlexGrid"></div>
JS
new wijmo.grid.FlexGrid('#csFlexGrid', { autoGenerateColumns: false, columns: [ { header: 'Country', binding: 'country', width: '*', isContentHtml: true, isReadOnly: true }, { header: 'Date', binding: 'date' }, { header: 'Revenue', binding: 'amount', format: 'n0' }, { header: 'Active', binding: 'active' }, ], formatItem: function (s, e) { // we are only interested in regular (scrollable) cells if (e.panel == s.cells) { // compute the cell color (for all columns, since cells may be recycled) var color = ''; if (s.columns[e.col].binding == 'amount') { var amount = e.panel.getCellData(e.row, e.col); color = amount < 500 ? 'red' : amount < 2500 ? 'black' : 'green'; } // always set the color e.cell.style.color = color; } }, itemsSource: data.getData(100) });

結果(ライブ):

テーマ

FlexGridの外観はCSSで定義されます。 デフォルトテーマに加えてプロフェッショナルなデザインのテーマが多数用意されており、すべてのWijmoコントロールの外観をカスタマイズして一貫性のある魅力的な見た目を提供できます。

グリッドの外観はCSSを使用してカスタマイズできます。 そのためには、デフォルトテーマから新しいCSSファイルにCSSルールをコピーし、必要なスタイル属性を変更します。

この例では、"custom-flex-grid"クラスをグリッド要素に追加し、"custom-flex-grid"クラスを持つグリッド用に白黒および罫線なしのシンプルなテーマを作成するCSSルールを定義しています。

HTML
<div id="tFlexGrid" class="custom-flex-grid"></div>
JS
new wijmo.grid.FlexGrid('#tFlexGrid', { itemsSource: data.getData(100) });
CSS
/* 'custom-flex-grid' theme for the FlexGrid */ .custom-flex-grid .wj-header.wj-cell { color: #fff; background-color: #000; border-bottom: solid 1px #404040; border-right: solid 1px #404040; font-weight: bold; } .custom-flex-grid .wj-cell { background-color: #fff; border: none; } .custom-flex-grid .wj-alt:not(.wj-state-selected):not(.wj-state-multi-selected) { background-color: #fff; } .custom-flex-grid .wj-state-selected { background: #000; color: #fff; } .custom-flex-grid .wj-state-multi-selected { background: #222; color: #fff; }

結果(ライブ):

ツリーと階層データ

グループ化に加えて、FlexGridは階層データ(サブ項目のリストを持つ項目で構成されたデータ)もサポートします。 この種の階層構造は非常に一般的で、通常はツリー表示コントロールで表示されます。

FlexGridで階層データソースを使用するには、子要素を含むデータ要素の名前をchildItemsPathプロパティに設定します。 グリッドがデータを自動的にスキャンしてツリーを構築します。

HTML
<div id="tvFlexGrid" class="custom-flex-grid"></div>
JS
new wijmo.grid.FlexGrid('#tvFlexGrid', { autoGenerateColumns: false, columns: [ { binding: 'name', width: '*' }, { binding: 'length', width: 80, align: 'center' } ], itemsSource: data.treeData, // hierarchical data childItemsPath: 'items', // set hierarchy path allowResizing: 'None', // disable resizing headersVisibility: 'None', // hide headers selectionMode: 'ListBox' // use ListBox selection });
CSS
/* 'custom-flex-grid' theme for the FlexGrid */ .custom-flex-grid .wj-header.wj-cell { color: #fff; background-color: #000; border-bottom: solid 1px #404040; border-right: solid 1px #404040; font-weight: bold; } .custom-flex-grid .wj-cell { background-color: #fff; border: none; } .custom-flex-grid .wj-alt:not(.wj-state-selected):not(.wj-state-multi-selected) { background-color: #fff; } .custom-flex-grid .wj-state-selected { background: #000; color: #fff; } .custom-flex-grid .wj-state-multi-selected { background: #222; color: #fff; }

結果(ライブ):

null値の扱い

デフォルトでは、FlexGridは文字列型の列に空文字を入力することができ、他の列型では空文字やnull値を許容しません。

isRequiredプロパティをグリッドの列に設定することでこの動作を変更することができます。 isRequiredプロパティをfalseに設定すると、列型に関わらず空文字の入力を許容することができます。 逆にtrueに設定すると、文字列型であっても空文字の入力を許容しません。

isRequiredにnullを設定すると、デフォルト動作(文字列型のみ空文字の入力を許容する)に戻ります。

グリッドは以下のデフォルト動作に戻します。 最初の列にisRequiredをtrueに設定し、他の列はfalseに設定します。 空文字を入力する、またはDeleteキーによってコンテンツを削除することができます。

HTML
<div id="nvGrid"></div>
JS
new wijmo.grid.FlexGrid('#nvGrid', { autoGenerateColumns: false, itemsSource: data.getData(100), columns: [ { header: 'Country', binding: 'country', width: '*', isRequired: true }, { header: 'Date', binding: 'date', isRequired: false }, { header: 'Revenue', binding: 'amount', format: 'n0', isRequired: false }, { header: 'Active', binding: 'active', isRequired: false } ] });

結果(ライブ):