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

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

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

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

Q&A

解決済

1回答

1673閲覧

Javascript: 画面遷移について

nanase21

総合スコア144

JavaScript

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

0グッド

0クリップ

投稿2019/04/08 09:23

編集2019/04/09 12:15

前提・実現したいこと

予約システムのカレンダーを実装しています。
カレンダーをクリックすると、次のalert('JavaScriptのアラート');出力したいです。

発生している問題・エラーメッセージ

setholidayの中が空だと遷移しなくなる

schedule.setHoliday();
エラーメッセージ

該当のソースコード

html

1<input type="hidden" name="off_date" value="<%= booking.booking_date.strftime("%Y-%m-%d-%H:%M") %>",class='off_date' readonly> 2 <input type="hidden" name="course" value="<%= booking.booking_course_name.delete!("^0-9") %>",class='course' readonly> 3<input type="text" name="id" value="<%= @user.id %>",class='id' readonly> 4<input type="text" name="holiday" value="<%= @user.holiday %>",class='holiday' readonly> 5 <div id="calendar"></div> 6 <input type="text" name="booktime" value="" class= "booktime" id="booktime" readonly> 7

js

1 { 2 const 3 day_name = [ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'], 4 day_jname = ['(日)', '(月)', '(火)', '(水)', '(木)', '(金)', '(土)'], 5 doc = document, 6 DEF_OPTION = { }; 7 8 const 9 A = (e, ...a) => a.map (a => e.appendChild (doc.createElement (a))), 10 B = (d, n) => d.setDate (d.getDate () + n), 11 C = d => [d.getFullYear (), '年', d.getMonth () + 1 , '月'].join (''), 12 D = d => [('0' + d.getHours ()).slice (-2), ('0' + d.getMinutes ()).slice (-2)].join (':'), 13 E = (e, d) => { 14 let 15 [a,,b] = A (e, 'label', 'br', 'label'), 16 w = d.getDay () ; 17 a.textContent = d.getDate (); 18 b.textContent = day_jname[w]; 19 e.classList.add (day_name[w]); 20 }, 21 F = d => { 22 let m = d.getMonth (); 23 return [0,31,59,90,120,151,181,212,243,273,304,334][m] + d.getDate() - 1 + 24 (new Date (d.getFullYear (), m + 1,0) === 29 && 0 < m); 25 }, 26 H = d => new Date (d.getFullYear (), d.getMonth (), d.getDate ()), 27 I = d => [('0' + d.getUTCHours ()).slice (-2), ('0' + d.getUTCMinutes ()).slice (-2)].join (':'); 28 29 //_____________ 30 31 32 class Schedule { 33 34 constructor (date = new Date, range = 7, plan = [ ], option = DEF_OPTION) { 35 this.current = H (date);//表の左端の日付、これを基準とする 36 this.date = H (date); 37 this.range = range; //何日分を表示するか 38 this.plan = plan; //予定表が構成される 39 this.table = document.createElement ('table'); 40 this.option = Object.assign ({ }, option); 41 42 this.remake (); 43 } 44 45 46 add (day = this.range) { 47 let d = H (this.current); 48 d.setDate (d.getDate () + day); 49 if (+this.date <= +d) 50 this.current = d; 51 return this; 52 } 53 54 55 setHoliday (...dayNo) { 56 let 57 year = this.current.getFullYear (), 58 start = new Date (year, 0, 1), 59 end = new Date (year, 12, 1), 60 61 b = new Date (Date.UTC (1970,0,1, 0, 0)), 62 e = new Date (Date.UTC (1970,0,1,24, 30)), 63 s = new Date (Date.UTC (1970,0,1, 0,30)); 64 65 dayNo.forEach (n => { 66 let current = new Date (start); 67 68 current.setDate (7 - current.getDate () + n); 69 70 for (; current < end; current.setDate (current.getDate () + 7)) { 71 let idx = F (current); 72 73 for (let c = b; c < e; c = new Date (+s + (+c))) { 74 let key = I (c); 75 if (! this.plan[key]) 76 this.plan[key] = [ ]; 77 this.plan[key][idx] = true; 78 } 79 } 80 }); 81 82 return this; 83 } 84 85 //Booking 86 setBook (date, occupancyTime) { 87 let 88 current = new Date (date), 89 dayNo = F (current), 90 sTime = 30, 91 step = new Date (Date.UTC (1970,0,1, 0, sTime)), 92 cnt = Math.floor (occupancyTime / sTime); 93 94 for (let i = 0; i < cnt; i++) { 95 let time = D (current); 96 if (! this.plan[time]) 97 this.plan[time] = [ ]; 98 this.plan[time][dayNo] = true; 99 current.setTime (+current +(+step)); 100 } 101 return this; 102 } 103 104 remake () { 105 let t = this.table; 106 t.innerText = ''; 107 108 let 109 h = t.createTHead (), 110 tr0 = h.insertRow (-1), 111 tr1 = h.insertRow (-1), 112 d = H (this.current), 113 s = tr0.insertCell (-1), 114 c = 1, 115 m = d.getMonth (); 116 117 for (let i = 0; i < this.range; i++, c++, B (d, 1)) { 118 let td = tr1.insertCell (-1); 119 if (m !== d.getMonth ()) { 120 s.colSpan = c - 1; 121 s = tr0.insertCell (-1); 122 m = d.getMonth (); 123 c = 1; 124 } 125 s.textContent = C (d); 126 E (td, d); 127 } 128 s.colSpan = c - 1; 129 130 let e = tr0.insertCell (0); 131 e.textContent = '前の一週間'; 132 e.classList.add ('button'); 133 e.rowSpan = 2; 134 this.prev_btn = e; 135 136 e = tr0.insertCell (-1); 137 e.textContent = '次の一週間'; 138 e.classList.add ('button'); 139 e.rowSpan = 2; 140 this.next_btn = e; 141 142 //__ 143 let 144 begin = new Date (Date.UTC (1970,0,1, 9, 0)), 145 end = new Date (Date.UTC (1970,0,1,21, 30)), 146 step = new Date (Date.UTC (1970,0,1, 0,30)), 147 o = F (this.current), 148 [tb] = A (t, 'tbody'); 149 150 for (let d = begin; d < end; d = new Date (+step + (+d))) { 151 let 152 b = I (d), 153 c = this.plan[b] || [], 154 tr = tb.insertRow (-1); 155 156 tr.insertCell (-1).textContent = b; 157 for (let i = 0; i < this.range; i++) { 158 let td = tr.insertCell (-1); 159 if (c[o + i]) { 160 td.textContent = '-'; 161 td.classList.add ('invalid'); 162 163 } 164 else { 165 td.textContent = '◎'; 166 td.classList.add ('valid'); 167 td.style.color = '#fd5c63'; 168 td.style.backgroundColor = 'white'; 169 } 170 } 171 tr.insertCell (-1).textContent = b; 172 } 173 174 return this; 175 } 176 177 178 handleEvent (event) { 179 let t = event.target; 180 if (t === this.prev_btn) this.add (-this.range).remake (); 181 if (t === this.next_btn) this.add ( this.range).remake (); 182 183 let cbfunc = this.option.handleEvent; 184 if ('function' === typeof cbfunc) 185 cbfunc.call (this, event); 186 } 187 188 189 static convert (ary) { 190 let rst = { }; 191 ary.forEach (a => { 192 let 193 dt = new Date (a + ':00.000+09:00'), 194 tm = D (dt), 195 dn = F (dt); 196 if (! rst[tm]) 197 rst[tm] = []; 198 rst[tm][dn] = true; 199 }); 200 return rst; 201 } 202 //追記 203 static getDayPlan (obj, dt) { 204 let idx = [ ]; 205 let dn = F (dt); 206 for (let i = 0; i < 24; i+= 1) { 207 let h = ('0' + i).slice (-2); 208 idx.push (h + ':00'); 209 idx.push (h + ':30'); 210 } 211 return idx.map (i => [i, !!obj.plan[i][dn]]); 212 } 213 } 214 215 this.Schedule = Schedule; 216 } 217 218 //_____________ 219 function strDateJp (date) { 220 let [y, m, d] = ['getFullYear', 'getMonth', 'getDate'].map (fc => date[fc]()); 221 return `${y}${m+1}${d}`; 222 } 223 224 //___________________________ 225 function daysCount(key){ 226 227 if (window.matchMedia( "(min-width: 400px)" ).matches) { 228 /* ビューポートの幅が 400 ピクセル以上の場合のコードをここに */ 229 return 14; 230 } else { 231 /* ビューポートの幅は 400 ピクセル未満の場合のコードをここに */ 232 return 7; 233 } 234 } 235 236 const 237 BUSY = ['2019-02-19T14:30', '2019-02-21T14:30'], 238 plan = Schedule.convert (BUSY), 239 schedule = new Schedule (new Date, daysCount(), plan), 240 table = schedule.table; 241 242 table.border = 1; 243 244 // 昼休みがあるのが日火木土 245 schedule.setHoliday(); 246 247 //予約入った時 例) 2月24日 9時30 2時間コースと予約が入った時 248 schedule.setBook (new Date (2019, 2, 24, 9, 30), 120).remake (); 249 250 document 251 .querySelector ('#calendar') 252 .appendChild (table) 253 .addEventListener ('click', schedule, false); 254 255 table.addEventListener('click', event => { 256 const target = event.target; 257 258 if (target.nodeName !== 'TD') 259 return; 260 261 if ('◎' !== target.textContent) 262 return; 263 264 let booktime = parseInt (document.querySelector ('#booktime').value, 10); 265 266 let cur = schedule.current; 267 268 let x = target.cellIndex; 269 270 let y = target.parentNode.rowIndex - 2; 271 272 let tgt = new Date (cur); 273 tgt.setDate (tgt.getDate () + x -1); 274 275 let plan = Schedule.getDayPlan (schedule, tgt); 276 console.log(plan); 277 278 plan = plan.slice (18, 31); 279 280 let rng = booktime / 30 |0; 281 plan = plan.slice (y, y + rng); 282 283 if (rng === plan.length && plan.every (a=> !a[1])){ 284 var id = Array.from(document.getElementsByName('id'), x => x.value); 285 286 if (!(target.closest('tbody') && 1 <= target.cellIndex && target.cellIndex <= 14)) { 287 return true; 288 } 289 const 290 time = target.parentNode.cells[0].textContent, 291 table = target.closest('table'), 292 date = table.tHead.rows[1].cells[target.cellIndex - 1].textContent.replace(/[^0-9]/g, ''), 293 ymrow = table.tHead.rows[0], 294 ym = (target.cellIndex <= ymrow.cells[1].colSpan ? ymrow.cells[1] : ymrow.cells[2]).textContent; 295 296 let 297 value = ym + date + '日' + time, 298 param = document.getElementById( "booktime" ).value; 299 alert('JavaScriptのアラート'); 300 }else{ 301 alert("その時間帯は予約は出来ません。"); 302 } 303 }, false);

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

ES6

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

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

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

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

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

Lhankor_Mhy

2019/04/08 10:12

HTMLもご提示いただいたほうがよさそうな? 「次のviewに遷移」とありますが、「次のview」とは一体なんですか? 予約画面とかですか?
Lhankor_Mhy

2019/04/08 10:30

「次のview(今回はconsole.log('hego');を出力したい)に遷移」とありますが、ちょっとよくわからないです。 カレンダーをクリックした時に、 console.log('hego'); を実行すればいいのですか?
nanase21

2019/04/08 10:30

コメントありがとうございます。 javascriptと、<div id="calendar">でカレンダーを出力しているのでHTMLは<div id="calendar">だけになります。 次のviewは、予約画面になります。
Lhankor_Mhy

2019/04/08 10:36

> javascriptと、<div id="calendar">でカレンダーを出力しているのでHTMLは<div id="calendar">だけになります。 コードをざっくり見た感じ、document.getElementsByName('holiday') も参照していて、スクリプトでは生成していなさそうな感じです。 当方の勘違いかもしれませんので、そうでしたらコードのご解説をしていただきたいです。
nanase21

2019/04/08 10:38

分かりづらくさせてしまい、申し訳ございません。 本来の実装ではクリックすると遷移するのですが本質問では、遷移の代わりに、hogeと出力できたら大丈夫です。
Lhankor_Mhy

2019/04/08 10:42

もしかして、「次のview(今回はconsole.log('hego');を出力したい)に遷移」というのは、コード中にある、 window.location.href = `new.${id}`+`confirm?datetime=${value + '-' + param + '分コース' + id}`; console.log('hoge'); のことですか?
Lhankor_Mhy

2019/04/08 10:47

当方で試してみましたが、エラーが出るようです。 daysCount 関数が未定義でしたので、その部分のコードをご提示ください。
nanase21

2019/04/08 10:49

はい。エラーなくクリックできるとwindow.location.href から次のviewに遷移できるようになっていますが、そこを'hoge'と出力出来れば画面遷移もするはずなので質問の意図を少し改めさせて頂きました。 document.getElementsByName('holiday')に関しては、textfiledでvalueを取得している処理になりますが、今回はエラーと直接関わりないので考慮しなくても大丈夫です。
Lhankor_Mhy

2019/04/08 11:12

これ、質問者の環境では動作しているのですか? document.getElementById('acdn-target')がないというエラーになりました。 これを解決したい、ということでしょうか?
nanase21

2019/04/08 11:31

document.getElementById('acdn-target')は、不必要なコードでした。(削除し忘れていました) そのため、考慮しなく大丈夫です。
nanase21

2019/04/08 11:43 編集

このコメントは気になされないでください。
Lhankor_Mhy

2019/04/09 06:51

その行を削除したところ、document.querySelector('#booktime') がない、というエラーが出ました。 もう少し、質問を整理してみてはいかが?
nanase21

2019/04/09 09:11

失礼しました。その行ではコース時間について取得していました。 #booktimeでは、textfieldの値を取得しています。(例:60分)を取得していてその値とカレンダーを照らし合わせており予約可能かどうかを判定しています。
guest

回答1

0

ベストアンサー

すみませんが、何が聞きたいのかが理解できませんでした。
提示のソースをonloadで実行すると別のエラー(#booktimeが無い)が出ます。setHolidayではエラーは出ていないように見えます。

ご自分が何をしたいか、何に困っているかは、正確に把握されていますでしょうか?
画面遷移をしたいだけならば、エラーが出る処理を全てそぎ落とせば良いわけです。必要な処理なのにエラーが出てしまっているならば、その部分だけを抜き出して質問したほうがいいです。

直接の解決方法ではないですが、以下を試してみると自己解決できるかもしれません。

  • フローチャートを書き出してみる
  • 変数、関数には正しく名づける
  • HTMLの生成と内部処理を分ける
  • コメントを書く

投稿2019/04/09 00:54

moredeep

総合スコア1507

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問