Bubbleのチュートリアル１１：Graduation lesson: a to-do app

# はじめに
Bubbleというノーコード/ローコードでアプリを作るサービスがあり、ちょっと言葉に癖があったりするので、チュートリアルをやってみる記録です。Bubble用語は、`Bubble`のように網掛けします。
なるべく細かくキャプチャしていくので、見るだけでもBubbleってこうやるんだと感じていただければ。

https://bubble.io/

## これまでのチュートリアルをやってみた記事
1. [Saving data](https://qiita.com/yo16/items/d77a5cf8df18419b079e)
    - 位置情報をDBへ登録して、地図にマーカーを表示
    - データのInsert
    - 地図
2. [Building a sign-up system](https://qiita.com/yo16/items/1ac9467ad5bb5ed6ba52)
    - ユーザー登録とログイン、ログオフ
3. [Saving and modifying data](https://qiita.com/yo16/items/449b9e0b15ff76ec9584)
    - SNSっぽい、投稿といいね
    - `Repeat Group`の利用
    - データのInsert、Update
4. [Building a slideshow](https://qiita.com/yo16/items/c015c2097ae53055bca0)
    - スライドショー形式のアプリ
    - `Plugin`の利用
5. [Sending data to pages](https://qiita.com/yo16/items/0b0a847b0e4fa382e07c)
    - `Data`（`Things`、DBのデータ）の共有
6. [Using conditions](https://qiita.com/yo16/items/57b9bef94122c59785db)
    - 条件の利用
7. [Defining a field as a list of things](https://qiita.com/yo16/items/eda7b609d12ac16cb205)
    - リストの利用
8. [Using external APIs](https://qiita.com/yo16/items/b99810f8d0262b9d0a1c)
    - Pluginの利用による、外部APIの呼び出し
9. [Using the chart element](https://qiita.com/yo16/items/a19678a03b49b24456d6)
    - Pluginの利用による、グラフの描画
10. [Login with Facebook](https://qiita.com/yo16/items/a4f76c6cf70392822be2)
    - Facebookアカウントを使ったログイン
11. **Graduation lesson: a to-do app** ＜＜今回＞＞
    - 総合的なアプリ作成の練習

# チュートリアルの記録
## チュートリアルを選択
ログイン後のトップページ
＞ 左メニューのAcademy
＞ Learn your way
＞ By watching
＞ Interactive lessons
＞ **Graduation lesson: a to-do app**

今回のサブタイトルは、「You've done the basics - now flex your Bubble skills!」です。
すでに基本はできたとのこと。卒業課題として、"簡単にできるシステム構築業界"ではあるあるの、ToDoアプリ作成ですね。やっていきたいと思います。
"flex"は、披露するという意味で使うようです。（英会話勉強）

ちなみにわたくし、チュートリアルを毎日１つか２つずつ続けていましたが、卒業課題前までのチュートリアルをやった後に数日間旅行へ行き、完全に空きました。毎日触っている日々から数日離れた状態での卒業試験なので、どうでしょうかね。このシチュエーションは偶然ですが、現実的と思います。

ではいってみます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/264313e1-ca3a-c2a9-833e-7cc6729acb90.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/212882e9-4212-e528-cef6-ba51e45ff682.png)

## To-Do登録フォームを構築
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/81569447-ea8f-8a5d-4a76-40685a3c517b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/2468e1c4-2c2b-e876-c5b6-1c57f8bc0c37.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/ef10f4a3-c393-f880-fb24-02dd5a12ac4b.png)
テキストでページタイトルをつけるところから。"My To-Dos"。どうでもいいですが、自分で作るとしたらTo-Doの複数形、考えちゃいますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/927fcbc2-610b-345b-477f-8a08aeae90bf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/d85f3e7a-53e1-8762-ab66-1d46eddff81e.png)
デザインがしょぼいのはBubbleのせいじゃないですよってことですね。わかっております。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/3a022b6f-7bab-e726-7554-15b266246388.png)
タイトルの入力欄に、日付ピッカー、ボタンを並べます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/e9211e24-9182-b38a-c718-9ba9e80847f5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/a55a9a83-d9b3-205e-27ff-ecaa02926170.png)
ボタンの"Add workflow"から、ボタン押下処理時の`workflow`の構築に入ります。

## 登録ボタン押下時の処理を作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/a87643b8-9bff-e34b-2b04-7b910aa90005.png)
`Thing`の作成です。To-Doのレコードを追加ということですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/7626d443-de6f-40cb-2827-88d7620246b3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/791f035f-7274-7f16-ed4a-7f7683eb4bdf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/d02f5902-fef5-0c94-5c1f-74b09de2a0ff.png)
`Type`作成（≒テーブル定義）、`field`作成（≒列定義）。そしてそこに入れる値は、入力ボックスから拾います。ちなみに "Title" は "text型"、"Due date" は "date型" です。

"Due date"は期日（英会話）

あれ、まだ追加する？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/bd86cd2f-4d0e-24da-6f89-826a6c8d8bf3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/da40c694-3f5e-5da8-0cd6-5fa3a1bd36a0.png)
そうでした。登録するだけでなく、終わったら消し込むための、終わったフラグみたいなものも必要でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/de7adb8f-6a25-869d-2ff7-ff6f915440b9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/923456d7-f860-80f3-cfba-c0d5b2c9db1e.png)
"Finished"という "yes/no型" の列を追加し、初期値は"no"です。booleanと言わないのが、ノーコードっぽいですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/f302cbe0-3a1d-7b01-19a1-ceabf94c2e44.png)
次の処理で、いつもの、入力を初期化。

この初期化処理では、タイトルと日付ピッカーがリセットされると思いますが、リセットする入力フィールドを指定しないんですよね。`<form>`の`<input type="reset">`なんでしょうか。だとしたら`<form>`にあたるものが複数ある場合、どこまでリセットされるのか不安ではあるけど、そんなことあんまりないですかね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/118ab77f-6c61-2f96-5de8-856d5f6cb35b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/cb2e7663-d41c-559e-e163-54309ac8381b.png)

