こんにちは!S.K.です。
突然ですが、こんな光景を見たことはありませんか?
お子様に「早くしなさい!!」とイライラしている親と、それでもやろうとしないお子様
まあ、まさに我が家なのですが…(汗)
宿題もせずに寝ていたり、お風呂も入らずテレビを見ていたり、散らかすだけ散らかして片付けをしなかったりとまさに天使のような悪魔ですよね。
とはいえ、さすがに都度イライラしていては親の身が持ちませんし、子どももそんなイライラしている親と一緒では絶対嫌なはず!!
あるとき、子どもと話していて、「あれやった?」と聞くと「あ、忘れてた!」ということが多かったことから、
一目で「やること」と「できたこと」がわかればいいんじゃない!?
と、今回の「Newやることりすと」の思い立ちましした。(ま、よくあるTodoListを作ろうと思った理由なんですけどね(笑))
ちなみに以前も似たような理由で「やることりすと」を作っているのですが、
![](http://ksk2aki.xsrv.jp/wp/wp-content/uploads/2020/10/図1-160x90.png)
こちらは親が「やること」を用意して、それを子どもがクリアしていくという形式でした。作ったのは2020年5月頃でして、数か月たった今現在では…
見向きもされていません!!
ですよね~。まあ、数か月は使っていたんですけどね…
機能のこれくしょんが意外と当たりだったようで、最初のころは結構楽しんでいたのですが、複数回の「やること」をクリアしていくとランダムに生まれる恐竜が、すでに持っているものと被ってしまい心が折れたようです。(ガラスのハートかっ)
なので、今回は少し大人向けにして、子どもが自分で「やること」を作って、「できたこと」に移動するようにして、自主的に「やること」を管理していけるようにしていこうと思い、作り始めた次第です。
私自身も管理なんてできていないのに、子どもに求めるのはどうかと思うのですが、それはそれ、これはこれの精神で(汗)、あとは何となくおもしろそうなので!
今回はJavaScriptとPHPで作ります。
「ふせん」を作って、insertAdjacentHTMLで追加しよう
まずは「やること」と「やりたいこと」を作れるようにする必要があります。
今回は「やること」を子どもに自分で作ってもらうので、使いやすいよう手書きで入力ができるようにしました。
やることボタンかやりたいことボタンを押すと、手書き文字を「ふせん」に清書して、ボードに貼っていくイメージです!!
ここの大まかな処理としては
- 手書き文字を認識する
- 押されたボタンによって、ふせんの色を変える
- 「やること」ボードに追加する
- ローカルストレージに追加したふせんの情報を追加する
となります。もちろん、ところどころでエラーチェックが入ります。
とはいえ、手書き文字の認識は以前作成した漢字検索アプリで行っているので、そこまで難しくはありません。むしろがっつり流用しています(笑)
![](http://ksk2aki.xsrv.jp/wp/wp-content/uploads/2020/12/サムネ4-160x90.png)
手書きの文字さえ認識できてしまえば、ふせんを作り、「やること」ボードに追加するのは難しくありません。
ようは、ふせんを「やること」ボードに次々に追加すればいいので、私はinsertAdjacentHTMLを使って追加しました。(appendChildを使ったりしてもいいかもしれませんね。)
insertAdjacentHTMLは4つの引数を指定できます。
-
beforebegin
-
afterbegin
-
beforeend
-
afterend
それぞれ要素を追加する場所がこのように変わります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<!-- beforebegin --> <div id="area"> <!-- afterbegin --> <p>子要素</p> <!-- beforeend --> </div> <!-- afterend --> <button onclick="add('beforebegin');">beforebegin</button> <button onclick="add('afterbegin');">afterbegin</button> <button onclick="add('beforeend');">beforeend</button> <button onclick="add('afterend');">afterend</button> <script> let area = document.getElementById('area'); function add(position) { let p = '<p>' + position + '</p>'; area.insertAdjacentHTML(position, p); } </script> |
今回、私はbeforeendを使いました。
そして、ふせんを追加するより大切なことは、ローカルストレージに追加するふせんの情報です。どのような情報を残しておく必要があるかを、ふせんを追加する部分だけではなく、全体の動きを考えながら決める必要があります。
ページを開き直したら、せっかく作ったふせんが消えているのでは、使い物になりませんよね?そうならないようにローカルストレージにふせんの情報を入れて保存しておきます。
ふせんの情報とは、例えばふせんが貼ってあるボードやふせんの内容です。(他にもあります。)
これをおろそかにして先に進んでしまうと、後からやり直しの嵐に遭遇します…。
「ふせん」を動かそう ドラッグ&ドロップ!!
ドラッグ&ドロップをするサンプルです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>sample</title> <style> #todoArea, #completeArea { overflow: hidden; min-height: 100px; height: 100%; padding: 15px 10%; text-align: center; } </style> </head> <body> <div id="todoArea" class="droppable-elem" ondrop="drop(event, this);" ondragover="dragOver(event); " style="background-color: #f0f8ff;"> <div id="A" class="todo-parts" draggable="true" ondragstart="dragStart( event );" style="background-color: white;">A</div> </div> <div id="completeArea" class="droppable-elem" ondrop="drop(event, this);" ondragover="dragOver(event);" style="background-color: #fff0f8;"> <div id="B" class="todo-parts" draggable="true" ondragstart="dragStart( event );" style="background-color: white;">B</div> </div> <script> function dragStart(event) { event.dataTransfer.setData("Text", event.target.id); } function dragOver(event) { event.preventDefault(); } function drop(event, parentDiv) { let id = event.dataTransfer.getData("Text"); parentDiv.appendChild(document.getElementById(id)); } </script> </body> </html> |
まずはドラックをしたいdivをドラッグ可能にするため draggable="true" を設定します。(divは初期値ではドラッグ不可となっているため)
また、ドラッグを開始した際の動き ondragstart="dragStart( event );" を設定します。ondragstartイベントは、ドラッグ操作を始めた時のイベントです。ここでは転送中のデータのidをセットしています。
ドロップを行うdivには ondrop="drop(event, this);" と ondragover="dragOver(event); を設定しています。ondropイベントは、ドロップした時のイベント。ondragoverイベントは、ドラッグ状態のマウスが、ドロップ可能な要素上に重なってる時のイベントです。
dragOver(event) では、 preventDefault で既定の動作を無効化しています。実はウェブページやアプリケーションのほとんどの場所では、ドロップデータを受け取る場所としては不適切でドロップを禁止しています。そのため、この既定の動作(ドロップ禁止)を無効化する必要があるんです!
drop(event, this) では、転送中のデータを取得して、appendChildで親要素にドラッグしてきた子要素を追加します。
上記サンプルでは要点だけを説明しました。どうです?難しくないですか?私もドラッグ&ドロップは初だったので悩みながら調べながら作っていきました。ただ私みたいに、やっていくともっとこうしたい、ここがうまくいかないなどが出てくると思います。
そんな中で私は「どこの要素」の、「どの位置」にドロップをしたいかで条件を分かるなどしていくと理解もしやすいかなと感じました。当たり前と言えば当たり前なんですが…。「どこの要素」をどう取得して、「どの位置」に何で追加するか(appendChiledだけでなく…)を考えてみてください。
ページを更新してもデータを残す?ローカルストレージはリセットしないの??
先に伝えてしまいましたが、ふせんの情報はローカルストレージに保存していきます。そのため、ページを開いたときにローカルストレージからふせんの情報を読み取り表示すれば、いつでも元通りになります!(ローカルストレージなので同PCの同ブラウザ間ではあるんですけどね)
ですが、ただローカルストレージからふせんの情報を表示しているだけだと、日をまたいで、さあ今日のやることを…とページを開いたとき、昨日終わったままの姿でページが表示されてしまいます。
朝一番、さあやろうとしたときに、いきなりできたことのボードにふせんが貼ってあったらなんとなく嫌じゃないですか?
せっかくなので、日をまたいでページを開いたらふせんを全部やることに入れるようにしようと考えました。(ふせんを消してしまうことも考えましたが、毎日のやることって基本的にくり返しが多いので、消さずにやることに入れるようにしています)
ページを開いたらローカルストレージに日付情報を入れるようにして、新しくページを開いたら新しい日付情報と古い日付情報を比較するようにしたんです。
日付が違っていた時や〇時を超えていた時などの条件に一致したら、
ふせんの情報を書き換えたあとでふせんを表示すれば、全部のふせんがやることに!!
(ドラッグ&ドロップに比べ、なんと簡単なことか…)
日付の取得は下記のようにできます。また、 getFullYear で年だけ、 getMonth で月だけ、 getDate で日だけを取得することもできます。※ getMonth は0始まりなので、+1する必要があることに注意です。
1 2 3 4 5 6 7 8 |
<script> let now = new Date(); let year = now.getFullYear(); let month = now.getMonth() + 1; let date = now.getDate(); console.log(now); console.log(year, month, date); </script> |
カレンダーから過去の結果を見れるようにしよう
ここまでで、ふせんの追加、ドラッグ&ドロップ、ページ更新時のふせんの保存とやってきました。正直ここまでやれば、とりあえず使う分には問題がありません。
ページを開いてやることを作って、できたらドラッグ&ドロップ!、ページを閉じても開きなおせば復帰できるので、これだけでも楽しいですよね♪(ちなみにここまでなら、JavaScriptだけで作ることができます)
そして、こうも思いました。(言われもしました(汗))
どうせなら過去の結果もみたくない?
ときどき自分から首を締めにいっている感がしないでもないですが、とにもかくにもカレンダーの登場です(笑)
ふせんのリセットを行った際にDBにふせんの情報を保存して、それをカレンダーに出してやろうというわけです。
まずはカレンダーです。お得意のコピペでやろうとしましたが、これまたお得意のうまくいかず…(泣)
結局いじくり回して、大半がちがうコードに…。大丈夫いつも通り!!
まあ、そんなことがありながらなんとかカレンダーを実装し、日付をクリックしたらモーダルウインドウでその日の結果を表示するようにしました。(モーダルウインドウは、クリックしたらふわっとでてくる画面のことです)
このときふせんの情報はカレンダーの日付をクリックしたら、この日付を元にajaxを使ってDBから取得するようにしています。
PHPとJavaScriptの違いが分かっているとなぜこんなことしているかもわかるはずです。
ログインを手軽に!?1回だけのID発行!!
DBを使うあたりから気づいた人もいるでしょう。この仕様でDB使うならユーザー情報がないと、どのふせんがだれのか分からなくない??と。
いえーす。ざっつらいと。その通りです。
ですが、毎回ログインするのってめんどくさくないですか?ましてやターゲットは子どもです。キーボード入力は言わずもなが、フリック入力も危ういです。
ですので、「ローカルストレージを使う」=「同じ端末で同じブラウザを使う」ことを前提に、初回のみIDを発行し、そのIDと紐づけしたページより使用してもらおうと思います。
少し細かく言うと、初回はID発行ページよりIDを発行、発行したIDを暗号化し、暗号化したIDをクエリパラメータとしたページを常に使ってもらうようにします。この暗号化したID付きのURLをお気に入りなどに入れておけば常に使えるようになるわけです。
完成!!Newやることりすと
そしてできたのがこちらです。
まとめ
ちなみにこの「Newやることりすと」はタブレットで使うことを考えています。
そして、タブレットやスマホで使う場合、ドラッグ&ドロップはondropどではなく、touchstartなどを使います!!
正直に言えば途中まで気づかなかったんですよね…。
PC画面でやったー!!ドラッグ&ドロップできた―!!と思い、タブレット画面でやろうとしたら動かないときに絶望感はやばかったです(笑)
流れはそうかわらないで、ぜひセットでお試しあれ!!
今回は以上です。