前提
予約カレンダーっぽいものをjasvascriptで描画しています。
コード
html
1<div id="calendar"></div>
js
1 window.onload = function() { 2 { 3 const 4 day_name = [ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'], 5 day_jname = ['(日)', '(月)', '(火)', '(水)', '(木)', '(金)', '(土)'], 6 doc = document, 7 DEF_OPTION = { }; 8 9 const 10 A = (e, ...a) => a.map (a => e.appendChild (doc.createElement (a))), 11 B = (d, n) => d.setDate (d.getDate () + n), 12 C = d => [d.getFullYear (), '年', d.getMonth () + 1 , '月'].join (''), 13 D = d => [('0' + d.getHours ()).slice (-2), ('0' + d.getMinutes ()).slice (-2)].join (':'), 14 E = (e, d) => { 15 let 16 [a,,b] = A (e, 'label', 'br', 'label'), 17 w = d.getDay () ; 18 a.textContent = d.getDate (); 19 b.textContent = day_jname[w]; 20 e.classList.add (day_name[w]); 21 }, 22 F = d => { 23 let m = d.getMonth (); 24 return [0,31,59,90,120,151,181,212,243,273,304,334][m] + d.getDate() - 1 + 25 (new Date (d.getFullYear (), m + 1,0) === 29 && 0 < m); 26 }, 27 H = d => new Date (d.getFullYear (), d.getMonth (), d.getDate ()), 28 I = d => [('0' + d.getUTCHours ()).slice (-2), ('0' + d.getUTCMinutes ()).slice (-2)].join (':'); 29 30 //_____________ 31 32 33 class Schedule { 34 35 constructor (date = new Date, range = 7, plan = [ ], option = DEF_OPTION) { 36 this.current = H (date);//表の左端の日付、これを基準とする 37 this.date = H (date); 38 this.range = range; //何日分を表示するか 39 this.plan = plan; //予定表が構成される 40 this.table = document.createElement ('table'); 41 this.option = Object.assign ({ }, option); 42 43 this.remake (); 44 } 45 46 47 add (day = this.range) { 48 let d = H (this.current); 49 d.setDate (d.getDate () + day); 50 if (+this.date <= +d) 51 this.current = d; 52 return this; 53 } 54 55 //Booking 56 setBook (date, occupancyTime) {// 予約日時,占有時間(分) 57 let 58 current = new Date (date), 59 dayNo = F (current), 60 sTime = 30,//30間隔 61 step = new Date (Date.UTC (1970,0,1, 0, sTime)), 62 cnt = Math.floor (occupancyTime / sTime); 63 64 for (let i = 0; i < cnt; i++) { 65 let time = D (current); 66 if (! this.plan[time]) 67 this.plan[time] = [ ]; 68 this.plan[time][dayNo] = true; 69 current.setTime (+current +(+step)); 70 } 71 return this; 72 } 73 74 remake () { 75 let t = this.table; 76 t.innerText = ''; 77 78 let 79 h = t.createTHead (), 80 tr0 = h.insertRow (-1), 81 tr1 = h.insertRow (-1), 82 d = H (this.current), 83 s = tr0.insertCell (-1), 84 c = 1, 85 m = d.getMonth (); 86 87 for (let i = 0; i < this.range; i++, c++, B (d, 1)) { 88 let td = tr1.insertCell (-1); 89 if (m !== d.getMonth ()) { 90 s.colSpan = c - 1; 91 s = tr0.insertCell (-1); 92 m = d.getMonth (); 93 c = 1; 94 } 95 s.textContent = C (d); 96 E (td, d); 97 } 98 s.colSpan = c - 1; 99 100 let e = tr0.insertCell (0); 101 e.textContent = '前の一週間'; 102 e.classList.add ('button'); 103 e.rowSpan = 2; 104 this.prev_btn = e; 105 106 e = tr0.insertCell (-1); 107 e.textContent = '次の一週間'; 108 e.classList.add ('button'); 109 e.rowSpan = 2; 110 this.next_btn = e; 111 112 //__ 113 let 114 begin = new Date (Date.UTC (1970,0,1, 9, 0)),//列のスタート時間 115 end = new Date (Date.UTC (1970,0,1,15, 30)),//列の終了時間 116 step = new Date (Date.UTC (1970,0,1, 0,30)),//列の間隔調整時間 117 o = F (this.current), 118 [tb] = A (t, 'tbody'); 119 120 for (let d = begin; d < end; d = new Date (+step + (+d))) { 121 let 122 b = I (d), 123 c = this.plan[b] || [], 124 tr = tb.insertRow (-1); 125 126 tr.insertCell (-1).textContent = b; 127 for (let i = 0; i < this.range; i++) { 128 let td = tr.insertCell (-1); 129 if (c[o + i]) { 130 td.textContent = '-'; 131 td.classList.add ('invalid'); 132 } 133 else { 134 td.textContent = '◎'; 135 td.classList.add ('valid'); 136 } 137 } 138 tr.insertCell (-1).textContent = b; 139 } 140 141 return this; 142 } 143 144 145 handleEvent (event) { 146 let t = event.target; 147 if (t === this.prev_btn) this.add (-this.range).remake (); 148 if (t === this.next_btn) this.add ( this.range).remake (); 149 150 let cbfunc = this.option.handleEvent; 151 if ('function' === typeof cbfunc) 152 cbfunc.call (this, event); 153 } 154 155 156 static convert (ary) { 157 let rst = { }; 158 ary.forEach (a => { 159 let 160 dt = new Date (a + ':00.000+09:00'), 161 tm = D (dt), 162 dn = F (dt); 163 if (! rst[tm]) 164 rst[tm] = []; 165 rst[tm][dn] = true; 166 }); 167 return rst; 168 } 169 //追記 170 static getDayPlan (obj, dt) { 171 let idx = [ ]; 172 let dn = F (dt); 173 for (let i = 0; i < 24; i+= 1) { 174 let h = ('0' + i).slice (-2); 175 idx.push (h + ':00'); 176 idx.push (h + ':30'); 177 } 178 console.log(obj.plan); 179 return idx.map (i => [i, !!obj.plan[i][dn]]); 180 } 181 } 182 183 this.Schedule = Schedule; 184 } 185 186 //_____________ 187 function strDateJp (date) { 188 let [y, m, d] = ['getFullYear', 'getMonth', 'getDate'].map (fc => date[fc]()); 189 return `${y}年${m+1}月${d}日`; 190 } 191 192 function daysCount(key){ 193 return 14; 194 } 195 196 const 197 BUSY = ['2019-09-26T14:30', '2019-09-25T09:30'], 198 plan = Schedule.convert (BUSY), 199 schedule = new Schedule (new Date, daysCount(), plan), 200 table = schedule.table; 201 202 table.border = 1; 203 204 //予約入った時 例) 9月27日 9時30 2時間コースと予約が入った時 205 schedule.setBook (new Date (2019, 8, 27, 9, 30), 120).remake (); 206 //サーバー側から返ってくるデータ 207 //下記の二次元配列を上記にいい感じに納めたい。 208 [['2019-09-26T14:30', 60], ['2019-09-27T09:30', 60], ['2019-09-28T14:30', 30]] 209 210 //schedule.remake (); //単独で表を更新 211 document.querySelector ('#calendar').appendChild (table) 212 213 }
#実現したいこと
該当箇所
js
1//予約入った時 例) 9月27日 9時30 2時間コースと予約が入った時 2schedule.setBook (new Date (2019, 8, 27, 9, 30), 120).remake (); 3//サーバー側から返ってくるデータ 4//下記の二次元配列を上記にいい感じに納めたい。 5[['2019-09-26T14:30', 60], ['2019-09-27T09:30', 60], ['2019-09-28T14:30', 30]]
サーバーから上記のような二次元配列を返しています。
上記の二次元配列をfor文で回して要素数の分だけschedule.setBookを生成したい。
イメージ
js
1date = [['2019-09-26T13:30', 120], ['2019-09-27T09:30', 60], ['2019-09-28T14:30', 30]] 2//処理上、月だけ 当月(9月) - 1 = 当月(9月)をする必要がある。 3schedule.setBook (new Date (2019, 8, 26, 13, 30), 120).remake (); 4schedule.setBook (new Date (2019, 8, 27, 09, 30), 60).remake (); 5schedule.setBook (new Date (2019, 8, 28, 14, 30), 30).remake (); 6
#困っていること
サーバーから返ってくるデータをschdule.setBookいい感じに収めることができずにいます。
js
1for (let i=1;i<date.count;i++){ 2//sliceメソッドを使って無理くりデータの中身をschdule.setBookに詰めることは出来るのですが、書き方があまり綺麗じゃないので皆さんからご教示頂きたいです。 3}
#試したこと
js
1 date = [['2019-09-26T13:30', 120], ['2019-09-27T09:30', 60], ['2019-09-28T14:30', 30]] 2 date.forEach((value) => { 3 schedule.setBook (value).remake (); 4 });
foreach
で配列を回して、schedule.setBook
に値を入れてみましたが、カレンダーに反映されませんでした。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/25 02:06 編集