これで半分きて、次はまだ終わってない"To-Dos"を表示する機能です。

## 登録されて未完了のToDoを表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/9044c670-1ec1-15b3-ad0d-3ef7e0bc2aeb.png)
もうおなじみの、`Repeating Group`です。これかなーと思うようになってきて、自分のささやかな成長具合を感じます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/d14234f4-81fb-924b-0119-fcea47f45b1b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/a628d5a8-d094-cb98-94af-73948d6dbf25.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/42c35413-fe89-8890-2af7-b0311bb39854.png)
`Type`は"Todo"で、そのソースは`Data`から`Search for`します。条件として、終わってないもの（"Finished"が`no`）。そしてソート順は期日。"Descending"（降順）をつけてないので、昇順ですかね。過去ほど上に出て、未来ほど下に出ると思われます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/e3696f61-787b-66da-e4c8-97f95e6b9ae3.png)
繰り返しの中にテキストを配置し、`Current cell's Todo`を使って、そのタイトルと期日を作ります。期日は"date型"なので、toStringするフォーマットを指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/cb5d8c19-fd53-aceb-f10e-641754b226be.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/bab782cc-8ca3-bc06-2858-5a006e66bbcb.png)

デフォルトでは、"MM/DD/YY"でしたが、"YYYY/MM/DD"に変えちゃいます。

Customを選ぶと、Custom formatに→が入る。`ddd, m/dd/yy, mmmm (mmm) dS, yyyy, h:MM tt, HH:MM:ss.L`
私はなるほどねってなってうれしいけど、非エンジニアは戸惑うかもしれない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/ebac3402-72c5-08df-72d1-7675c049e975.png)
`yyyy/m/d`にしてみました。`d`はなかったけど、`m`（１桁目が０の場合は０を表示しない）があるならあるでしょ！どうかな。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/51336a96-5058-0783-9689-11c223a3ff42.png)
"Done"（済）ボタンを追加して、完了！・・・ってちょっと繰り返しの中が混とんとしすぎてやしませんか:sweat:

これの原因はわかっていて、繰り返しグループの中で、自由に配置できる`Fixed`でなく、`Column`になっているから。`Column`は登録されている順に縦に並べるもので、横にしたいときはGroupを作ったりして、手でコーディングするのに近く、コードが綺麗になる書き方。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/d29db711-7a98-6447-ce24-83570609ea49.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/84bc1e6a-cc14-2aca-d606-a65c80547934.png)

今はざっくりとやって動作確認したいので、繰り返しグループのLayoutで`Fixed`に変更して、適当に整形しておきます。（チュートリアル外）

## 実施済ボタンを実装
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/5acf016c-f53c-3c6c-b7eb-f4960ce27b72.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/3b68f8c3-294c-d62f-d081-ccf894f4109f.png)
ボタン押下時の処理を追加します。"Make changes"っていうけど、Updateですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/ebfffd0d-ee9a-0787-1e7d-d63096917d91.png)
処理の構築中に、Updateする対象を"Current cell's"と出てくるのは親切でわかりやすい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/6d0ccce8-c399-855d-1654-a207eb23d910.png)
"Finished"を"yes"に更新します。

