PageSourceSearch

https://cottage.co.jp/js/yprox_searchForm.js

js cottage.co.jp collected 2026-10-08 10:55:59 UTC 41,689 bytes, 801 lines download raw bytes

1/**
2 *
3 *   @author abilive
4 *   @file yprox_searchForm.js
5 *   @version 1.0.1
6 *   @requires dayjs-1.11.7 (MIT License)
7 *   @requires flatpickr-4.6.9 (MIT License)
8 *
9 *   @hitory
10 *   2023.12.07 一部android端末にてカレンダーが表示されない不具合を修正
11 *   2023.12.25 チェックイン日だけを選択して検索された場合に、泊数初期値で検索されるように修正
12 *   2023.12.25 チェックイン日を指定した時に、チェックアウト日を選択するような案内文を追加
13 *
14 */
15
16// リサイズ用のタイマー変数
17let yprox_wr_queue = null;
18let yprox_wr_currentWidth = window.innerWidth;
19let yprox_wr_currentHeight = window.innerHeight;
20// チェックアウト日の案内文用の変数
21let textCheckInnOut = '';
22let flagCalendarHideCheckOutText = false;
23
24/**
25 * DOMContentLoaded
26 */
27document.addEventListener('DOMContentLoaded', function () {
28    const nInitDay = 0;		// 日付(○日後) ※本日の場合は 0 //※20240507ダイレックスにて修正
29    const nInitPer = 4;
29		// 人数 //※20240507ダイレックスにて修正
30    const nInitStay = 1;		// 泊数
31    const nInitRoom = 1;		// 部屋数
32
33    const nOpMaxYear = 2;			// 日付(今年も含めて何年分表示するか)
34    const nOpMaxPer = 20;		// 人数(最大選択値) //※20240507ダイレックスにて修正
35    const nOpMaxNights = 10;		// 泊数(最大選択値)
36    const nOpMaxRoom = 20;		// 部屋数(最大選択値)
37
38    let flagNoDate = false;		// 初期表示日付(日付なし)の場合は true 、formタグへ data-no-date を付与で日付なし
39
40    let flagCalendar = true;   // カレンダーを表示する場合は true 、formタグへ data-calendar を付与でカレンダー表示 //※20240507ダイレックスにて修正
41    flagCalendarHideCheckOutText = false; // チェックアウト日を選択するような案内文を非表示にする場合は true 、formタグへ data-hide-checkout-text を付与で非表示
42
43    const windowMobileWidth = 767; //モバイルの画面幅
44
45    const nInitCalendar = 2; //カレンダーの月の表示数
46    const nInitCalendarMobile = 1; //windowMobileWidth以下の画面幅でのカレンダーの月の表示数
47
48    const calendarSpanStr = ' - '; //カレンダーの日付の間に入れる文字 初期表示にしたい場合は null
49
50    const wr_wait = 600; // リサイズイベント発生時の待ち時間
51    // チェックアウト日を指定した時に、チェックアウト日を選択するような案内文
52    const textCheckInnOutJP = `続けてチェックアウト日を<br>選択してください`;
53    const textCheckInnOutEN = `Please select your check-out date`;
54    const textCheckInnOutKR = `체크아웃 날짜를<br>선택해 주세요`;
55    const textCheckInnOutCN = `請選擇退房日期`;
56    const textCheckInnOutTW = `請選擇退房日期`;
57    textCheckInnOut = textCheckInnOutEN;
58
59    /**
60     * 日付計算用のscriptのパス
61     * CDNをご希望の場合は以下のパスをご利用ください
62     * https://cdn.jsdelivr.net/npm/dayjs@1/dayjs.min.js
63     */
64    const dayjsPath = '/js/dayjs.min.js'; //日付計算用のscriptのパス	  ※20240507ダイレックスにて修正
65    /**
66     * カレンダー用cssのパス
67     * CDNをご希望の場合は以下のパスをご利用ください
68     * https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css
69     */
70    const calendarCss = '/css/flatpickr.min.css';	  //※20240507ダイレックスにて修正
71    /**
72     * カレンダー用jsのパス
73     * CDNをご希望の場合は以下のパスをご利用ください
74     * https://cdn.jsdelivr.net/npm/flatpickr
75     */
76    const calendarJs = '/js/flatpickr.js'; //※20240507ダイレックスにて修正
77    /**
78     * カレンダー用の言語ファイルのパス
79     * CDNをご希望の場合は以下のパスをご利用ください
80     * ※ブラウザの言語設定によって表示される言語が変わります
81     * https://cdn.jsdelivr.net/npm/flatpickr/dist/l10n/ja.js
82     * https://cdn.jsdelivr.net/npm/flatpickr/dist/l10n/ko.js
83     * https://cdn.jsdelivr.net/npm/flatpickr/dist/l10n/zh.js
84     * https://cdn.jsdelivr.net/npm/flatpickr/dist/l10n/zh-tw.js
85     */
86    const calendarLangJa = '/js/l10n/ja.js'; //カレンダー用の言語ファイルのパス //※20240507ダイレックスにて修正
87    const calendarLangKo = '/js/l10n/ko.js'; //韓国語 //※20240507ダイレックスにて修正
88    const calendarLangZh = '/js/l10n/zh.js'; //中国語(簡体字) //※20240507ダイレックスにて修正
89    const calendarLangZh_TW = '/js/l10n/zh-tw.js'; //中国語(繁体字) //※20240507ダイレックスにて修正
90
91    const dayjsJa = '/js/locale/ja.js'; //カレンダー用の言語ファイルのパス //※20240507ダイレックスにて修正
92    const dayjsKo = '/js/locale/ko.js'; //韓国語 //※20240507ダイレックスにて修正
93    const dayjsZh = '/js/locale/zh-cn.js'; //中国語(簡体字) //※20240507ダイレックスにて修正
94    const dayjsTW = '/js/locale/zh-tw.js'; //中国語(繁体字) //※20240507ダイレックスにて修正
95
96    //日付計算用のscriptを読み込む
97    const scriptDayjs = document.createElement('script'); //script要素を作成
98    document.head.appendChild(scriptDayjs); //head要素にscript要素を追加
99    //日付計算用のscriptの読み込み完了
100    scriptDayjs.onload = function () {
101        //カレンダーを表示が有効に設定してあればscriptを読み込む
102        const Body = document.body; // body
103        const searchForm = Body.querySelectorAll('.js-yprox-searchForm'); // search form
104        const lenSearchForm = searchForm.length; // formの数
105        // formの数だけループ
106        for (let i = 0; i < lenSearchForm; i++) {
107            const form = searchForm[i]; // form
108            if (!flagCalendar) {
109                flagCalendar = form.getAttribute('data-calendar') === '' ? true : false; //カレンダーを表示するかどうか
110                flagCalendarHideCheckOutText = form.getAttribute('data-hide-checkout-text') === '' ? true : false; //カレンダーを表示するかどうか
111            }
112        }
113        //カレンダーを表示する場合はscriptを読み込む
114        if (flagCalendar) {
115            //cssを読み込む
116            const link = document.createElement('link'); //link要素を作成
117            link.rel = 'stylesheet'; //rel属性をstylesheetに
118            document.head.appendChild(link); //head要素にlink要素を追加
119            //cssの読み込みが完了したらscriptを読み込む
120            link.onload = function () {
121                //scriptを読み込む
122                let userLanguage = navigator.language; //言語を取得
123                if (String(userLanguage).indexOf('ja') != -1 || String(userLanguage).indexOf('ja-JP') != -1 || String(userLanguage).indexOf('zh-CN') != -1 || String(userLanguage).indexOf('ko') != -1 || String(userLanguage).indexOf('ko-KR') != -1 || String(userLanguage).indexOf('zh-TW') != -1) {
124                    //英語以外の場合
125                    const script = document.createElement('script'); //script要素を作成
126                    const scriptDayjs = document.createElement('script'); //script要素を作成
127                    document.head.appendChild(script); //head要素にscript要素を追加
128                    document.head.appendChild(scriptDayjs);
129                    //言語ファイルの読み込み完了
130                    script.onload = function () {
131                        const script2 = document.createElement('script'); //script要素を作成
132                        document.head.appendChild(script2); //head要素にscript要素を追加
133                        //カレンダーの読み込み完了
134                        script2.onload = function () {
135                            yproxSearchFormInit(nInitDay, nInitPer, nInitStay, nInitRoom, nOpMaxYear, nOpMaxPer, nOpMaxNights, nOpMaxRoom, flagNoDate, flagCalendar, nInitCalendar, calendarSpanStr, windowMobileWidth, wr_wait, nInitCalendarMobile);
136                        };
137                        script2.src = calendarJs; //src属性にjsのパスを指定
138                    }
139                    switch (userLanguage) {
140                        case 'ja':
141                            //日本語
142                            script.src = calendarLangJa; //src属性にjsのパスを指定
143                            scriptDayjs.src = dayjsJa; //src属性にjsのパスを指定
144                            textCheckInnOut = textCheckInnOutJP;
145                            break;
146                        case 'ja-JP':
147                            //日本語
148                            script.src = calendarLangJa; //src属性にjsのパスを指定
149                            scriptDayjs.src = dayjsJa; //src属性にjsのパスを指定
150                            textCheckInnOut = textCheckInnOutJP;
151                            break;
152                        case 'ko':
153                            //韓国語
154                            script.src = calendarLangKo; //src属性にjsのパスを指定
155                            scriptDayjs.src = dayjsKo; //src属性にjsのパスを指定
156                            textCheckInnOut = textCheckInnOutKR;
157                            break;
158                        case 'ko-KR':
159                            //韓国語
160                            script.src = calendarLangKo; //src属性にjsのパスを指定
161                            scriptDayjs.src = dayjsKo; //src属性にjsのパスを指定
162                            textCheckInnOut = textCheckInnOutKR;
163                            break;
164                        case 'zh-CN':
165                            //中国語(簡体字)
166                            script.src = calendarLangZh; //src属性にjsのパスを指定
167                            scriptDayjs.src = dayjsZh; //src属性にjsのパスを指定
168                            textCheckInnOut = textCheckInnOutCN;
169                            break;
170                        case 'zh-TW':
171                            //中国語(繁体字)
172                            script.src = calendarLangZh_TW; //src属性にjsのパスを指定
173                            scriptDayjs.src = dayjsTW; //src属性にjsのパスを指定
174                            textCheckInnOut = textCheckInnOutTW;
175                            break;
176                        default:
177                            //英語
178                            textCheckInnOut = textCheckInnOutEN;
179                            break;
180                    }
181                } else {
182                    //英語の場合は言語ファイルは読み込まない
183                    const script2 = document.createElement('script'); //script要素を作成
184                    document.head.appendChild(script2); //head要素にscript要素を追加
185                    //カレンダーの読み込み完了
186                    script2.onload = function () {
187                        yproxSearchFormInit(nInitDay, nInitPer, nInitStay, nInitRoom, nOpMaxYear, nOpMaxPer, nOpMaxNights, nOpMaxRoom, flagNoDate, flagCalendar, nInitCalendar, calendarSpanStr, windowMobileWidth, wr_wait, nInitCalendarMobile);
188                    };
189                    script2.src = calendarJs; //src属性にjsのパスを指定
190                }
191            };
192            link.href = calendarCss; //href属性にcssのパスを指定
193        } else {
194            //カレンダーを表示しない場合はそのまま検索フォームの初期化
195            yproxSearchFormInit(nInitDay, nInitPer, nInitStay, nInitRoom, nOpMaxYear, nOpMaxPer, nOpMaxNights, nOpMaxRoom, flagNoDate, flagCalendar, nInitCalendar, calendarSpanStr, windowMobileWidth, wr_wait, nInitCalendarMobile);
196        }
197    };
198    scriptDayjs.src = dayjsPath; //src属性にjsのパスを指定
199});
200
201/**
202 * functions
203 */
204
205/**
206 * 検索フォームの初期化
207 * @param nInitDay - 日付(○日後) ※本日の場合は 0
208 * @param nInitPer - 人数
209 * @param nInitStay - 泊数
210 * @param nInitRoom - 部屋数
211 * @param nOpMaxYear - 日付(今年も含めて何年分表示するか)
212 * @param nOpMaxPer - 人数(最大選択値)
213 * @param nOpMaxNights - 泊数(最大選択値)
214 * @param nOpMaxRoom - 部屋数(最大選択値)
215 * @param flagNoDate - 日付(日付なし)の有無
216 * @param flagCalendar - カレンダーを表示するかどうか
217 * @param nInitCalendar - カレンダーの月の表示数
218 * @param calendarSpanStr - カレンダーの日付の間に入れる文字
219 * @param windowMobileWidth - ウィンドウサイズ(モバイル)
220 * @param wr_wait - リサイズイベント発生時の待ち時間
221 */
222function yproxSearchFormInit(nInitDay, nInitPer, nInitStay, nInitRoom, nOpMaxYear, nOpMaxPer, nOpMaxNights, nOpMaxRoom, flagNoDate, flagCalendar, nInitCalendar, calendarSpanStr, windowMobileWidth, wr_wait, nInitCalendarMobile) {
223    const Body = document.body; // body
224    const searchForm = Body.querySelectorAll('.js-yprox-searchForm'); // search form
225    const lenSearchForm = searchForm.length; // formの数
226    const userLanguage = navigator.language; //言語を取得
227    let strPersons = ''; // 人数の単位
228    let strNights = ''; // 泊数の単位
229    let strRooms = ''; // 部屋数の単位
230    let calendarLocale = null; // カレンダーの言語
231    const rangeSeparators = ['から', 'to', '至', '~']; // カレンダーの日付の間に入れる文字
232    const yproXClendars = [];
233    if (String(userLanguage).indexOf('ja') != -1 || String(userLanguage).indexOf('ja-JP') != -1 || String(userLanguage).indexOf('zh-CN') != -1 || String(userLanguage).indexOf('ko') != -1 || String(userLanguage).indexOf('ko-KR') != -1 || String(userLanguage).indexOf('zh-TW') != -1) {
234        // 言語が英語以外の場合
235        switch (userLanguage) {
236            case 'ja':
237                // 日本語の場合
238                if (flagCalendar) {
239                    calendarLocale = ja.Japanese;
240                }
241                strPersons = '名';
242                strNights = '泊';
243                strRooms = '部屋';
244                dayjs.locale('ja'); //日本語に設定
245                break;
246            case 'ja-JP':
247                // 日本語の場合
248                if (flagCalendar) {
249                    calendarLocale = ja.Japanese;
250                }
251                strPersons = '名';
252                strNights = '泊';
253                strRooms = '部屋';
254                dayjs.locale('ja'); //日本語に設定
255                break;
256            case 'ko':
257                // 韓国語の場合
258                if (flagCalendar) {
259                    calendarLocale = ko.Korean;
260                }
261                strPersons = '명';
262                strNights = '박';
263                strRooms = 'ë°©';
264                dayjs.locale('ko'); //日本語に設定
265                break;
266            case 'ko-KR':
267                // 韓国語の場合
268                if (flagCalendar) {
269                    calendarLocale = ko.Korean;
270                }
271                strPersons = '명';
272                strNights = '박';
273                strRooms = 'ë°©';
274                dayjs.locale('ko'); //日本語に設定
275                break;
276            case 'zh-CN':
277                // 簡体字中国語の場合
278                if (flagCalendar) {
279                    calendarLocale = zh.Mandarin;
280                }
281                strPersons = '名';
282                strNights = '晚';
283                strRooms = '间';
284                dayjs.locale('zh-cn'); //日本語に設定
285                break;
286            case 'zh-TW':
287                // 繁体字中国語の場合
288                if (flagCalendar) {
289                    calendarLocale = window['zh-tw'].MandarinTraditional;
290                }
291                strPersons = '名';
292                strNights = '晚';
293                strRooms = '間';
294                dayjs.locale('zh-tw'); //日本語に設定
295                break;
296            default:
297                dayjs.locale('en'); //英語に設定
298                break;
299        }
300    } else {
301        // 言語が英語の場合
302        strPersons = 'guests';
303        strNights = 'nights';
304        strRooms = 'room';
305    }
306    // formの数だけループ
307    for (let i = 0; i < lenSearchForm; i++) {
308        const form = searchForm[i]; // form
309        flagCalendar = form.getAttribute('data-calendar') === '' ? true : false; //カレンダーを表示するかどうか
310        flagNoDate = form.getAttribute('data-no-date') === '' ? true : false; //日付なしを表示するかどうか
311        // 日付の初期値を設定
312        const d = dayjs().add(nInitDay, 'day'); // dayjs object
313        let nYear = d.year(); // å¹´
314        let nMonth = d.month() + 1; // 月
315        let nDay = d.date(); // 日
316        const formWrpCheckInn = form.querySelector('.js-yprox-searchForm__wrpCheckInn'); // 日付のラッパー
317        const formCheckInn = form.querySelector('.js-yprox-searchForm__checkin'); //日付
318        const formBoxCheckInnDay = form.querySelector('.js-yprox-searchForm__boxCheckin-day'); // 日付(日)のラッパー
319        const formCheckInnDay = form.querySelector('.js-yprox-searchForm__checkin-day'); // 日付(日)
320        const formBoxCheckInnMonth = form.querySelector('.js-yprox-searchForm__boxCheckin-month'); // 日付(月)のラッパー
321        const formCheckInnMonth = form.querySelector('.js-yprox-searchForm__checkin-month'); // 日付(月)
322        const formBoxCheckInnYear = form.querySelector('.js-yprox-searchForm__boxCheckin-year'); // 日付(年)
323        const formCheckInnYear = form.querySelector('.js-yprox-searchForm__checkin-year');// 日付(年)
324        const formNoDate = form.querySelector('.js-yprox-searchForm__noDate'); // 日付(日付なし)
325        const formCheckInnOut = form.querySelector('.js-yprox-searchForm__checkInnOut'); // カレンダー
326        // 人数
327        const formAdults = form.querySelector('.js-yprox-searchForm__adults');
328        const formWrpAdults = form.querySelector('.js-yprox-searchForm__wrpAdults');
329        //nOpMaxPerの数だけoptionを追加
330        if (formAdults) {
331            for (let j = 1; j <= nOpMaxPer; j++) {
332                const Option = document.createElement('option');
333                Option.value = j;
334                Option.textContent = j + strPersons;
335                formAdults.appendChild(Option);
336                if (j === nInitPer) {
337                    Option.setAttribute('selected', 'selected');
338                }
339            }
340        }
341        // 泊数
342        const formNights = form.querySelector('.js-yprox-searchForm__nights');
343        const formWrpNights = form.querySelector('.js-yprox-searchForm__wrpNights');
344        //nOpMaxNightsの数だけoptionを追加
345        if (formNights) {
346            for (let j = 1; j <= nOpMaxNights; j++) {
347                const Option = document.createElement('option');
348                Option.value = j;
349                Option.textContent = j + strNights;
350                formNights.appendChild(Option);
351                if (j === nInitStay) {
352                    Option.setAttribute('selected', 'selected');
353                }
354            }
355        }
356        // 部屋数
357        const formRoom = form.querySelector('.js-yprox-searchForm__rooms');
358        const formWrpRoom = form.querySelector('.js-yprox-searchForm__wrpRooms');
359        if (flagCalendar) {
360            // カレンダーを表示する場合
361            formBoxCheckInnYear && formWrpCheckInn.removeChild(formBoxCheckInnYear); // 年のラッパーを削除
362            formBoxCheckInnMonth && formWrpCheckInn.removeChild(formBoxCheckInnMonth); // 月のラッパーを削除
363            formBoxCheckInnDay && formWrpCheckInn.removeChild(formBoxCheckInnDay); // 日のラッパーを削除
364            formWrpNights && formWrpNights.parentNode.removeChild(formWrpNights); // 泊数のラッパーを削除
365            //デフォルトの泊数は削除したので検索用にinputを追加
366            const formNights = document.createElement('input');
367            formNights.type = 'hidden';
368            formNights.name = 'nights';
369            formNights.value = nInitStay;
370            formNights.classList.add('js-yprox-searchForm__nights');
371            formWrpCheckInn.appendChild(formNights);
372            // カレンダーの初期値を設定
373            formCheckInn.value = d.format('YYYYMMDD'); // 日付
374            const fp = flatpickr(formCheckInnOut, {
375                locale: calendarLocale, // 言語
376                mode: "range", // 日付の範囲を選択
377                dateFormat: 'Y/m/d(D)', // 日付のフォーマット
378                defaultDate: [dayjs().add(nInitDay, 'day').format('YYYY/MM/DD'), dayjs().add(nInitDay + 1, 'day').format('YYYY/MM/DD')], // 初期値
379                showMonths: window.innerWidth > windowMobileWidth ? nInitCalendar : nInitCalendarMobile, // 月の表示数
380                minDate: 'today', // 今日以降の日付のみ選択可能
381                maxDate: dayjs().add(nOpMaxYear - 1, 'year').format('YYYY/MM/DD'), // カレンダーの最大日付
382                static: true, // カレンダーの表示場所をinputの隣に固定
383                onDayCreate: function (dObj, dStr, fp, dayElem) {
384                    // カレンダーの日付が表示された時
385                    /**
386                     *   曜日のクラスを付与
387                     * */
388                    switch (dayjs(dayElem.dateObj).format('d')) {
389                        case '0':
390                            dayElem.classList.add('is-sunday');
391                            break;
392                        case '1':
393                            dayElem.classList.add('is-monday');
394                            break;
395                        case '2':
396                            dayElem.classList.add('is-tuesday');
397                            break;
398                        case '3':
399                            dayElem.classList.add('is-wednesday');
400                            break;
401                        case '4':
402                            dayElem.classList.add('is-thursday');
403                            break;
404                        case '5':
405                            dayElem.classList.add('is-friday');
406                            break;
407                        case '6':
408                            dayElem.classList.add('is-saturday');
409                            break;
410                    }
411                },
412                onChange: function (selectedDates, dateStr, instance) {
413                    // 日付が変更された時
414                    const d = dayjs(selectedDates[0]); // dayjs object
415                    nYear = d.year(); // å¹´
416                    nMonth = d.month() + 1; // 月
417                    nDay = d.date(); // 日
418                    formCheckInn.value = d.format('YYYYMMDD'); // 日付
419                    // チェックアウト日の案内を表示
420                    if (!flagCalendarHideCheckOutText && selectedDates.length <= 1) {
421                        queueMicrotask(() => {
422                            showCheckOutInfo(instance.selectedDateElem);
423                        });
424                    }
425                    //泊数を再計算
426                    const nStay = selectedDates.length <= 1 ? null : dayjs(selectedDates[1]).diff(dayjs(selectedDates[0]), 'day'); // 泊数
427                    if (nStay !== null) {
428                        /**
429                         *   チェックイン・チェックアウト日が選択された場合
430                         * */
431                        formNights.name = 'nights';
432                        formNights.value = nStay; // 泊数
433                    } else {
434                        formNights.removeAttribute('name');
435                    }
436                    /**
437                     * カレンダーInput内の文字を初期設定からcalendarSpanStr に変更
438                     */
439                    if (calendarSpanStr && calendarSpanStr !== '') {
440                        const input = instance._input;
441                        let str = '';
442                        const lenSeparators = rangeSeparators.length;
443                        for (let i = 0; i < lenSeparators; i++) {
444                            if (input.value.indexOf(rangeSeparators[i]) !== -1) {
445                                str = input.value.replace(rangeSeparators[i], calendarSpanStr);
446                            }
447                        }
448                        input.value = str;
449                    }
450                    // inputのvalueを変更
451                    if (selectedDates.length === 1) {
452                        instance.input.value = d.format('YYYY/MM/DD(ddd)');
453                    } else {
454                        const dd = dayjs(selectedDates[0]).format('YYYYMMDD');
455                        const dd2 = dayjs(selectedDates[1]).format('YYYYMMDD');
456                        if (dd === dd2) {
457                            instance.input.value = d.format('YYYY/MM/DD(ddd)');
458                        }
459                    }
460                }, onReady: function (selectedDates, dateStr, instance) {
461                    // カレンダーが表示された時
462                    /**
463                     * カレンダーInput内の文字を初期設定からcalendarSpanStr に変更
464                     */
465                    if (calendarSpanStr && calendarSpanStr !== '') {
466                        const input = instance._input;
467                        let str = '';
468                        const lenSeparators = rangeSeparators.length;
469                        //スタイルを調整する
470                        if (instance.calendarContainer) {
471                            const container = instance.calendarContainer.querySelector('.flatpickr-innerContainer');
472                            if(container){
473                                container.style.overflow = 'visible';
474                                const outer = container.querySelector('.flatpickr-days');
475                                if(outer){
476                                    outer.style.overflow = 'visible';
477                                }
478                            }
479                        }
480                        for (let i = 0; i < lenSeparators; i++) {
481                            if (input.value.indexOf(rangeSeparators[i]) !== -1) {
482                                str = input.value.replace(rangeSeparators[i], calendarSpanStr);
483                            }
484                        }
485                        input.value = str;
486                    }
487                },
488            });
489            yproXClendars.push(fp); // カレンダーを配列に格納
490        } else {
491            // カレンダーを表示しない場合
492            formWrpCheckInn.removeChild(formCheckInnOut); // カレンダーを削除
493            //å¹´
494            if (formCheckInnYear) {
495                //nOpMaxYearの数だけoptionを追加
496                for (let j = 0; j < nOpMaxYear; j++) {
497                    const Option = document.createElement('option');
498                    Option.value = dayjs().add(j, 'year').year();
499                    Option.textContent = dayjs().add(j, 'year').year();
500                    formCheckInnYear.appendChild(Option);
501                    if (Option.value === String(nYear)) {
502                        Option.setAttribute('selected', 'selected');
503                    }
504                }
505                // 年の変更
506                formCheckInnYear.addEventListener('change', function (e) {
507                    nYear = e.currentTarget.value;
508                    const yd = dayjs().year(nYear).month(nMonth - 1).date(1);
509                    const nMaxDay = yd.endOf('month').date();
510                    if (Number(nMaxDay) < Number(nDay)) {
511                        nDay = nMaxDay;
512                    }
513                    // 年の変更時に日付の最大値を変更
514                    setMaxDate(formCheckInnDay, nMaxDay, nDay, String(nYear) + String(ToDoubleDigits(nMonth)) + String(ToDoubleDigits(nDay)));
515                    //検索年月日を変更
516                    setSearchDate(formCheckInn, nYear, nMonth, nDay);
517                });
518            }
519            //月
520            if (formCheckInnMonth) {
521                // 12ヶ月分のoptionを追加
522                for (let j = 1; j <= 12; j++) {
523                    const Option = document.createElement('option');
524                    Option.value = j;
525                    Option.textContent = j;
526                    formCheckInnMonth.appendChild(Option);
527                    if (j === nMonth) {
528                        Option.setAttribute('selected', 'selected');
529                    }
530                }
531                // 月の変更
532                formCheckInnMonth.addEventListener('change', function (e) {
533                    nMonth = e.currentTarget.value;
534                    const md = dayjs().year(nYear).month(nMonth - 1).date(1);
535                    const nMaxDay = md.endOf('month').date();
536                    if (Number(nMaxDay) < Number(nDay)) {
537                        nDay = nMaxDay;
538                    }
539                    // 月の変更時に日付の最大値を変更
540                    setMaxDate(formCheckInnDay, nMaxDay, nDay, String(nYear) + String(ToDoubleDigits(nMonth)) + String(ToDoubleDigits(nDay)));
541                    //検索年月日を変更
542                    setSearchDate(formCheckInn, nYear, nMonth, nDay);
543                });
544            }
545            //日
546            if (formCheckInnDay) {
547                const nMaxDay = d.endOf('month').date();
548                // 日付の変更
549                formCheckInnDay.addEventListener('change', function (e) {
550                    nDay = e.currentTarget.value;
551                    //検索年月日を変更
552                    setSearchDate(formCheckInn, nYear, nMonth, nDay);
553                });
554                // 月の最大日数分のoptionを追加
555                setMaxDate(formCheckInnDay, nMaxDay, nInitDay);
556            }
557            // 日付
558            if (formCheckInn) {
559                // 日付の初期値を設定
560                setSearchDate(formCheckInn, nYear, nMonth, nDay);
561            }
562        }
563        // 日付なし
564        if (formNoDate) {
565            // 日付なしの初期値を設定
566            const parentFormCheckInnOut = formCheckInnOut ? formCheckInnOut.parentNode : null;
567            if (flagNoDate) {
568                formNoDate.setAttribute('checked', 'checked');
569                formCheckInn.setAttribute('disabled', 'disabled');
570                if (flagCalendar) {
571                    // カレンダーを表示する場合
572                    formCheckInnOut.setAttribute('disabled', 'disabled');
573                    parentFormCheckInnOut && parentFormCheckInnOut.setAttribute('disabled', 'disabled');
574                } else {
575                    // カレンダーを表示しない場合
576                    formCheckInnYear.setAttribute('disabled', 'disabled');
577                    formCheckInnMonth.setAttribute('disabled', 'disabled');
578                    formCheckInnDay.setAttribute('disabled', 'disabled');
579                }
580            }
581            // 日付なしの変更
582            formNoDate.addEventListener('change', function (e) {
583                // 日付なしのチェックが入っている場合
584                if (e.currentTarget.checked) {
585                    formCheckInn.setAttribute('disabled', 'disabled');
586                    formCheckInnOut && formCheckInnOut.setAttribute('disabled', 'disabled');
587                    formCheckInnYear && formCheckInnYear.setAttribute('disabled', 'disabled');
588                    formCheckInnMonth && formCheckInnMonth.setAttribute('disabled', 'disabled');
589                    formCheckInnDay && formCheckInnDay.setAttribute('disabled', 'disabled');
590                    parentFormCheckInnOut && parentFormCheckInnOut.setAttribute('disabled', 'disabled');
591                } else {
592                    // 日付なしのチェックが入っていない場合
593                    formCheckInn.removeAttribute('disabled');
594                    formCheckInnOut && formCheckInnOut.removeAttribute('disabled');
595                    formCheckInnYear && formCheckInnYear.removeAttribute('disabled');
596                    formCheckInnMonth && formCheckInnMonth.removeAttribute('disabled');
597                    formCheckInnDay && formCheckInnDay.removeAttribute('disabled');
598                    parentFormCheckInnOut && parentFormCheckInnOut.removeAttribute('disabled');
599                }
600            });
601        }
602        //nOpMaxRoomの数だけoptionを追加
603        if (formRoom) {
604            for (let j = 1; j <= nOpMaxRoom; j++) {
605                const Option = document.createElement('option');
606                Option.value = j;
607                Option.textContent = j + strRooms;
608                formRoom.appendChild(Option);
609                if (j === nInitRoom) {
610                    Option.setAttribute('selected', 'selected');
611                }
612            }
613        }
614        // フォームが複数ある場合は、ID名重複を避けるため、の末尾に数字を付ける
615        if (lenSearchForm > 1) {
616            //フォームの数だけクラス名を追加
617            form.classList.add('js-yprox-searchForm_' + String(i + 1));
618            const labels = form.querySelectorAll('.js-yprox-searchForm__wrpLabel'); // ラベル
619            const lenLabels = labels.length; // ラベルの数
620            // ラベルのfor属性とinputのid属性に数字を付ける
621            for (let j = 0; j < lenLabels; j++) {
622                const wrpLabel = labels[j]; // ラベルのラッパー
623                const label = wrpLabel.querySelectorAll('label'); // ラベル
624                const lenLabel = label.length; // ラベルの数
625                const input = wrpLabel.querySelectorAll('input'); // input
626                const lenInput = input.length; // inputの数
627                const select = wrpLabel.querySelectorAll('select'); // select
628                const lenSelect = select.length; // selectの数
629                // ラベルが1つ以上ある場合
630                if (lenLabel > 0) {
631                    // ラベルのfor属性に数字を付ける
632                    for (let k = 0; k < lenLabel; k++) {
633                        label[k].setAttribute('for', label[k].getAttribute('for') + '_' + String(i + 1));
634                    }
635                }
636                // inputが1つ以上ある場合
637                if (lenInput > 0) {
638                    // inputのid属性に数字を付ける
639                    for (let k = 0; k < lenInput; k++) {
640                        if (input[k].getAttribute('id') && input[k].getAttribute('id') !== '') {
641                            input[k].setAttribute('id', input[k].getAttribute('id') + '_' + String(i + 1));
642                        }
643                    }
644                }
645                // selectが1つ以上ある場合
646                if (lenSelect > 0) {
647                    // selectのid属性に数字を付ける
648                    for (let k = 0; k < lenSelect;
648 k++) {
649                        if (select[k].getAttribute('id') && select[k].getAttribute('id') !== '') {
650                            select[k].setAttribute('id', select[k].getAttribute('id') + '_' + String(i + 1));
651                        }
652                    }
653                }
654            }
655        }
656    }
657    window.addEventListener('resize', function () {
658        setNumCalendarMonth(windowMobileWidth, wr_wait, yproXClendars, nInitCalendar, nInitCalendarMobile);
659    }, false);
660}
661
662/**
663 * 日付の最大値を変更
664 * @param select 日付のselect要素
665 * @param days 最大値
666 * @param initDay 初期値
667 */
668function setMaxDate(select, days, initDay, currentDay = null) {
669    const d = !currentDay ? dayjs().add(initDay, 'day').date() : dayjs(currentDay).date();
670    select.innerHTML = '';
671    for (let j = 1; j <= days; j++) {
672        const Option = document.createElement('option');
673        Option.value = j;
674        Option.textContent = j;
675        select.appendChild(Option);
676        if (j === d) {
677            Option.setAttribute('selected', 'selected');
678        }
679    }
680}
681
682/**
683 * 日付の初期値を設定
684 * @param checkInn チェックイン日付のinput要素
685 * @param year å¹´
686 * @param month 月
687 * @param day 日
688 */
689function setSearchDate(checkInn, year, month, day) {
690    checkInn.value = String(year) + String(ToDoubleDigits(Number(month))) + String(ToDoubleDigits(Number(day)));
691}
692
693/**
694 * 0埋め
695 * @param num 数値
696 * @param digits 桁数
697 * @returns {string}
698 * @constructor
699 */
700function ToDoubleDigits(num, digits = 2) {
701    return (Array(digits).join('0') + num).slice(-digits);
702};
703
704/**
705 * windowの幅によってカレンダーの表示月を変更
706 * @param wm windowの幅
707 * @param wait ウィンドウリサイズ時の待ち時間
708 * @param init 初期表示かどうか
709 * @param calendars カレンダーの要素
710 * @param numCalendar カレンダーの表示月数
711 */
712function setNumCalendarMonth(wm, wait, calendars, numCalendar, numCalendarMobile) {
713    const len_c = calendars.length;
714    if (len_c > 0) {
715        clearTimeout(yprox_wr_queue);
716        yprox_wr_queue = setTimeout(function () {
717            if (wm > yprox_wr_currentWidth) {
718                if (yprox_wr_currentWidth === window.innerWidth && yprox_wr_currentHeight === window.innerHeight) {
719                    return;
720                }
721            } else {
722                if (yprox_wr_currentWidth === window.innerWidth) {
723                    return;
724                }
725            }
726            yprox_wr_currentWidth = window.innerWidth;
727            yprox_wr_currentHeight = window.innerHeight;
728            //カレンダーの表示月を変更
729            if (wm > yprox_wr_currentWidth) {
730                //モバイルの場合
731                for (let i = 0; i < len_c; i++) {
732                    // calendars[i].destroy();
733                    calendars[i].set({showMonths: numCalendarMobile});
734                }
735            } else {
736                //PCの場合
737                for (let i = 0; i < len_c; i++) {
738                    // calendars[i].destroy();
739                    calendars[i].set({showMonths: numCalendar});
740                }
741            }
742        }, wait);
743    }
744};
745
746/**
747 * チェックアウト日の案内を表示
748 */
749function showCheckOutInfo(selectElem) {
750    // 要素が存在する場合
751    if (selectElem) {
752        let positionClass = 'none';
753        const cm = document.createElement('em');
754        const cmb = document.createElement('b');
755        cm.classList.add('flat__checkOutComment');
756        cm.classList.add(positionClass);
757        cmb.innerHTML = textCheckInnOut;
758        cm.appendChild(cmb);
759        selectElem.appendChild(cm);
760        //スタイルを適用
761        selectElem.style.position = 'relative';
762        cm.style.position = 'absolute';
763        cm.style.bottom = '99%';
764        cm.style.left = '50%';
765        cm.style.transform = 'translateX(-50%)';
766        cm.style.color = '#000';
767        cm.style.fontSize = '12px';
768        cm.style.lineHeight = '1.4';
769        cm.style.padding = '.5em .5em';
770        cm.style.borderRadius = '.25em';
771        cm.style.backgroundColor = '#f6f6f6';
772        cm.style.boxShadow = '0 0 5px rgba(0,0,0,.2)';
773        cm.style.border = '1px solid #dedede';
774        cm.style.zIndex = '100';
775        cm.style.width = '10em';
776        cm.style.textAlign = 'center';
777        cm.style.pointerEvents = 'none';
778        cm.style.transition = 'opacity .3s ease-in-out';
779        cm.style.opacity = '1';
780        // 曜日によってクラスを付与
781        if (selectElem.classList.contains('is-sunday') || selectElem.classList.contains('is-monday')) {
782            positionClass = 'is-sunday';
783            cm.style.left = '0';
784            cm.style.transform = 'translateX(0)';
785        } else if (selectElem.classList.contains('is-saturday') || selectElem.classList.contains('is-friday')) {
786            positionClass = 'is-saturday';
787            cm.style.right = '0';
788            cm.style.left = 'auto';
789            cm.style.transform = 'translateX(0)';
790        }
791        //3秒後に削除
792        setTimeout(() => {
793            cm.classList.add('is-hide');
794            cm.style.opacity = '0';
795            //0.3秒後に削除
796            setTimeout(() => {
797                cm.remove();
798            }, 300);
799        }, 3000);
800    }
801}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.