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

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

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

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

JavaScript

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

jQuery

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

Q&A

解決済

1回答

3647閲覧

カレンダーの日付をクリックした際に、複数選択できるようにしたい。

VS2utiYGJMaArVp

総合スコア12

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

JavaScript

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

jQuery

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

0グッド

0クリップ

投稿2022/01/13 08:34

編集2022/01/13 09:02

カレンダーは生成しています。
実装したいのは、
jsで日付を複数選択されている状態にする
もう一度同じ日付を選択したときに、消す
という処理です。

アルゴリズムにすると
1.日付をクリックする(onClick関数)
2.クリックされた日付を取得
3.もう1度、日付をクリックする
4.再度クリックされた日付を取得し、2.と日付が違う場合、そのまま取得
5.再度クリックされた日付を取得し、2.と日付が同じ場合、同じ日付を削除
という流れは、頭では分かっているのですが、コードに落とし込めない状態です。

(カレンダーを生成) <?php namespace App\Controller\Component; use Cake\Controller\Component; use Cake\ORM\TableRegistry; class ScheduleComponent extends Component { //指定月のカレンダーを生成 public function getCalendar($year, $month, $day, $events) { //ヘッダー部分の曜日表示 $days = array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); //本日を取得 $today = date('Y-m-d'); //1行ごとの順番(1〜7)と、月全体の順番(1〜31(最大)) $num_row = 1; $num_day = 1; //月の始まる曜日から、前月の空白分を取得 $num_blank = date('w', mktime(0, 0, 0, $month, 1, $year)); //月の合計日 $total = $month == 2 ? ($year % 4 ? 28 : ($year % 100 ? 29 : ($year % 400 ? 28 : 29))) : (($month - 1) % 7 % 2 ? 30 : 31); //カレンダーのヘッダー部分 $calendar = '<table class="calendar table">'; $calendar .= '<thead><tr>'; while ($num_row <= count($days)) { $calendar .= '<th>' . $days[$num_row - 1] . '</th>'; $num_row++; } $calendar .= '</tr></thead>'; //カレンダーの本体部分 $calendar .= '<tbody><tr>'; $num_row = 1; //前月の空白分のセルを生成 while ($num_blank > 0) { $label = ''; $label = ($num_row == 1) ? 'sun' : $label; $calendar .= '<td class="' . $label . ' td_day td_day' . $num_day . '"><input type="hidden" class="hidden_td_day' . $num_day . '" value="' . $num_day . '"></td>'; $num_blank--; $num_row++; } //1日〜31日(最大)までのセルを生成 while ($num_day <= $total) { //「$label」は要素のクラス名として、「$content」は祝日などのイベント内容 $label = ''; $content = ''; //イベントの配列を走査するためのキーとして、「20120512」の形式で文字列を生成 $key = $year . '-' . sprintf('%02d', $month) . '-' . sprintf('%02d', $num_day); //左端なら日曜日、右端なら土曜日のためのラベル(クラス)を付加 $label = ($num_row == 1) ? 'sun' : $label; $label = ($num_row == 7) ? 'sat' : $label; //本日の場合もクラスを付加 $label = ($key == $today) ? 'today' : $label; //イベントの配列があれば、配列を走査 if (isset($events)) { //連想配列になっているイベントの配列($event)の中の、各イベント配列ごとに処理 for ($i = 0; $i < count($events); $i++) { $label_event = (isset($events[$i]['label'])) ? $events[$i]['label'] : ''; //イベントの配列に一致するキー(20120512など)があれば、要素を付加 if (array_key_exists($key, $events[$i])) { $label .= ' ' . $label_event; $content .= '<div class="event ' . $label_event . '">' . $events[$i][$key] . '</div>'; } } } $calendar .= '<td class="' . $label . ' td_day td_day' . $num_day . '">'; $calendar .= '<div class="day"><span>' . $num_day . '</span></div>'; $calendar .= $content; $calendar .= '<input type="hidden" class="hidden_td_day' . $num_day . '" value="' . $num_day . '"></td>'; $num_day++; $num_row++; //1行の終わり(7日目)ごとに、新しい行を開始 if ($num_row > 7) { $calendar .= '</tr><tr>'; $num_row = 1; } } //月の最終日以降の空白分のセルを生成 while ($num_row > 1 && $num_row <= 7) { $label = ''; $label = ($num_row == 7) ? 'sat' : $label; $calendar .= '<td class="' . $label . ' td_day td_day' . $num_day . '"><input type="hidden" class="hidden_td_day' . $num_day . '" value="' . $num_day . '"></td>'; $num_row++; } //カレンダーの終了 $num_day_max = $num_day - 1; $calendar .= '</tr></tbody></table><input type="hidden" class="num_day_max" value="' . $num_day_max . '">'; //文字列として生成したカレンダーを返す return $calendar; } //Googleカレンダーから祝日を取得 public function getHolidays($year) { //スケジュールの年 //Googleカレンダーから、指定年の祝日情報をJSON形式で取得するためのURL $url = 'https://holidays-jp.github.io/api/v1/' . $year . '/date.json'; //JSON形式で取得した情報を配列に変換 $results = json_decode(file_get_contents($url), true); //祝日の配列を早い順に並び替え ksort($results); //配列として祝日を返す return $results; } }
(jquery) var num_day_max = $(".num_day_max").val(); for (let i = 1; i <= num_day_max; i++) { $(".td_day" + i).on("click", function () { //CSRFのバグ回避の為に記載。 var csrf = $('input[name="_csrfToken"]').val(); //選択された日付から年月日形式で日付を生成 var year = $(".schedule_year>option:selected").val(); var month = getZeroPadding( $(".schedule_month>option:selected").val(), 2 ); var day = getZeroPadding($(".hidden_td_day" + i).val(), 2); //パラメータを生成 var date_parameters = year + "-" + month + "-" + day + ""; $.ajax({ type: "POST", url: "/ajax_master/set_date", beforeSend: function (xhr) { xhr.setRequestHeader("X-CSRF-Token", csrf); }, dataType: "JSON", data: { date_parameters: date_parameters, }, }) .done(function (data) { console.log(data); }) .fail(function () { alert("日付の選択に失敗しました。"); }); }); } });

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

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

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

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

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

yambejp

2022/01/13 09:21

PHPの挙動は理解しているのですか?であればカレンダー自体はHTMLで感的なものにした方が切り分けしやすいのでは?
guest

回答1

0

自己解決

クリック前に、空配列を入れ、
indexOfでセレクトされているか確認(入っていなければ -1、入っていればそのindexを返す)することによって、
配列へのpush、spliceで配列内で同じものがあれば削除することによって、日付の取得ができました。

var date_parameters = []; $(".td_day" + i).on("click", function () { //選択された日付から年月日形式で日付を生成 var year = $(".schedule_year>option:selected").val(); var month = getZeroPadding( $(".schedule_month>option:selected").val(), 2 ); var day = getZeroPadding($(".hidden_td_day" + i).val(), 2); //パラメータを生成 var select_date = year + "-" + month + "-" + day + ""; //カレンダーの日にちを取得 const date_parameters_index = date_parameters.indexOf(select_date); if (date_parameters.indexOf(select_date) < 0) { date_parameters.push(select_date); } else { date_parameters.splice(date_parameters_index, 1); } }

投稿2022/01/14 05:50

VS2utiYGJMaArVp

総合スコア12

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問