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

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

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

jQuery UI はjQuery公式のインターフェースライブラリであり、対話型のウェブアプリケーションを作る際に役立ちます。

PHP

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

jQuery

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

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

Q&A

1回答

2262閲覧

jQuery UI Datepickerで動的に選択不可日を設定したい。

rock_square

総合スコア14

jQuery UI

jQuery UI はjQuery公式のインターフェースライブラリであり、対話型のウェブアプリケーションを作る際に役立ちます。

PHP

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

jQuery

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

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

0グッド

1クリップ

投稿2018/06/18 10:00

編集2018/06/21 06:41

jQuery UI Datepickerで動的に選択不可日を設定したい。

前提・実現したいこと

Laravel5.5を使って、システム開発を行っています。

日付を入力する箇所が2ヶ所あり(出発日時、到着日時)、それぞれに関して入力補助として jQuery UI Datepicker を使用してカレンダーを出すようにしています。
その際に、選択不可となる日付をサーバーから取得し、カレンダーに反映しています。

初期表示時にPHPで取得した配列($arr_list['unavailable_days'])の内容は

array:1 [
0 => "2018-06-19",
1 => "2018-06-24"
]

です。

こちらの値を用いて初期表示を行うと、2018/06/19 と 2018/06/24 がカレンダー上で選択不可状態で表示されます。
これが「正常にカレンダーに反映できた」という状態です。

初期表示させた後、出発空港または到着空港を変更した場合、初期表示の場合と同じくサーバーから選択不可となる日付を取得し、カレンダーに反映させたいと考えています。
初期表示は正常にカレンダーに反映できたのですが、変更時のカレンダー反映ができない状況にあります。

下記、表示を行っているHTMLと、処理を行っているJS部分となります。

HTML

1<tr class="required"> 2 <th colspan="2">出発空港</th> 3 <td class="form-group"> 4 <span class="lookup w30"> 5 <input class="form-control airport-dialog" name="departure_airport" type="text" value=""> 6 <input class="form-control" name="departure_airport_id" type="hidden" value=""> 7 </span> 8 </td> 9</tr> 10 11<tr class="required"> 12 <th colspan="2">到着空港</th> 13 <td class="form-group"> 14 <span class="lookup w30"> 15 <input class="form-control airport-dialog" name="arrival_airport" type="text" value=""> 16 <input class="form-control" name="arrival_airport_id" type="hidden" value=""> 17 </span> 18 </td> 19</tr> 20 21<tr class="required"> 22 <th colspan="2">出発日時</th> 23 <td class="form-group"> 24 <input id="departure_date" type="tel" name="departure_date" value="" class="form-control w30 rm10" style="width:250px;display:inline;" placeholder="yyyy/mm/dd" autocomplete="off" > 25 </td> 26</tr> 27 28<tr class="required"> 29 <th colspan="2">到着日時</th> 30 <td class="form-group"> 31 <input id="arrival_date" type="tel" name="arrival_date" value="" class="form-control w30 rm10" style="width:250px;display:inline;" placeholder="yyyy/mm/dd" autocomplete="off" > 32 </td> 33</tr>

JavaScript

1<script> 2//出発日時カレンダー初期表示 3$(function () { 4 var dateFormat = 'yyyy/mm/dd'; 5 var disableDates = [ 6 @foreach($arr_list['unavailable_days'] as $num => $days) 7 <?php 8 $days_ = str_replace('-','/',$days); 9 ?> 10 '{{$days_}}', 11 @endforeach 12 ]; 13 14 //出発日カレンダー指定 15 $('#departure_date').datepicker({ 16 format: dateFormat, 17 startDate: '+1d', 18 endDate: '+30d', 19 beforeShowDay : function(days) { 20 var formatedDate = $.datepicker.formatDate('yy/mm/dd', days); 21 return ( disableDates.indexOf(formatedDate) == -1 ); 22 } 23 }); 24}); 25 26//到着日時カレンダー初期表示 27$(function () { 28 var dateFormat = 'yyyy/mm/dd'; 29 var disableDates = [ 30 @foreach($arr_list['unavailable_days'] as $num => $days) 31 <?php 32 $days_ = str_replace('-','/',$days); 33 ?> 34 '{{$days_}}', 35 @endforeach 36 ]; 37 38 //到着日カレンダー指定 39 $('#arrival_date').datepicker({ 40 format: dateFormat, 41 startDate: '+1d', 42 endDate: '+30d', 43 beforeShowDay : function(days) { 44 var formatedDate = $.datepicker.formatDate('yy/mm/dd', days); 45 return ( disableDates.indexOf(formatedDate) == -1 ); 46 } 47 }); 48}); 49 50 51//変更時の処理 52$(function() { 53 //出発空港の変更検知 54 $(document).on('blur', 'input[name=departure_airport]', function() { 55 datetime(); 56 }); 57 58 //到着空港の変更検知 59 $(document).on('blur', 'input[name=arrival_airport]', function() { 60 datetime(); 61 }); 62 63 function datetime(){ 64 var departure_airport_id = document.form_main.departure_airport_id.value; 65 var arrival_airport_id = document.form_main.arrival_airport_id.value; 66 var token = '{{csrf_token()}}' 67 68 //空港変更時 69 if(departure_airport_id!="" && arrival_airport_id!=""){ 70 var dateFormat = 'yy/mm/dd'; 71 var send_url = '{{url('flight/unavail_days')}}'; 72 73 var formData = new FormData(); 74 formData.append('_token', token); 75 formData.append('departure_airport_id', departure_airport_id); 76 formData.append('arrival_airport_id', arrival_airport_id); 77 78 $.ajax({ 79 type: 'POST', 80 contentType: false, 81 processData: false, 82 url: send_url, 83 data: formData, 84 success: function(rdata) { 85 var disableDates = JSON.parse(rdata); 86 87 //カレンダー制御 88 $('#departure_date').datepicker('option','beforeShowDay',function(days){ 89 var formatedDate = $.datepicker.formatDate(dateFormat, days); 90 return ( disableDates.indexOf(formatedDate) == -1 ); 91 }); 92 93 //カレンダー制御 94 $('#arrival_date').datepicker('option','beforeShowDay',function(days){ 95 var formatedDate = $.datepicker.formatDate(dateFormat, days); 96 return ( disableDates.indexOf(formatedDate) == -1 ); 97 }); 98 }, 99 error: function(data) { 100 //alert('エラーが発生しました。'); 101 }, 102 }); 103 } 104 } 105}); 106</script>

