Web上でExcelライクなエディタ「Handsontable」

# Web上でExcelライクなエディタ「Handsontable」
## 概要
　「Handsontable」はWebアプリケーション上でExcelライクなエディタを実現するjQueryプラグイン。
　WEBページにプラグインに適用するだけでリッチなUIが可能になります。

## どんなとき使う？
Handsontableは例えば下記に挙げたような用途に利用できる。しかし、ユーザ次第でこれ以外にも様々な用途に応用可能です。

- データベース編集
- 設定管理
- データ統合
- 人員管理
- 売上報告
- 財務分析

(引用元: https://docs.handsontable.com/pro/1.13.0/tutorial-introduction.html)

## こんなの
為替の一覧
![画像01.png](https://qiita-image-store.s3.amazonaws.com/0/190792/a482591a-fc40-f63d-e2ea-d2bb98418e41.png)

日付編集時はコーディングなしでカレンダーが表示可能
![画像2.png](https://qiita-image-store.s3.amazonaws.com/0/190792/a04ac720-5443-9dff-de4a-bc4a8d4adb65.png)


# 導入まで
ハンズオンテーブルの導入には１．プラグインの入手、２．HTMLにデータの定義と表の表示をコーディング、３．ブラウザから表示となります。

## 準備するもの

入手方法
Handsontable公式ホームページ
https://handsontable.com/

無償版
https://github.com/handsontable

マニュアル（英語） 0.34.0版
https://docs.handsontable.com/0.34.0/tutorial-introduction.html?_ga=2.174165218.1147910324.1503039446-133538248.1503039446

GitHubより入手できる以下の資産を使用する
handsontable.full.min.js
handsontable.full.min.css

## 実装　
```
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="D:/sample/handsontable.full.min.css">
<script src="D:/sample/handsontable.full.min.js"></script>
</head>
<body>
<div id="hot"></div>

/* 表示データ定義 */
<script>
  var dataObject = [
    {id: 1, flag: 'EUR', currencyCode: 'EUR', currency: 'Euro',	level: 0.9033, units: 'EUR / USD', asOf: '08/19/2015', onedChng: 0.0026},
    {id: 2, flag: 'JPY', currencyCode: 'JPY', currency: 'Japanese Yen', level: 124.3870, units: 'JPY / USD', asOf: '08/19/2015', onedChng: 0.0001},
    {id: 3, flag: 'GBP', currencyCode: 'GBP', currency: 'Pound Sterling', level: 0.6396, units: 'GBP / USD', asOf: '08/19/2015', onedChng: 0.00},
    {id: 4, flag: 'CHF', currencyCode: 'CHF', currency: 'Swiss Franc',	level: 0.9775, units: 'CHF / USD', asOf: '08/19/2015', onedChng: 0.0008},
    {id: 5, flag: 'CAD', currencyCode: 'CAD', currency: 'Canadian Dollar',	level: 1.3097, units: 'CAD / USD', asOf: '08/19/2015', onedChng: -0.0005},
    {id: 6, flag: 'AUD', currencyCode: 'AUD', currency: 'Australian Dollar',	level: 1.3589, units: 'AUD / USD', asOf: '08/19/2015', onedChng: 0.0020},
    {id: 7, flag: 'NZD', currencyCode: 'NZD', currency: 'New Zealand Dollar',	level: 1.5218, units: 'NZD / USD', asOf: '08/19/2015', onedChng: -0.0036},
    {id: 8, flag: 'SEK', currencyCode: 'SEK', currency: 'Swedish Krona',	level: 8.5280, units: 'SEK / USD', asOf: '08/19/2015', onedChng: 0.0016},
    {id: 9, flag: 'NOK', currencyCode: 'NOK', currency: 'Norwegian Krone',	level: 8.2433, units: 'NOK / USD', asOf: '08/19/2015', onedChng: 0.0008},
    {id: 10, flag: 'BRL', currencyCode: 'BRL', currency: 'Brazilian Real',	level: 3.4806, units: 'BRL / USD', asOf: '08/19/2015', onedChng: -0.0009},
    {id: 11, flag: 'CNY', currencyCode: 'CNY', currency: 'Chinese Yuan',	level: 6.3961, units: 'CNY / USD', asOf: '08/19/2015', onedChng: 0.0004},
    {id: 12, flag: 'RUB', currencyCode: 'RUB', currency: 'Russian Rouble xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',	level: 65.5980, units: 'RUB / USD', asOf: '08/19/2015', onedChng: 0.0059},
    {id: 13, flag: 'INR', currencyCode: 'INR', currency: 'Indian Rupee',	level: 65.3724, units: 'INR / USD', asOf: '08/19/2015', onedChng: 0.0026},
    {id: 14, flag: 'TRY', currencyCode: 'TRY', currency: 'New Turkish Lira',	level: 2.8689, units: 'TRY / USD', asOf: '08/19/2015', onedChng: 0.0092},
    {id: 15, flag: 'THB', currencyCode: 'THB', currency: 'Thai Baht',	level: 35.5029, units: 'THB / USD', asOf: '08/19/2015', onedChng: 0.0044},
    {id: 16, flag: 'IDR', currencyCode: 'IDR', currency: 'Indonesian Rupiah',	level: 13.83, units: 'IDR / USD', asOf: '08/19/2015', onedChng: -0.0009},
    {id: 17, flag: 'MYR', currencyCode: 'MYR', currency: 'Malaysian Ringgit',	level: 4.0949, units: 'MYR / USD', asOf: '08/19/2015', onedChng: 0.0010},
    {id: 18, flag: 'MXN', currencyCode: 'MXN', currency: 'Mexican New Peso',	level: 16.4309, units: 'MXN / USD', asOf: '08/19/2015', onedChng: 0.0017},
    {id: 19, flag: 'ARS', currencyCode: 'ARS', currency: 'Argentinian Peso',	level: 9.2534, units: 'ARS / USD', asOf: '08/19/2015', onedChng: 0.0011},
    {id: 20, flag: 'DKK', currencyCode: 'DKK', currency: 'Danish Krone',	level: 6.7417, units: 'DKK / USD', asOf: '08/19/2015', onedChng: 0.0025},
    {id: 21, flag: 'ILS', currencyCode: 'ILS', currency: 'Israeli New Sheqel',	level: 3.8262, units: 'ILS / USD', asOf: '08/19/2015', onedChng: 0.0084},
    {id: 22, flag: 'PHP', currencyCode: 'PHP', currency: 'Philippine Peso',	level: 46.3108, units: 'PHP / USD', asOf: '08/19/2015', onedChng: 0.0012}
  ];
  var currencyCodes = ['EUR', 'JPY', 'GBP', 'CHF', 'CAD', 'AUD', 'NZD', 'SEK', 'NOK', 'BRL', 'CNY', 'RUB', 'INR', 'TRY', 'THB', 'IDR', 'MYR', 'MXN', 'ARS', 'DKK', 'ILS', 'PHP'];

  var hotElement = document.querySelector('#hot');
  var hotElementContainer = hotElement.parentNode;
　/* 表の定義情報 */
  var hotSettings = {
    data: dataObject,
    columns: [
        {
            data: 'id',
            type: 'numeric',
            width: 40
        },
        {
            data: 'currencyCode',
            type: 'text'
        },
        {
            data: 'currency',
            type: 'text',
            width: 40
        },
        {
            data: 'level',
            type: 'numeric',
            format: '0.0000'
        },
        {
            data: 'units',
            type: 'text'
        },
        {
            data: 'asOf',
            type: 'date',
            dateFormat: 'MM/DD/YYYY'
        },
        {
            data: 'onedChng',
            type: 'numeric',
            format: '0.00%'
        }
    ],
    stretchH: 'all',
    width: 806,
    autoWrapRow: true,
    height: 441,
    contextMenu: true,
    rowHeaders: true,
    colHeaders: [
        'ID',
        'Code',
        'Currency',
        'Level',
        'Units',
        'Date',
        'Change'
    ]
};

  var hot = new Handsontable(hotElement, hotSettings);
</script>
</body>
</html>
```

## TIPS
・表示内容が見切れないように折り返して表示させる場合、行の高さがデータごとに変わる。
　このとき、表の列が多く横スクロールが必要となる場合、表示している内容で行の高さが自動で変わり、
　どのデータにフォーカスが当たっているのか見分けがつかなくなってしまう。
　以下の設定を行うことで、行の高さが自動で変わる事象を解消することができる。

　autoRowSize: true

・バリデーションを組み込み、特定の条件を満たす値のみした許可しないようにすることができる。
　また、設定によって、条件を満たさない場合の値が入力された場合の挙動を変えることが可能。

　allowInvalid: true →　条件を満たさない値を入力した場合、セル色が赤くなる
　allowInvalid: false →　条件を満たす値が入力するまで、フォーカスが外れない

・Excelのように、行の固定、列の固定を行うことができる
　そのため、キーととなる情報の列は固定で常に表示した状態にすることができる。

・Chormeで「てすと」と入力しようとすると、「tえすと」となってしまうバグがある。
　※IEでは、問題なく「てすと」と入力することができる。

・値が変更されたとき、フォーカスが移動されたときなどのさまざまなイベントが発生した際に
　処理を組み込むことができる。

　処理を作りこむことで、Googleスプレッドシートのように同時編集を行えるような画面を
　作成することも可能。