アコーディオンウィジェットの動きを修正してみた

どうもこんばんは、みかんです。

**！！！！とつぜんですがたいせつなおしらせ！！！！**

2020年1月27日
App Maker の提供終了に向けた対応のご案内
https://support.google.com/a/answer/9682494?p=am_announcement&visit_id=637157414793613981-426262357&rd=1


??!???!?!?!???!?

残念ながら2021年1月19日には終了してしまうそうです(涙)
移行先はAppSheetかApp EngineかGoogleフォームだそうです・・・

消すのは忍びないので記事は残して置きますが、何かの間違いじゃ無い限り役に立つことはないでしょう・・・


**！！！！おしらせはおわりです！！！！！**

今回は「アコーディオンウィジェットの動きを修正してみた」という題で書いてみます。
下記ステップでやっていきます。

* 1 下準備
* 2 アコーディオンウィジェットの確認
* 3 レイアウトを確認する
* 4 詳細が開いている行をクリックしたら閉じるようにカスタマイズする

# 1 下準備

この記事と同様です。
[Material Galleryテンプレートを見てUIの引き出しを増やす](https://qiita.com/ExistMikan/items/cc1fd8b68b7b6f83303a)

Material Galleryテンプレートで説明します。
上の記事ではテンプレート自体の説明を入れているので、是非見ていただければと思います。

# 2 アコーディオンウィジェットの確認

Sticker Sheetページの、Project Cardsから更に下に進み、一番右の「Project Card Accordion」がアコーディオンウィジェットです。

|![gif001-compressor.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/34a0ac67-7fe7-fed5-205e-eee152890aeb.gif)|
|:-:|

リストの行をクリックすると、そのすぐ下に詳細情報が表示されるようになっています。
また、他の行をクリックすると、直前で開いていた詳細情報は閉じるようになっています。

# 3 レイアウトを確認する

エディタに戻って、レイアウトを確認してみましょう。

|![ap002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/e1e2a67f-5e90-1d10-5062-cd2343768db5.png)|
|:-:|

青枠で囲まれた部分がアコーディオンウィジェット本体です。
その下に、行となる**Panel: Accordion1Row**と、詳細情報となる**Panel: Accordion1Detail**がありますね。

アコーディオンウィジェットのプロパティを見てみます。

|![ap003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/c4c17a22-d5dd-2ed5-bf43-7c23f2bc2054.png)|
|:-:|

selectedRowという、選択されている行を合わすプロパティこそあるものの、このウィジェット専用のプロパティは見当たりません。。
シンプルなのは良いのですが、カスタマイズとかが難しいということになります。

# 4 詳細が開いている行をクリックしたら閉じるようにカスタマイズする

触っていて違和感を覚えたのですが、このアコーディオン、開いている詳細情報を閉じる方法がありません。

|![gif002-compressor.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/12c68c34-a71c-4d47-9eab-5d921f31def1.gif)|
|:-:|

普通開いたら閉じませんか？？？ 少なくとも私は閉じたい派です。

ということで、クリックした行の詳細情報が既に表示されていた場合は非表示にするというカスタマイズを行ってみます。

まずは、アウトラインで一番トップレベルのウィジェット(=ページ本体)をクリックし、「detailWidget」という名前、Dynamicという型でカスタムプロパティを用意します。また、次のステップで使うので「selectedIndex」という名前、「Number」という型でもプロパティをセットしておきます。

|![ap004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/f929db22-bbfc-d52c-23b7-a2a230099907.png)|![ap005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/d147e7d4-6745-03a3-7a13-77ed6767d54f.png)|
|:---:|:---:|

次に、詳細情報用のパネルウィジェットをクリックし、**onAttach**イベントに次のスクリプトを記述します。

|![ap006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/36a65de3-332e-5a6f-805a-7a97837dff9f.png)|
|:-:|

```javascript
widget.root.properties.detailWidget = widget;
```

このようにすると、この詳細情報用ウィジェットは、画面に表示(アタッチ)されたタイミングで常に画面のカスタムプロパティ「detailWidget」にセットされるようになるので、どこからでも参照できるようになります。
普通参照したいウィジェットがあれば、絶対参照や相対参照でいい感じに指定できるのがApp Makerの仕組みですが、アコーディオンウィジェットの詳細部分に関してはその手法だと問題があったので、このようなやり方にたどり着きました。

次に、処理の起点となる行を選択し、今度は**onClick**イベントに次のスクリプトを記述します。

|![ap007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/4f06c454-6d2f-9ceb-a5fc-bdec9d30bcc8.png)|
|:-:|

```javascript
var rootProps = widget.root.properties;

//現在選択されているアイテムの位置
var currentIndex = widget.parent.selectedIndex;

//前回選択したアイテムの位置
var oldIndex = rootProps.selectedIndex;

//同じ位置をクリックしている時はvisibleを反転させる。
if (currentIndex == oldIndex) {  
  rootProps.detailWidget.visible = !rootProps.detailWidget.visible;
} 
//位置が変わる時は次の判定用に位置を記録。
else {
  rootProps.selectedIndex = currentIndex;
}
```

一つ前にクリックした行のインデックスを覚えておくことで、クリックした時に前回と同じ行をクリックしているか否かがわかるようにしています。
同じ場所をクリックしていることがわかれば、その行に対応する詳細情報の「見える or 見えない」の設定である**visible**プロパティを反転させています。その行に対応する、、、という書き方をしたのですが、実際は詳細情報用パネルはアコーディオンウィジェット内でただ1つだったので、それを常に参照できるようにしています。

(最初はアコーディオンウィジェットの子要素、childrenから探して参照するようにしてtryしたのですが、それだと何故かnullになってしまいました)

結果、動きはこうなりました。

|![gif003-compressor.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/8038b299-a3d3-2db4-1c3e-0859bb0102a8.gif)|
|:-:|

個人的には大分満足しました。
アコーディオンウィジェットも、タブなどと同じ様に少ないスペースで多くの情報を伝えられるレイアウトだと思うので、違和感のある動きにならないように使っていければと思います。

以上です。良いApp Makerライフを!