質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

0回答

1672閲覧

Javascriptにおいて時間帯のはじめの時間に対応した終わりの時間を導き出したい

kamille-mio

総合スコア24

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

1クリップ

投稿2019/12/25 19:09

編集2019/12/25 19:12

環境

Laravel 6.5.0
Homestead
使っているライブラリ
→flatpickr(日付)、datetimepicker(時間)、moment.js、holiday_jp.js

やろうとしていること

イメージ説明

画像のようなある施設の利用予約を申請するシステムについて、
決定ボタンが押されるとテーブルからその日の予約情報を取得して、それを参照しDatetimepickerの時間選択で予約が入っている時間は利用開始・利用終了時刻から選択できないようにしたい。
今回の場合は9時13時と15時17時で予約が入っていることを前提として、利用開始時刻は絞り込めている状態です。
また、実際は決定ボタンを押したあとに、時間の選択フォームとフォームの全体の情報をPOSTするSubmitボタンが出現するという仕様になります。

質問したいこと

以前に

Javascriptにおいて配列の中の時間の最大値や最小値、及び間の時刻を取得したい。

という質問をして、その中で回答者様のご教授に従い、ユーザーが利用したい施設と利用したい日付をフォームから送信すると、Ajaxで非同期通信を行い、既にテーブルにある予約情報を取得してそこから指定した施設・利用日において予約できる時間帯をユーザーに提示するにはどうすればよいのかということについて、以下のようなdatetimepickerのallowTimes(選択の候補に含める時間の一覧)を求めるのに

javascript

1jQuery('#datetimepicker5').datetimepicker({ 2 datepicker:false, 3 allowTimes:[ 4 '12:00', '13:00', '15:00', 5 '17:00', '17:05', '17:20', '19:00', '20:00' 6 ] 7});

javascript

1 2// momentのフォーマット文字列を定数にしておく 3 const FORMAT_DATE = "YYYY-MM-DD"; 4 const FORMAT_DATETIME = "YYYY-MM-DD HH:mm:ss"; 5 const FORMAT_TIME = "HH:mm:ss"; 6 7 // ジェネレータ(関数)を定義しておく 8 // 今回はある時間とある時間の間にある日時を開始は含み、終了は含まないように1時間ごとに取得する。 9 10 function* range({start, end}) { // 引数はstartとendプロパティを持つオブジェクトである。 11 let m = start; // 変数にstartプロパティを設定する。 12 while (m.isBefore(end)) { // 実行する関数を定義。momentのisBeforeメソッドを使って、mに設定したmomentプロパティをendと比較し続け、m<endである限り以下の処理を実行する。 13 yield m; // 一度関数の処理を止めたあとmをreturnする。 14 m = moment(m).add(1, 'hour'); // mに1時間加算する。whileまで戻る。 15 } 16 } 17 18 19 // Ajaxで受け取ったJsonデータをパースする 20 21 const reservedata = JSON.parse(data).map(e => ({ 22 start: moment(e.start_time, FORMAT_DATETIME), 23 end: moment(e.end_time, FORMAT_DATETIME) 24 })); 25 26 console.log(reservedata); 27 28 // 日付部分の文字列の取得 29 30 const dateStr = reservedata[0].start.format(FORMAT_DATE); // dataで得られた時間からその日の日付をだけ抜き出す。 31 32 // 営業時間の定義。本来は営業時間テーブルから引っ張ってくるが今回は直接momentの値を持つオブジェクトとして定義する。 33 34 const business_hours = { 35 start: moment(`${dateStr} 09:00:00`, FORMAT_DATETIME), 36 end: moment(`${dateStr} 19:00:00`, FORMAT_DATETIME) 37 }; 38 // filterを用いて、営業時間帯に含まれる時間の中で選択可能な時間に適用ものだけを取得する 39 40 const selecttablesStartMoments = [...range(business_hours)].filter(m => 41 // [...range()]はスプレット構文といい、iterableオブジェクトをこれで展開することができる。range関数はジェネレーターでジェネレーターはiterableであるのでこの表記で実行することができる。 42 reservedata.every(e => m.isBefore(e.start) || m.isSameOrAfter(e.end)) // everyメソッドに与えられた引数の関数が配列すべてに適応されるかチェック。 43 44 // つまり、filterで絞る条件はrangeで取得されていくmがdata.every()に適応されるかということになる。 45 ); 46 47 const selectStarttime = selecttablesStartMoments.map(m => m.format(FORMAT_TIME)); // mapで新たにfilterの結果を配列にする。m.format()を実行するようにすることでmomentの値の配列にできる。 48 49 console.log(selectStarttime); 50

