kintoneの詳細画面にkintoneライクなUIを使った印刷ボタンを置いてみた

まだまだ「最後は紙に印刷（あるいはPDFに）したい」という要望を無視できないので、標準のkintoneの詳細画面から何故か隠されている印刷メニューを、kintoneライクなUIを使える[「kintone UI Component」](https://developer.cybozu.io/hc/ja/articles/360000511023)を使って主役に抜擢してみるサンプルです。

# 画面イメージ

<img width="1194" alt="スクリーンショット 2018-10-06 4.52.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/214523/9c1ba347-fe06-429b-1232-8875a43a53ef.png">

# サンプルコード

```javascript

(function() {
    'use strict';
    kintone.events.on('app.record.detail.show', function(event) {
        new kintone.Promise(function(resolve, reject) {
            let button = new kintoneUIComponent.Button({text: '印刷'});
            let elPrintButton = kintone.app.record.getSpaceElement('printButton');
            elPrintButton.appendChild(button.render());
            resolve(button);
            return;
        })
        .then(function (UiButton) {
            let url = kintone.api.url('/k/v1/records', true);
            let reg = /http(s)?:\/\/([\w-]+\.)+([\w-]+)+\/([\w-]+)\/([\w-]+)\/([\d]+)/;
            console.log(url.match(reg));
            if (url.search('guest') !== -1) {
                console.log(url.match(reg));
            } else {
                reg = /http(s)?:\/\/([\w-]+\.)+([\w-]+)+\/([\w-]+)/;
                console.log(url.match(reg));
            }
            let appId = kintone.app.getId();
            console.log(appId);
            let body = {'id': appId};
            kintone.api(kintone.api.url('/k/v1/app', true), 'GET', body, function(resp) {
                // success
                console.log(resp);
                let printURL = url.match(reg)[0] + '/' + resp.appId + '/print?record=' + event.recordId;
                console.log(printURL);
                UiButton.on('click', function(event) {
                    window.open(printURL, null);
                });
            });
        });
    });
})();

```

#サンプルアプリの準備

お気に入りのアプリを[アプリストア](https://kintone-sol.cybozu.co.jp/apps/)からインストールします。今回は[交通費申請](https://kintone-sol.cybozu.co.jp/apps/027-kotsuhi.html)アプリを使っています。（アイコンが可愛いので結構お気に入り♪）

###フォームにスペースを追加
どこでも良いのですが、スペースを追加します。
サンプルコードの通りに使う場合は、フィールドコードを printButton とします。
<img width="853" alt="スクリーンショット 2018-10-06 5.14.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/214523/840dfec6-34fb-e1dd-7bfb-6aa92a2a8e08.png">

###JavaScriptファイルとCSSファイルをアップロード
<img width="564" alt="スクリーンショット 2018-10-06 5.17.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/214523/2fee540e-7333-a66c-f12c-12c3ffa7d71f.png">
サンプルコードと[「kintone UI Component」](https://developer.cybozu.io/hc/ja/articles/360000511023)をアップロードして保存します。

#サンプルコードの説明
処理の流れは次の通り

1.印刷ボタンを設置
2.印刷ページのURLを生成

###何やってるか？
`let button = new kintoneUIComponent.Button({text: '印刷'});`
[「kintone UI Component」](https://developer.cybozu.io/hc/ja/articles/360000511023)でボタンを生成

`elPrintButton.appendChild(button.render());`
JavaScript（以下JS）でボタンの要素をスペースフィールドに追加

`resolve(button);`
成功時のPromiseコールバック変数にボタンオブジェクトをセットして、印刷用のURL生成コードに渡します。

`let url = kintone.api.url('/k/v1/records', true);`
[kintone JavaScript API（以下KJS）でURLを取得します](https://developer.cybozu.io/hc/ja/articles/202166310#step3)

`let reg = /http(s)?:\/\/([\w-]+\.)+([\w-]+)+\/([\w-]+)/`
JSでURLを切り出す為に正規表現を設定します。URLがおかしい場合はこちらのコードを修正してみてください。正規表現のデバックには[Rubular](http://rubular.com/)が便利です。

```javascript

UiButton.on('click', function(event) {
    window.open(printURL, null);
});
```
ボタンオブジェクトのclickイベントのコールバック関数に生成した印刷画面遷移用のURLを仕込んでおきます。コールバックに仕込んでおくことで、印刷ボタンが押された時のclickイベントで処理が発火します。

※サンプルコードには動作確認の為、デバッグコードを残してあります。

#注意点
- [「kintone UI Component」](https://developer.cybozu.io/hc/ja/articles/360000511023)を利用する前提なので、[GitHub](https://github.com/kintone/kintone-ui-component)からJSとCSSをダウンロードして、そのファイルをアップロードしてください。
- kintoneのJavaScriptイベント[app.record.detail.show](https://developer.cybozu.io/hc/ja/articles/201941974#step1)ではeventをreturnしないでください。理由は[こちら](https://developer.cybozu.io/hc/ja/community/posts/115000032826)をご覧ください。

#必要スキル
- [cybozu developer network](https://developer.cybozu.io/hc/ja) のサンプルコードを自分で設置できる
- JavaScriptのコードを[デバッグ](https://developer.cybozu.io/hc/ja/articles/207613916)できる。

# ヘッダーメニューにボタンを置く場合
下記のコードに差し替えてください。

```javascript
        new kintone.Promise(function(resolve, reject) {
            let button = new kintoneUIComponent.Button({text: '印刷'});
            kintone.app.record.getHeaderMenuSpaceElement().appendChild(button.render());
            resolve(button);
            return;
        })
```