## カスタマイズ？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/83820f70-3231-2c44-f5c0-34802e02e109.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/ce5dad70-4678-c44e-e612-2e8e6eecebe2.png)
これで終わり！と思ったら、アイデアへのリンク・・・？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/b61184ba-25fe-d3a0-ea17-4c9f5f4149aa.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/8d190445-96f7-2c90-59e6-e0107fec18b5.png)
Elementsからリンクを作成したら、URLにアイデアページへのリンクを自動的に入力してくれました。なんかおもしろいチュートリアルの使い方ですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/84dd03b2-ded5-a707-7c5a-bd97bed8bac0.png)
試しに飛んでみると、まさかの「Page not found」ｗ
まぁいいけど。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/a4fd20f5-d66e-ee22-55e4-cf931777f5fa.png)
そしてプレビューです！

## プレビューで確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/9f8950ae-bfdb-352a-5f50-bf10cf06f4ac.png)
- Createの操作、リセット
- 日付が、古い日付ほど上
- 日付のフォーマットはYYYY/m/d（月と日、それぞれ前ゼロなし）
- Doneボタンを押すと消える（ようにみえる）

## 改造：表示条件をいじる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/35751cc2-3fb3-15d0-4ac4-15d7739330e0.png)
Doneボタンを押すと消えちゃうので、
①：今日以降
②：昨日以前 かつ 未のみ
これらのOR条件にしたかったのだけど、ちょっといじってもそのやり方はわかりませんでした。

ググってみると解決。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/15b0d25c-1a68-12f6-8952-efc6b0d5a219.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/74d2b6ba-84a3-0194-2e9a-842133dfbdf2.png)
`Search for Todos`の中は全部AND条件で、それら（①と②）を`merged with`でつなぐとOR条件になります。ここでは、①で今日以降はすべて、②で昨日以前は未のみ、という条件にしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/bf885e81-5d50-caaf-65ba-c3d880328438.png)
あっ！表示はできたけど時系列にならない！
これはきっと、SQL的には、ORDER BYした結果をUNIONしてるからですね。

うーん、これ以上はちょっとわからないので、これはここでギブアップしよう。

## 改造：済のものは色を変える
上の改造によって、今日以降なら済でも出るようになったけど、それがわからないとダメなので、今日以降かつ済のものは、取り消し線がいいなぁ。。ということで条件をいじります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/97a763cd-8b78-7862-845a-8c6304027100.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/69b4395f-1b64-9c0c-e3ea-45e73de02f63.png)
これは以前、[チュートリアル６](https://qiita.com/yo16/items/57b9bef94122c59785db)でやった話です。タイトルのテキストの条件を入れて、CSSで・・・あっ取り消し線が選択肢にない！あんまり使わないのかな。
仕方がないので、半透明30%にして灰色っぽくしてみました。ボタンは灰色。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/497adda5-4794-c0a9-d0ea-f2c20bd67a45.png)
まぁいいか。自由にすべてのCSSを使えるというわけではないのかもしれません。

というわけで卒業！:mortar_board::tada:


# おわりに
卒業アプリということで、ログイン画面からやるのかと思ったら、そうでもなく、これまで何度かやったことをもう一度という感じでした。
最初に書いたように、数日間が空いたのですが、まったく問題なくできました。Bubbleは、何かを記憶するというよりも、自転車の乗り方を覚えるみたいな感覚が正しい気がします。見るところを覚える、みたいな。

あとBubbleはやはり言葉・単語ですね。`type`とか`filed`という言葉をはじめ、慣れないとわからないのがあるのですが、基本的にはチュートリアルをやれば慣れます。その点は、今後そんなに苦労しなさそうなイメージ。

ただ今回の最後の改造で、AND条件OR条件を混ぜて並び替えることや、マイナーなStyleを使うなど、ちょっと凝ったことに初めて出会うと、調べないといけないかもしれない。もしかしたら、そこまで自由度は高くないってできないかもしれない。
その場合の代替方法は、作り手の腕の見せ所ですね。（今回でいうと、取り消し線はできないみたいだから灰色にする、みたいな）

最後に、やはりエンジニア視点がないとちょっと厳しそうではあります。ノーコードではあるけど、やりたいことの言語化からググってやり方を調べるとか（AND条件 OR条件の混在とか）、逆にプルダウンの選択肢の意味の理解とか（SQLでいうWhere句だなとか）。

ということで、個人的にはもう少しお付き合いしたいと思います。

ではよきBubble＆ノーコード・ローコードライフを！