実現したいこと
予約がすでに埋まっている時間帯はその時間帯をクリックしても反応しないようにしたい。
例えば、12時が既に予約がされている時、新規の申込者が120分コースを選択した時に10時より前の時間を選択せず、10:30や11:00や11:30を選択しようとクリックした時に確認画面に飛ばないようにしたい。
###試した事
他の質問やネットの記事を参考にしてカレンダーをクリックすると,画面遷移し、パラメーターに値を乗せて遷移先のテキストフィールドに予約したい時間帯を反映させる事ができた。
###困っている事
予約が埋まっている時間を取得し、どのような処理を書けばいいか分からなく困っています。
html
1<p>予約時間: <input type="text" name="booktime" value="120分" class= "booktime" id="booktime" readonly></p> 2 3 <p>選択した日時: <input type="text" class= "text" id="acdn-target" onselect="click_date" readonly></p> 4<div id="calendar"></div>
js
1{ 2 const 3 day_name = [ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'], 4 day_jname = ['(Sun.)', '(Mon.)', '(Tue.)', '(Wed.)', '(Thu.)', '(Fri.)', '(Sat.)'], 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 Shedule { 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 86 87 setLunchTime (...dayNo) { 88 let 89 year = this.current.getFullYear (), 90 start = new Date (year, 0, 1), 91 end = new Date (year, 12, 1), 92 93 b = new Date (Date.UTC (1970,0,1, 12, 0)),//列のスタート時間 94 e = new Date (Date.UTC (1970,0,1,13, 30)),//列の終了時間 95 s = new Date (Date.UTC (1970,0,1, 0,30));//列の感覚調整時間 96 97 dayNo.forEach (n => { 98 let current = new Date (start); 99 current.setDate (7 - current.getDate () + n); 100 101 for (; current < end; current.setDate (current.getDate () + 7)) { 102 let idx = F (current); 103 104 for (let c = b; c < e; c = new Date (+s + (+c))) { 105 let key = I (c); 106 if (! this.plan[key]) 107 this.plan[key] = [ ]; 108 this.plan[key][idx] = true; 109 } 110 } 111 }); 112 113 return this; 114 } 115 116 117 //Booking 118 setBook (date, occupancyTime) {// 予約日時,占有時間(分) 119 let 120 current = new Date (date), 121 dayNo = F (current), 122 sTime = 30,//30間隔 123 step = new Date (Date.UTC (1970,0,1, 0, sTime)), 124 cnt = Math.floor (occupancyTime / sTime); 125 126 for (let i = 0; i < cnt; i++) { 127 let time = D (current); 128 if (! this.plan[time]) 129 this.plan[time] = [ ]; 130 this.plan[time][dayNo] = true; 131 current.setTime (+current +(+step)); 132 } 133 return this; 134 } 135 136 remake () { 137 this.prev_btn = this.next_btn = null; 138 let t = this.table; 139 [...t.childNodes].forEach (e => e.remove ()); 140 141 let 142 h = t.createTHead (), 143 tr0 = h.insertRow (-1), 144 tr1 = h.insertRow (-1), 145 d = H (this.current), 146 s = tr0.insertCell (-1), 147 c = 1, 148 m = d.getMonth (); 149 150 for (let i = 0; i < this.range; i++, c++, B (d, 1)) { 151 let td = tr1.insertCell (-1); 152 if (m !== d.getMonth ()) { 153 s.colSpan = c - 1; 154 s = tr0.insertCell (-1); 155 m = d.getMonth (); 156 c = 1; 157 } 158 s.textContent = C (d); 159 E (td, d); 160 } 161 s.colSpan = c - 1; 162 163 let e = tr0.insertCell (0); 164 e.textContent = '前の一週間'; 165 e.classList.add ('button'); 166 e.rowSpan = 2; 167 this.prev_btn = e; 168 169 e = tr0.insertCell (-1); 170 e.textContent = '次の一週間'; 171 e.classList.add ('button'); 172 e.rowSpan = 2; 173 this.next_btn = e; 174 175 //__ 176 let 177 begin = new Date (Date.UTC (1970,0,1, 9, 0)),//列のスタート時間 178 end = new Date (Date.UTC (1970,0,1,15, 30)),//列の終了時間 179 step = new Date (Date.UTC (1970,0,1, 0,30)),//列の感覚調整時間 180 o = F (this.current), 181 rst = [ ]; 182 183 for (let d = begin; d < end; d = new Date (+step + (+d))) { 184 let 185 a = new Array (this.rangi), 186 b = I (d), 187 c = this.plan[b] || []; 188 189 for (let i = 0; i < this.range; i++) 190 a[i] = c[o + i] ? '-' : '◎'; 191 192 rst.push ([b, ...a, b]); 193 } 194 195 let [tb] = A (t, 'tbody'); 196 rst.forEach (r => { 197 let tr = tb.insertRow (-1); 198 r.forEach (c => tr.insertCell (-1).textContent = c) 199 }); 200 201 return this; 202 } 203 204 205 handleEvent (event) { 206 let t = event.target; 207 if (t === this.prev_btn) this.add (-this.range).remake (); 208 if (t === this.next_btn) this.add ( this.range).remake (); 209 210 let cbfunc = this.option.handleEvent; 211 if ('function' === typeof cbfunc) 212 cbfunc.call (this, event); 213 } 214 215 216 static convert (ary) { 217 let rst = { }; 218 ary.forEach (a => { 219 let 220 dt = new Date (a + ':00.000+09:00'), 221 tm = D (dt), 222 dn = F (dt); 223 if (! rst[tm]) 224 rst[tm] = []; 225 rst[tm][dn] = true; 226 }); 227 return rst; 228 } 229 230 } 231 232 this.Shedule = Shedule; 233} 234 235//_____________ 236function strDateJp (date) { 237 let [y, m, d] = ['getFullYear', 'getMonth', 'getDate'].map (fc => date[fc]()); 238 return `${y}年${m+1}月${d}日`; 239} 240 241 242//___________________________ 243 244const 245 BUSY = ['2019-02-19T14:30', '2019-02-21T14:30'], 246 plan = Shedule.convert (BUSY), 247 shedule = new Shedule (new Date, 7, plan), 248 table = shedule.table; 249 250table.border = 1; 251//月水金を休日 昼休みがあるのが日火木土 252shedule.setHoliday (0, 6).setLunchTime (0, 1, 2, 3, 5, 4, 6)//..remake (); 253 254 //予約入った時 例) 2月24日 9時30 2時間コースと予約が入った時 255shedule.setBook (new Date (2019, 1, 19, 9, 30), 30).remake (); 256shedule.setBook (new Date (2019, 1, 24, 9, 30), 120).remake (); 257 258//shedule.remake (); //単独で表を更新 259document 260 .querySelector ('#calendar') 261 .appendChild (table) 262 .addEventListener ('click', shedule, false); 263 264//クリック時の処理 265document.getElementById ('acdn-target').value = strDateJp (shedule.current); 266 267document.querySelector('#calendar').addEventListener('click', event => { 268 const target = event.target; 269 if (target.nodeName.toLowerCase() !== 'td') { 270 return true; 271 } 272 273 if (!(target.closest('tbody') && 1 <= target.cellIndex && target.cellIndex <= 7)) { 274 return true; 275 } 276 277 const time = target.parentNode.cells[0].textContent; 278 const table = target.closest('table'); 279 const date = table.tHead.rows[1].cells[target.cellIndex - 1].textContent.slice(0,-6); 280 const ymrow = table.tHead.rows[0]; 281 const ym = (target.cellIndex <= ymrow.cells[1].colSpan ? ymrow.cells[1] : ymrow.cells[2]).textContent; 282 document.getElementById('acdn-target').value = ym + date + '-' + time; 283 284 const value = ym + date + ' ' + time; 285 var id = Array.from(document.getElementsByName('id'), x => x.value); 286 //確認ページに飛ぶ 287 window.location.href = `new.${id}`+`confirm?datetime=${value}`; 288 289 //ここで予約時間を取得 290 var str = document.getElementById( "booktime" ).value, 291 edit_str = str.slice(0,-1); 292 console.log(edit_str); 293 294 295 return true; 296}, false);
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/03/22 01:06
退会済みユーザー
2019/03/22 01:25