PageSourceSearch

https://www.tochigi-reform.jp/wpcms/wp-content/themes/tochigi_reform_2025/assets/js/event.js?ver=1790044909

js tochigi-reform.jp collected 2026-10-05 11:14:08 UTC 11,262 bytes, 365 lines download raw bytes

1$("#slider").slick({
2  autoplay: true,
3  autoplaySpeed: 4000,
4  fade: true,
5  infinite: false, // 無限スライド
6});
7
8//フォームのイベントタイトルを触れないように
9document.addEventListener("DOMContentLoaded", function () {
10  const eventTitleInput = document.querySelector('input[name="event_title"]');
11  if (eventTitleInput) {
12    eventTitleInput.setAttribute("readonly", "readonly");
13  }
14});
15
16//日付制御
17document.addEventListener("DOMContentLoaded", function () {
18  if (document.querySelector(".event-lp-form")) {
19    return;
20  }
21
22  if (typeof flatpickr === "undefined") {
23    console.warn("Flatpickr is not loaded");
24    return;
25  }
26
27  flatpickr.localize(flatpickr.l10ns.ja);
28
29  function zenkakuToHankaku(str) {
30    return str
31      .replace(/[0-9]/g, (s) => String.fromCharCode(s.charCodeAt(0) - 0xfee0))
32      .replace(/[〜~]/g, "~")
33      .replace(/-/g, "-")
34      .replace(/[()]/g, (s) => (s === "(" ? "(" : ")"));
35  }
36
37  const eventDateTextRaw = document.querySelector('[name="event_day"]')?.value;
38  const targetInputs = document.querySelectorAll(".datepicker");
39  if (!targetInputs.length) return;
40
41  if (!eventDateTextRaw) {
42    // カスタムフィールドが空だった場合のフォールバック
43    targetInputs.forEach((input) => {
44      input.value = "担当よりご連絡差し上げます";
45      input.disabled = true;
46    });
47    return;
48  }
49
50  const eventDateText = zenkakuToHankaku(eventDateTextRaw);
51
52  function parseJapaneseDate(str) {
53    str = str.replace(/([^)]+)/, "");
54    const match = str.match(/(\d{4})年(\d{1,2})月(\d{1,2})日/);
55    if (match) {
56      const [_, y, m, d] = match;
57      return `${y}-${m.toString().padStart(2, "0")}-${d
58        .toString()
59        .padStart(2, "0")}`;
60    }
61    return null;
62  }
63
64  function getDatesBetween(startStr, endStr) {
65    if (!startStr || !endStr) return [];
66    const startDate = new Date(startStr);
67    const endDate = new Date(endStr);
68    if (isNaN(startDate) || isNaN(endDate)) return [];
69    const dates = [];
70    for (
71      let dt = new Date(startDate);
72      dt <= endDate;
73      dt.setDate(dt.getDate() + 1)
74    ) {
75      const y = dt.getFullYear();
76      const m = (dt.getMonth() + 1).toString().padStart(2, "0");
77      const d = dt.getDate().toString().padStart(2, "0");
78      dates.push(`${y}-${m}-${d}`);
79    }
80    return dates;
81  }
82
83  const today = new Date();
84  const todayStr = today.toISOString().split("T")[0];
85  const tomorrow = new Date(today);
86  tomorrow.setDate(tomorrow.getDate() + 1);
87  const tomorrowStr = tomorrow.toISOString().split("T")[0];
88
89  // 手動で選択不可にしたい日付
90  const disabledDates = [
91    "2026-05-04",
92    "2026-05-05",
93  ];
94
95  let enableDates = [];
96  let defaultDate = null;
97  let minDate = null;
98
99  if (eventDateText.includes("~")) {
100    const [startText, endText] = eventDateText.split("~").map((s) => s.trim());
101    const startDate = parseJapaneseDate(startText);
102    const endDate = parseJapaneseDate(endText);
103    if (!startDate || !endDate) return;
104
105    // 今日を含む範囲ならminDateを明日以降にセット
106    if (startDate <= todayStr && endDate >= todayStr) {
107      minDate = tomorrowStr; // 今日を含むなら翌日以降のみ選択可
108      // enableは範囲の終わりまでに設定
109      enableDates = getDatesBetween(minDate, endDate);
110      defaultDate = minDate;
111    } else {
112      // 今日を含まないなら元のenableDates全部許可
113      enableDates = getDatesBetween(startDate, endDate);
114      defaultDate = startDate;
115    }
116  } else {
117    const onlyDate = parseJapaneseDate(eventDateText);
118    if (!onlyDate) return;
119
120    // 単日の場合、今日以降ならminDateは今日または明日
121    if (onlyDate <= todayStr) {
122      minDate = tomorrowStr; // 今日以前は選べない
123      enableDates = [minDate]; // もしくは空配列でも可
124      defaultDate = minDate;
125    } else {
126      enableDates = [onlyDate];
127      defaultDate = onlyDate;
128    }
129  }
130
131  // disabledDates に含まれる日を除外
132  enableDates = enableDates.filter((d) => !disabledDates.includes(d));
133
134  function getClosedEventWeekdays() {
135    const configEl = document.getElementById("event-datepicker-config");
136    if (configEl) {
137      try {
138        const data = JSON.parse(configEl.textContent);
139        if (Array.isArray(data.closedWeekdays)) {
140          return data.closedWeekdays.map(Number);
141        }
142      } catch (e) {
143        // 設定の読み込みに失敗した場合は従来値へフォールバック
144      }
145    }
146    if (
147      typeof eventDatepickerConfig !== "undefined" &&
148      Array.isArray(eventDatepickerConfig.closedWeekdays)
149    ) {
150      return eventDatepickerConfig.closedWeekdays.map(Number);
151    }
152    return [0, 3];
153  }
154
155  function getWeekdayFromYmd(ymd) {
156    const parts = String(ymd).split("-").map(Number);
157    if (parts.length === 3 && parts.every((n) => !Number.isNaN(n))) {
158      return new Date(parts[0], parts[1] - 1, parts[2]).getDay();
159    }
160    return new Date(ymd).getDay();
161  }
162
163  // 定休曜日(0:日曜〜6:土曜)。イベントごとにACFで設定
164  const closedEventWeekdays = getClosedEventWeekdays();
165  enableDates = enableDates.filter((d) => {
166    const day = getWeekdayFromYmd(d);
167    return !closedEventWeekdays.includes(day);
168  });
169
170  targetInputs.forEach((input, index) => {
171    flatpickr(input, {
172      dateFormat: "Y-m-d",
173      locale: "ja",
174      enable: enableDates.length > 0 ? enableDates : undefined,
175      minDate: minDate,
176      // 第1希望のみデフォルト日付をセット、第2希望以降は空(任意入力)
177      defaultDate: index === 0 ? defaultDate : null,
178    });
179  });
180});
181
182document.addEventListener("DOMContentLoaded", function () {
183  if (document.querySelector(".event-lp-form")) {
184    return;
185  }
186
187  if (typeof flatpickr === "undefined") {
188    console.warn("Flatpickr is not loaded for general datepickers");
189    return;
190  }
191
192  // ▼【対象セレクタ】変更する場合ここを修正
193  const targetPickers = ".datepicker-time";
194
195  // ▼【何日後から選択可能か】(例:1 → 翌日から、2 → 翌々日から)
196  const selectableOffsetDays = 1;
197
198  // ▼【定休にしない曜日をコメントアウトで調整】(0:日〜6:土)
199  const closedWeekdays = [
200    0, // 日曜
201    3, // 水曜
202    // 4, // 木曜
203    // 0, // 日曜などを追加してもOK
204  ];
205
206  // ▼【祝日を定休日にするか】
207  const disableHolidays = false;
208
209  // ▼【手動で定休日にしたい日付(YYYY-MM-DD形式)】
210  const manualHolidays = [
211    // 年末年始休業 2024-2025
212    "2024-12-27",
213    "2024-12-28",
214    "2024-12-29",
215    "2024-12-30",
216    "2024-12-31",
217    "2025-01-01",
218    "2025-01-02",
219    "2025-01-03",
220    "2025-01-04",
221    // 夏季休業
222    "2025-08-15",
223    "2025-08-16",
224    "2025-08-17",
225    // 年末年始休業 2025-2026
226    "2025-12-27",
227    "2025-12-28",
228    "2025-12-29",
229    "2025-12-30",
230    "2025-12-31",
231    "2026-01-01",
232    "2026-01-02",
233    "2026-01-03",
234    "2026-01-04",
235    // GW休業 2026
236    "2026-05-04",
237    "2026-05-05",
238  ];
239
240  // ▼ minDateを翌日に設定
241  const tomorrow = new Date();
242  tomorrow.setDate(tomorrow.getDate() + selectableOffsetDays);
243  tomorrow.setHours(0, 0, 0, 0);
244
245  let holidayList = [];
246
247  if (disableHolidays) {
248    fetch("https://holidays-jp.github.io/api/v1/date.json")
249      .then((res) => res.json())
250      .then((data) => {
251        holidayList = [...Object.keys(data), ...manualHolidays];
252        initFlatpickr();
253      });
254  } else {
255    holidayList = [...manualHolidays];
256    initFlatpickr();
257  }
258
259  function initFlatpickr() {
260    flatpickr(targetPickers, {
261      enableTime: true,
262      noCalendar: false,
263      dateFormat: "Y/m/d H:i",
264      time_24hr: true,
265      minuteIncrement: 30,
266      locale: "ja",
267      minDate: tomorrow, //記述注意
268      defaultHour: 9,
269      defaultMinute: 0,
270      minTime: "09:00",
271      maxTime: "18:30",
272
273      disable: [
274        function (date) {
275          const day = date.getDay(); // 0:日〜6:土
276
277          // 日付を YYYY-MM-DD に整形
278          const y = date.getFullYear();
279          const m = ("0" + (date.getMonth() + 1)).slice(-2);
280          const d = ("0" + date.getDate()).slice(-2);
281          const formatted = `${y}-${m}-${d}`;
282
283          return (
284            closedWeekdays.includes(day) || holidayList.includes(formatted)
285          );
286        },
287      ],
288
289      onOpen: function (selectedDates, dateStr, instance) {
290        if (instance.input.value === "") {
291          const defaultPickerTime = new Date(tomorrow); // 翌日の9:00
292          defaultPickerTime.setHours(9, 0);
293          instance.setDate(defaultPickerTime, false);
294        }
295      },
296
297      onClose: function (selectedDates, dateStr, instance) {
298        const selectedDate = selectedDates[0];
299        if (selectedDate) {
300          const hour = selectedDate.getHours().toString().padStart(2, "0");
301          const minute = selectedDate.getMinutes().toString().padStart(2, "0");
302          const inputName = instance.input.name;
303          const timeSelectName = inputName.replace("date", "time");
304          const timeSelect = document.querySelector(
305            `select[name="${timeSelectName}"]`
306          );
307
308          if (timeSelect) {
309            let closestOption = null;
310            let minDiff = Infinity;
311            Array.from(timeSelect.options).forEach((option) => {
312              if (option.value === "") return;
313              const [optHour, optMinute] = option.value.split(":").map(Number);
314              const optionTime = optHour * 60 + optMinute;
315              const selectedTime =
316                selectedDate.getHours() * 60 + selectedDate.getMinutes();
317              const diff = Math.abs(selectedTime - optionTime);
318              if (diff < minDiff) {
319                minDiff = diff;
320                closestOption = option;
321              }
322            });
323            if (closestOption) {
324              timeSelect.value = closestOption.value;
325              timeSelect.dispatchEvent(new Event("change", { bubbles: true }));
326            }
327          }
328        }
329      },
330    });
331  }
332
333  // ▼ MW WP Form のセレクトを非表示に
334  const timeSelects = document.querySelectorAll(
335    '.form__select.small[name^="time"]'
336  );
337  timeSelects.forEach((select) => {
338    select.style.display = "none";
339    const spanText = select.nextElementSibling;
340    if (spanText && spanText.classList.contains("form__input-text")) {
341      spanText.style.display = "none";
342    }
343  });
344});
345
346// チェックボックスを単一選択に制御(.single-select を付けた項目が対象)
347document.addEventListener("DOMContentLoaded", function () {
348  const singleSelectGroups = document.querySelectorAll(
349    ".form__item.single-select"
350  );
351
352  singleSelectGroups.forEach((group) => {
353    const checkboxes = group.querySelectorAll('input[type="checkbox"]');
354    checkboxes.forEach((checkbox) => {
355      checkbox.addEventListener("change", function () {
356        if (this.checked) {
357          // 同じグループ内の他のチェックを外す
358          checkboxes.forEach((other) => {
359            if (other !== this) other.checked = false;
360          });
361        }
362      });
363    });
364  });
365});

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.