となっています。

試したこと

Ajax直後での取得データと、カレンダー制御部分でコンソールへのログ出力を行いました。

JavaScript

1 success: function(rdata) { 2 var disableDates = JSON.parse(rdata); 3console.log('データ取得'); 4console.log(disableDates); 5 //カレンダー制御 6 $('#departure_date').datepicker('option','beforeShowDay',function(days){ 7console.log('選択不可'); 8console.log(days); 9 var formatedDate = $.datepicker.formatDate(dateFormat, days); 10 return ( disableDates.indexOf(formatedDate) == -1 ); 11 });

Ajaxでのデータは

データ取得
edit:1535 (2) ["2018/06/19", "2018/06/24"]

という様に取得できているのですが、カレンダーへの反映部分がうまく動作していない様です。
⇒console.log('選択不可'); と console.log(days); が出力されない。

おそらく呼び出し方に問題があると思われますが、この状態からどの様に対応すれば良いかといった部分で詰まっています。

補足情報(FW/ツールのバージョンなど)

◆動作環境
・Windows10 Pro 64bit
・Apache2.4
・PHP7.1
・Laravel5.5
・MySQL5.7
・jQuery UI Datepicker
http://js.studio-kingdom.com/jqueryui/widgets/datepicker

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

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

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

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

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

mix-peach

2018/06/19 01:47

カレンダー上で、「選択不可日」が選択できない状態になればいいのだと思いますが、掲載のコードでは「初期表示は正常にカレンダーに反映できた」が確認できませんでした。どうなっているのが「正常にカレンダーに反映できた」なのでしょうか?
rock_square

2018/06/19 02:31

説明が不足していまして申し訳ございません。 初期表示時にPHPで取得した配列($arr_list['unavailable_days'])の内容は array:1 [ 0 => "2018-06-19", 1 => "2018-06-24" ] です。 こちらの値を用いて初期表示を行うと、2018/06/19 と 2018/06/24 がカレンダー上で選択不可状態で表示されます。 これが「正常にカレンダーに反映できた」という状態です。
x_x

2018/06/19 05:22

提示されたコードではbeforeShowDayの戻りが仕様通りではないため、初期表示時ですべて選択できない状態です。バージョンによっては選択できたりするのでしょうか? https://api.jqueryui.com/datepicker/#option-beforeShowDay
mix-peach

2018/06/19 05:29

私の方説明が足りてないですね。x_xさんのおっしゃっている内容と同じ原因で、「初期表示はカレンダーに反映できた」というのが確認できていません。jquery_ui はリンク先に1.10と書いてあったので、それで動作を見てみたのですが、もしやバージョンが違うのでしょうかね・・?
rock_square

2018/06/19 09:36

jQuery UI のバージョンを確認したところ v1.12.1 でした。beforeShowDayの戻り値ですが、通常であれば return [( disableDates.indexOf(formatedDate) == -1 ), "", ""]; という形になると思います。ですが、こちらでは期待する結果が得られませんでした。試行錯誤する中で return ( disableDates.indexOf(formatedDate) == -1 ); としたところ、期待する結果(カレンダーへの選択不可表示)となりました。これが現在の戻り値となった経緯となります。この違いがバージョンに依るものなのか、環境に依存するものなのかは不明です…。
x_x

2018/06/20 00:57

こちらの確認も1.12.1です。jQueryのバージョンはいくつでしょうか?
x_x

2018/06/20 01:19

やはりうまくいかないですね。仕様通りの書き方で正常に動かせるようにすることが先決かと思います。
rock_square

2018/06/20 01:25

ご確認ありがとうございます。そうですね。再度、確認しながら進めたいと思います。ありがとうございました。
mix-peach

2018/06/20 01:44

初期の設定で return [( disableDates.indexOf(formatedDate) == -1 ), "", ""]; がうまくいかない理由は分からないですが、不可日の再設定をしている方を、 return [( disableDates.indexOf(formatedDate) == -1 ), "", ""];  にしたら動くようになったりするかも・・? (って、仮に動いても根本解決にはならないんですけどね。仕様通りに書いて動くのが一番なので・・^^;)
rock_square

2018/06/20 01:51

コメントありがとうございます。再設定の方は $('#departure_date').datepicker('option','beforeShowDay',function(days){…} のループ自体が回らないんですよね。なので、return ( disableDates.indexOf(formatedDate) == -1 ); の部分までも辿り着けていない状況です。
LineOfLightning

2018/06/20 02:23

問題の切り分けのために、念のために確認したいんですが、空港変更後、カレンダーを表示させても「選択不可」がコンソールに出力されないということで合ってますか? 空港変更しただけでは、「選択不可」は出力されないので念の為・・・
rock_square

2018/06/20 04:40

コメントありがとうございます。そうですね。空港を変更し、カレンダーを表示させても選択不可日が更新されていなかった(選択した空港によって選択不可日が変わります)ので おかしいと思い、提示した場所へ「選択不可」がコンソールに出力されなかった…というのが経緯です。最終的に、カレンダーの選択不可日が選択された空港によって更新されれば良く、その過程で「選択不可」をコンソールに出力して確認した、という流れです。
guest

回答1

0

jQuery-uiのdatepickerは、途中でオプションを変更しても反映されないようです。
なので、一旦、destroyしてから作り直すしかないみたいです。

こんな感じでどうでしょう?
動作確認はしていませんが・・・

JavaScript

1// 外部変数として、デフォルトオプションを定義 2var default_options = {format: dateFormat, startDate: '+1d', endDate: '+30d'};

JavaScript

1success: function(rdata) { 2 var disableDates = JSON.parse(rdata); 3 console.log('データ取得'); 4 console.log(disableDates); 5 //カレンダー制御 6 $('#departure_date').datepicker('destroy'); 7 8 // デフォルトオプションをコピー 9 let new_options = $.extend(true, {}, default_options); 10 new_options.beforeShowDay = function(days){ 11 console.log('選択不可'); 12 console.log(days); 13 var formatedDate = $.datepicker.formatDate(dateFormat, days); 14 return ( disableDates.indexOf(formatedDate) == -1 ); 15 }; 16 17 $('#departure_date').datepicker(new_options); 18 $('#departure_date').datepicker('refresh');

投稿2018/06/20 02:58

LineOfLightning

総合スコア253

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

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

rock_square

2018/06/20 05:07

ありがとうございます。 ご提示いただいた内容で試してみたのですが、特に動作に変化はありませんでした(エラーも出ていない状況です)。
mix-peach

2018/06/20 09:10

私が動作確認した限りでは、beforeShowDay の戻り値を初期の時、不可日変更の時、の両方を return [( disableDates.indexOf(formatedDate) == -1 ), "", ""]; に直すだけで、他のコードは特に修正しなくても「選択不可日」の変更が反映されていましたよ! 一度、datepickerを含むjquery_ui そのものを、新しくダウンロードして置き換えた方が良いのかもしれません・・(もし既存で問題なく動いている画面で、同じライブラリを使っているなら、この画面でだけ新しいjquery-uiを読み込むようにして確認するのでもいいと思います。)
LineOfLightning

2018/06/21 01:29

確かに、jQuery UIのdatepickerの場合、作り直す必要はないみたいですね。すみません。bootstrap-datepickerと混同してました。後、動作確認したところ、一応、beforeShowDayの戻り値が配列ではない場合でも、動作するみたいです。(あまり、おすすめできる書き方ではないですが・・・)
LineOfLightning

2018/06/21 02:07

それと、下記の部分で、括弧が一つ多いんですが、エラーになってませんか?開発者ツールのコンソールでエラーになっているか確認してますか? //空港変更時 if(departure_airport_id!="" && arrival_airport_id!="")){
rock_square

2018/06/21 06:41 編集

mix-peachさん ご返信ありがとうございます。 システム全体で共用している jquery-ui であるため、該当ページだけ分けて jquery-ui をダウンロードして差し替えたのですが、状況は変わりませんでした。 どうやら、完全に環境に依存(他に読み込んでいるモジュールか、Laravelあたり?)している様なので、もう少しこちらで原因となるポイントを切り分けて考えてみたいと思います。 ありがとうございました。 LineOfLightningさん > 括弧が一つ多いんですが、エラーになってませんか?開発者ツールのコンソールでエラーになっているか確認してますか? すいません。こちら単純なソースのコピペミスですね。 実際のソースは、エラーが出ていないことは確認済です。 記載内容を修正しておきます。 ご指摘ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問