このようなコードを書いて以下の通りのような結果を得て、利用開始時刻のallowTimesに関しては無事に絞り込めました。

javascript

1 2console.log(selectStarttime); // => ["13:00", "14:00", "17:00", "18:00"] 3 4

よって、今度は利用終了時刻の絞り込みとして利用開始時刻に対応して今回の場合だと

javascript

1console.log(selectEndtime); // => ["14:00:00","15:00:00", "18:00:00", "19:00:00"] 2

という結果を得たいと考えて利用開始時刻の考えを応用して以下のようなコードを書き、一応期待している結果にはなったのですが、それが正しいアルゴリズムなのか、穴があるのかアドバイスいただきたいと思って質問いたしました。

コードはこちらです。

javascript

1 2// $end_timeのallowTimesに設定する時間を取得する 3 4 function* range1({start, end}) { // 引数はstartとendプロパティを持つオブジェクトである。 5 let m = start; // 変数にstartプロパティを設定する。 6 while (m.isBefore(end)) { // 実行する関数を定義。momentのisBeforeメソッドを使って、mに設定したmomentプロパティをendと比較し続け、m<endである限り以下の処理を実行する。 7 yield m = moment(m).add(1, 'hour'); // rangeとは違い今度は開始を含みたくない。 8 } 9 } 10 const selecttablesEndMoments = [...range1(business_hours)].filter(m => 11 reservedata.every(e => m.isSameOrBefore(e.start)|| m.isAfter(e.end)) 12 ); 13 const selectEndtime = selecttablesEndMoments.map(m => m.format(FORMAT_TIME)); 14 15 console.log(selectEndtime); 16 17

出力結果は以下のように期待しているものが出ました。

javascript

1console.log(selectEndtime); // => ["14:00:00","15:00:00", "18:00:00", "19:00:00"] 2

試しに後述している予約情報に比べて予約情報を以下のように増やしてみて実行しても

{ "id": "1", "start_time": "2019-11-30 09:00:00", "end_time": "2019-11-30 13:00:00" }, { "id": "2", "start_time": "2019-11-30 15:00:00", "end_time": "2019-11-30 17:00:00" }, { "id": "4", "start_time": "2019-11-30 13:00:00", "end_time": "2019-11-30 14:00:00" }

以下のようにやはり一応期待している結果は出ています。

javascript

1console.log(selectEndtime); // => ["15:00:00", "18:00:00", "19:00:00"] 2 3

なお、15時~17時で予約が入っているところで

イメージ説明

このような選択がなされた場合についてはLaravelでバリデーションを行うことを考えています。

質問に際してやったこと・作ったもの

PHPから返ってきたテーブルから取得したデータ
イメージ説明

定義しているテーブル
イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2019/12/27 05:27

ちょっと詰め込みすぎて何を聞きたいかわかりません。 PHPからAJAXで受け取ったJSONデータを利用して セレクトボックスに制限をつけるということですか? もう少し必要な部分だけ抜き出した方が良いと思います
kamille-mio

2019/12/27 16:35

タイトルにある通り、PHPからAjaxで受け取ったJsonデータを利用して、Datetimepickerのセレクトボックスに制限をつけるという過程で、すでに予約が入ってる時間は選択できないように利用開始時刻に制限をつけたら、利用終了時刻もそれに対応するようにしたいというのが今回の趣旨です。 そこで、利用開始時刻のallowTimesは求められたので、それを応用して利用終了時刻のallowTimesを求めるコードを書いたがそれが適切なコードなのか、あるいは適切だとしてもより良い書き方はあるでしょうかというのをお聞きしたいということになります。
kyoya0819

2019/12/29 02:31

穴があるというのはセキュリティ的なものですか? それとも仕組み的なもんですか?
kamille-mio

2019/12/29 06:58

これは言葉が足りていなかったです……そうですね仕組み的なところです。 セキリュティに関しても気になりますが、バリデーションとか基本的なところ以外は今の自分には手に余ってしまうので。 ひとまず想定外の値が出ないかどうかと想定している値が漏れないかというのが気になっています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問