【コラボフロー】編集履歴を残すJSカスタマイズ（テトリス申請編）

[コラボフロー Advent Calendar 2023](https://qiita.com/advent-calendar/2023/collaboflow) の23日目の記事です。
昨年のAdvent Calendarでは、[コラボフロー](https://www.collabo-style.co.jp/)でテトリス申請を作成しました。
今年はテトリス申請に機能を追加します！

https://qiita.com/tetrer/items/bcce00b910fafd14e636

結果の報告だけでなく、結果に至った経緯も大事、という場面ありますよね？
申請書に結果だけ記載しても、良し悪しの判断ができない、など。

テトリス申請でも判定時に申請者のプレイ状況を確認したい、
といったご要望の声が聞こえてきました（脳内で🤯）

ということで、JavaScriptカスタマイズで「**リプレイ機能**」を追加してみます！！

# DEMO
リプレイ機能の完成イメージです。
プレイ後や判定/閲覧画面でクリックできる「▶️ REPLAY」ボタンを配置しました。
このボタンをクリックすると、ゲームオーバーになる状況が再生されます。

![ac2023-3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953201/e9af7ecf-7867-acb7-21af-152f4632a6ac.gif)
（リーゼント風？？）

それでは主な改修内容を紹介していきます。

# 【1】 Excelで申請書レイアウトや配色を変更

今年は緑を基調にしてみました:christmas_tree:
昨年と同じ説明ですが、申請書のレイアウトをExcelで作成しているので、
Excelで編集してアップロードするだけで、簡単に画面デザインを変えられます :heart_eyes:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953201/a7a66754-378f-0ade-bc29-7d405ebe7604.png)

（参考：[Excelフォームを作成する](https://collaboflow.zendesk.com/hc/ja/articles/360000415915)）

# 【2】 ラベルパーツにボタンを配置

「▶️ REPLAY」ボタンを、ラベルパーツで配置しました。
[ラベルパーツ](https://collaboflow.zendesk.com/hc/ja/articles/360000382956)は、HTMLタグが使えるので密かに便利なパーツです！

申請書に画像をimgタグで埋め込んだり、入力ガイドなどへのリンクを
aタグで付けたり、JavaScript無しでも申請書に追加できるんです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953201/ad6dc7b0-5714-3332-bd6b-17317ab528d3.png)

# 【3】 非表示パーツで履歴管理

リプレイ用のブロック位置情報を、非表示パーツに登録しました。
[テキスト（一行）パーツ](https://collaboflow.zendesk.com/hc/ja/articles/360000389075)は、見せたくない値を非表示にして隠すことができます。


以下はパーツを非表示にせず、位置情報の履歴をセットしていくイメージです。
![ac2023-history.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953201/cbbb5c21-0c62-4afe-d698-f7149a17d1af.gif)

```js
parts.tbl_1.value[0].fidHistory.value = JSON.stringify(histories)
```

`JSON.stringify()`で構造体を、JSON形式の文字列にしてパーツへセットできます！
（参考：[パーツのデータと状態の操作 - valueプロパティへの値設定](https://collaboflow.zendesk.com/hc/ja/articles/360000266835)）

テキスト（一行）パーツに登録できる値は最大999文字ですが、
今回は数値配列の位置情報だけなのでJSON形式でも問題なく収まりました。
パーツに値を登録することで、判定/閲覧画面でもデータを取得できるようになります。


一つ注意点として、この値を判定画面のJavaScriptカスタマイズで取得した際は
「"（ダブルクォーテーション）」が「`&quot;`」という文字に変換されていました:disappointed_relieved:
ですが以下のような置換処理を入れることで、構造体のオブジェクトに戻せました。
```js
var historyValue = parts.tbl_1.value[0].fidHistory.value;
historyValue = historyValue.replaceAll('&quot;', '"');
const histories = JSON.parse(historyValue);
```



# 【4】 ボタンのクリックイベント

idを付けておいた「▶️ REPLAY」ボタンに、クリックイベントを設定しました。

```js
setReplayButton() {
    if (!this._replayButtonId) {
        return;
    }

    this.replayButton = document.querySelector(`#${this._replayButtonId}`);
    this.replayButton.disabled = false;
    this.replayButton.addEventListener('click', (event) => {
        event.preventDefault();
        this.replay();
    });
}
```

`event.preventDefault();`で、入力フォームがsubmitされないようにしています。

```js
async replay() {
    const delay = 500;

    for (let rowIndex = 1; rowIndex <= this.rowLength; rowIndex++) {
        // ブロックの表示を書き換える処理
        // （省略）

        await this.wait(delay);
    }
}

async wait(delay) {
    await new Promise(resolve => setTimeout(resolve, delay));
}
```

リプレイ処理では、非表示パーツに登録したブロック位置情報をもとに、
プレイ画面用のテキストパーツの値を順に書き換えていきます。
`wait()`処理で間を開けて更新することで、アニメーションっぽく表現できました🎉

# おわりに

結果には原因がある、を意識してみましたがいかがでしょうか。

以下リンクからzip形式のフォームと経路の情報をダウンロードし、
コラボフローでインポートするとテトリス風の申請書を利用できます♪
（追記：アレンジを加えたバージョンに差し替えました）

1. [ [テトリス風申請](https://app.box.com/s/8vs5xpa4ophvsv949594bbd38tye5i7v) ]のフォームと経路のzipファイルをダウンロードする
2. [フォームをインポートする](https://collaboflow.zendesk.com/hc/ja/articles/115001410550)
3. [経路をインポートする](https://collaboflow.zendesk.com/hc/ja/articles/360000383276)

因みに、テトリスのブロックを積んで描く絵は「[テトリスアート](https://www.google.com/search?q=%E3%83%86%E3%83%88%E3%83%AA%E3%82%B9%E3%82%A2%E3%83%BC%E3%83%88)」と呼ばれますが、
上の[DEMO](#demo)画面内の横顔2つは**チート**で作りました:boom:
リプレイされるシーンが少ないから、ごまかせる...🫠