PageSourceSearch

https://img.dormy-hotels.com/static/js/top_nono/form.js

js dormy-hotels.com collected 2026-10-02 05:59:37 UTC 22,124 bytes, 654 lines download raw bytes

1$(function () {
2  /* alert
3   * --------------------------------------------------------- */
4   function confirmDeleteDisp() {
5     if(window.confirm('登録がある場合、空欄となります。本当に削除しますか?')){
6       window.alert('削除しました。');
7 	   }
8 	   else {
9 		   window.alert('キャンセルされました。');
10     }
11   }
12   $('.js-confirm-delete').on('click',function(){
13     confirmDeleteDisp();
14   });
15
16  /* login input
17   * ------------------------------------------------------- */
18  $('.form-login-input .form-control').each(function() {
19    let error;
20    let value = $(this).val();
21    if(value == "") {
22      error = true;
23    } else if(!value.match(/[^\s\t]/)) {
24      error = true;
25    }
26    if(!error) {
27      $(this).addClass('form-entered');
28    }
29  });
30
31  $('.form-login-input input.form-control').on('keyup',function(e){
32    let error;
33    let value = $(this).val();
34    if(value == "") {
35      error = true;
36    } else if(!value.match(/[^\s\t]/)) {
37      error = true;
38    }
39    if(error) {
40      $(this).removeClass('form-entered');
41    } else {
42      $(this).addClass('form-entered');
43    }
44  });
45
46  /* select box
47   * ------------------------------------------------------- */
48   $('.form-select').each(function() {
49     let value = $(this).val();
50     if(value === "") {
51       $(this).addClass('no-value');
52     }
53   });
54   $(document).on('change', '.form-select' ,function(e){
55     let value = $(this).val();
56     if(value === "") {
57       $(this).addClass('no-value');
58     } else {
59       $(this).removeClass('no-value');
60     }
61   });
62
63   /* readonly control
64   * ------------------------------------------------------- */
65   $(document).on('change', '.form-readonly-control' ,function(e){
66     let val = $(e.target).val();
67     let target = $(e.target).data('readonly-target');
68     if (val > 0) {
69       $('.readonly-target-' + target).attr('readonly', false);
70     } else {
71       $('.readonly-target-' + target).attr('readonly', true);
72     }
73   });
74   $('.form-readonly-control').each(function() {
75     let name = $(this).attr('name');
76     let val = $('input[name="'+name+'"]:checked').val();
77     let target = $(this).data('readonly-target');
78     if (val > 0) {
79       $('.readonly-target-' + target).attr('readonly', false);
80     } else {
81       $('.readonly-target-' + target).attr('readonly', true);
82     }
83   });
84
85   /* disabled control
86   * ------------------------------------------------------- */
87   $(document).on('change', '.form-disabled-control' ,function(e){
88     let val = $(e.target).val();
89     let target = $(e.target).data('disabled-target');
90     if ($(this).prop('checked') == true) {
91       $('.disabled-target-' + target).attr('disabled', false);
92     } else {
93       $('.disabled-target-' + target).prop('checked',false).attr('disabled', true);
94     }
95   });
96   $('.form-disabled-control').each(function() {
97     let target = $(this).data('disabled-target');
98     if ($(this).prop('checked') == true) {
99       $('.disabled-target-' + target).attr('disabled', false);
100     } else {
101       $('.disabled-target-' + target).prop('checked',false).attr('disabled', true);
102     }
103   });
104
105   /* hidden control
106   * ------------------------------------------------------- */
107   $(document).on('change', '.form-hidden-control' ,function(e){
108     let val = $(e.target).val();
109     let target = $(e.target).data('hidden-target');
110     if (val > 0) {
111       $('.hidden-target-' + target).show();
112     } else {
113       $('.hidden-target-' + target).hide();
114     }
115   });
116   $('.form-hidden-control').each(function() {
117     let name = $(this).attr('name');
118     let val = $('input[name="'+name+'"]:checked').val();
119     let target = $(this).data('hidden-target');
120     if (val > 0) {
121       $('.hidden-target-' + target).show();
122     } else {
123       $('.hidden-target-' + target).hide();
124     }
125   });
126
127   /* all checkbox
128    * ------------------------------------------------------- */
129    $('.all-checked-btn').on('click',function(e){
130      var target = $(this).data('target'),
131          aria = $(this).attr('aria-checked');
132      if (aria == 'true') {
133        $('#'+target+' input[type="checkbox"]').each(function() {
134          $(this).prop('checked', false);
135        });
136        $(this).attr('aria-checked', false);
137      } else {
138        $('#'+target+' input[type="checkbox"]').each(function() {
139          $(this).prop('checked', true);
140        });
141        $(this).attr('aria-checked', true);
142      }
143    });
144
145
146   /* required background color
147    * ------------------------------------------------------- */
148   $(document).on('keydown keyup keypress change focus blur', '.form-control.form-required' ,function(e){
149     if($(this).val() == ''){
150         $(this).css({backgroundColor:'#f7f2e4'});
151     } else {
152         $(this).css({backgroundColor:'#fff'});
153     }
154   });
155   $('.form-control.form-required').each(function() {
156     if($(this).val() == ''){
157         $(this).css({backgroundColor:'#f7f2e4'});
158     } else {
159         $(this).css({backgroundColor:'#fff'});
160     }
161   });
162   $(document).on('change', '.form-select.form-required' ,function(e){
163     if($(this).val() == ''){
164         $(this).css({backgroundColor:'#f7f2e4'});
165     } else {
166         $(this).css({backgroundColor:'#fff'});
167     }
168   });
169   $('.form-select.form-required').each(function() {
170     if($(this).val() == ''){
171         $(this).css({backgroundColor:'#f7f2e4'});
172     } else {
173         $(this).css({backgroundColor:'#fff'});
174     }
175   });
176
177 /* file name
178  * ------------------------------------------------------- */
179  $('input[type="file"].form-control').on('change', function(){
180    let file = $(this).prop('files')[0];
181    $(this).parent('.form-file').next('.form-file-text').text(file.name);
182  });
183
184 /* add comma for input number
185  * ------------------------------------------------------- */
186  function updateTextView(_obj){
187    let num = getNumber(_obj.val());
188    if(num==0){
189      _obj.val('');
190    } else {
191      _obj.val(num.toLocaleString());
192    }
193  }
194  function getNumber(_str){
195    let arr = _str.split('');
196    let out = new Array();
197    for(let cnt=0;cnt<arr.length;cnt++){
198      if(isNaN(arr[cnt])==false){
199        out.push(arr[cnt]);
200      }
201    }
202    return Number(out.join(''));
203  }
204  function removeComma(number) {
205    var removed = number.replace(/,/g, '');
206    return parseInt(removed, 10);
207  }
208  $('input[type="text"].form-add-comma').on('keyup',function(){
209    updateTextView($(this));
210  });
211
212  /* ajaxzip3
213  * ------------------------------------------------------- */
214  $('#ajaxZip_1').on('click', function(){
215    AjaxZip3.zip2addr('zip','','pref','addr1','addr2');
216
217    //成功時に実行する処理
218    AjaxZip3.onSuccess = function() {
219      $('.addr2').focus();
220    };
221
222    //失敗時に実行する処理
223    AjaxZip3.onFailure = function() {
224        alert('郵便番号に該当する住所が見つかりません');
225    };
226
227    return false;
228  });
229
230  $('#ajaxZip_2').on('click', function(){
231    AjaxZip3.zip2addr('zip_2','','pref_2','addr1_2','addr2_2');
232
233    //成功時に実行する処理
234    AjaxZip3.onSuccess = function() {
235      $('.addr2_2').focus();
236    };
237
238    //失敗時に実行する処理
239    AjaxZip3.onFailure = function() {
240        alert('郵便番号に該当する住所が見つかりません');
241    };
242
243    return false;
244  });
245
246 /* insert zip str
247  * ------------------------------------------------------- */
248  function insertZipStr(input){
249    return input.slice(0, 3) + '-' + input.slice(3,input.length);
250  }
251  $(".form-postal-code").on('keyup',function(e){
252    var input = $(this).val();
253
254    //削除キーではハイフン追加処理が働かないように制御(8がBackspace、46がDelete)
255    var key = event.keyCode || event.charCode;
256    if( key == 8 || key == 46 ){
257      return false;
258    }
259
260    //3桁目に値が入ったら発動
261    if(input.length === 3){
262      $(this).val(insertZipStr(input));
263    }
264  });
265  $(".form-postal-code").on('blur',function(e){
266    var input = $(this).val();
267
268    //4桁目が'-(ハイフン)’かどうかをチェックし、違ったら挿入
269    if(input.length >= 3 && input.substr(3,1) !== '-'){
270      $(this).val(insertZipStr(input));
271    }
272  });
273
274 /* quantity
275  * ------------------------------------------------------- */
276
277  $(document).off('click', '.js-qty__adjust').on('click', '.js-qty__adjust', function () {
278    const LIMIT_PER_ROOM = 10;
279
280    const $btn = $(this);
281    const $qty = $btn.parent('.js-qty');
282    const $input = $qty.children('.js-qty__num');
283
284    const name = $input.attr('name') || '';
285    const min = parseInt($input.attr('min'), 10);
286    const max = parseInt($input.attr('max'), 10);
287
288    const safeInt = (v, fallback = 0) => {
289        const n = parseInt(v, 10);
290        return Number.isNaN(n) ? fallback : n;
291    };
292
293    const getVal = ($el, fallback = 0) => safeInt($el.val(), fallback);
294
295    const setMinusDisabled = ($wrap, disabled) => {
296        $wrap.children('.js-qty__adjust--minus').prop('disabled', !!disabled);
297    };
298
299    const setPlusDisabled = ($wrap, disabled) => {
300        $wrap.children('.js-qty__adjust--plus').prop('disabled', !!disabled);
301    };
302
303    const clamp = (val, minVal, maxVal) => {
304        let v = val;
305        if (!Number.isNaN(minVal)) v = Math.max(minVal, v);
306        if (!Number.isNaN(maxVal)) v = Math.min(maxVal, v);
307        return v;
308    };
309
310    const $room = $btn.closest('.room-group');
311    const $scope = $room.length ? $room : $(document);
312
313    const $adult = $scope.find('.js-qty__num[name="number_of_adults[]"]');
314    const $child = $scope.find('.js-qty__num[name="number_of_children_need_futons[]"]');
315
316    const updateRoomLimitButtons = () => {
317        if ($adult.length === 0 || $child.length === 0) {
318            return;
319        }
320
321        const ad = getVal($adult, 0);
322        const ch = getVal($child, 0);
323        const sum = ad + ch;
324
325        const reach = (sum >= LIMIT_PER_ROOM);
326
327        const adultMax = safeInt($adult.attr('max'), NaN);
328        const childMax = safeInt($child.attr('max'), NaN);
329
330        const $adultPlus = $adult.siblings('.js-qty__adjust--plus');
331        const $childPlus = $child.siblings('.js-qty__adjust--plus');
332
333        $adultPlus.prop('disabled', reach || (!Number.isNaN(adultMax) && ad >= adultMax));
334        $childPlus.prop('disabled', reach || (!Number.isNaN(childMax) && ch >= childMax));
335    };
336
337    // クローンした部屋の初期値をセットする
338    const initNewRoomValues = ($roomEl) => {
339        const $newAdult = $roomEl.find('.js-qty__num[name="number_of_adults[]"]');
340        const $newChild = $roomEl.find('.js-qty__num[name="number_of_children_need_futons[]"]');
341        const $newnoneedChild = $roomEl.find('.js-qty__num[name="number_of_children_no_need_futons[]"]');
342
343        // 大人=1 / 子供=0
344        if ($newAdult.length) {
345            $newAdult.val(1);
346            // minが1以上なら - をdisabled
347            const aMin = safeInt($newAdult.attr('min'), 0);
348            $newAdult.siblings('.js-qty__adjust--minus').prop('disabled', 1 <= aMin);
349            // maxが1以下なら + をdisabled
350            const aMax = safeInt($newAdult.attr('max'), NaN);
351            $newAdult.siblings('.js-qty__adjust--plus').prop('disabled', !Number.isNaN(aMax) && 1 >= aMax);
352        }
353
354        if ($newChild.length) {
355            $newChild.val(0);
356            // minが0以上なら - をdisabled(通常0minならdisabled)
357            const cMin = safeInt($newChild.attr('min'), 0);
358            $newChild.siblings('.js-qty__adjust--minus').prop('disabled', 0 <= cMin);
359            // maxが0以下なら + をdisabled
360            const cMax = safeInt($newChild.attr('max'), NaN);
361            $newChild.siblings('.js-qty__adjust--plus').prop('disabled', !Number.isNaN(cMax) && 0 >
361= cMax);
362        }
363        
364        if ($newnoneedChild.length) {
365            $newnoneedChild.val(0);
366            // minが0以上なら - をdisabled(通常0minならdisabled)
367            const nMin = safeInt($newnoneedChild.attr('min'), 0);
368            $newnoneedChild.siblings('.js-qty__adjust--minus').prop('disabled', 0 <= nMin);
369            // maxが0以下なら + をdisabled
370            const nMax = safeInt($newnoneedChild.attr('max'), NaN);
371            $newnoneedChild.siblings('.js-qty__adjust--plus').prop('disabled', !Number.isNaN(nMax) && 0 >= nMax);
372        }
373
374        // 部屋ごとの上限10も反映(大人1 + 子供0 なら基本OK)
375        // ※この部屋内だけで判定するため、$roomEl内の値を使って計算し直す
376        const ad = getVal($newAdult, 0);
377        const ch = getVal($newChild, 0);
378        const sum = ad + ch;
379
380        const reach = (sum >= LIMIT_PER_ROOM);
381        if ($newAdult.length) {
382            $newAdult.siblings('.js-qty__adjust--plus').prop('disabled', reach);
383        }
384        if ($newChild.length) {
385            $newChild.siblings('.js-qty__adjust--plus').prop('disabled', reach);
386        }
387    };
388
389    const syncRoomBlocks = (before, after) => {
390        if (!$btn.hasClass('js-qty__room')) {
391            return;
392        }
393
394        if (before <= 0 && after <= 0) {
395            return;
396        }
397
398        // 同じポップアップ内の部屋ブロックのみを対象にする
399        // (総合TOPは下部の検索ガジェット fixingInputArea にも .room-block があるため、ページ全体を対象にすると両方に複製さã
399‚Œã‚‹ï¼‰
400        const $popup = $btn.closest('.search-popup__rooms');
401        const $roomBlock = ($popup.length ? $popup : $(document)).find('.room-block').first();
402
403        if (after < before) {
404            $roomBlock.find('.room-group[data-room-group="' + before + '"]').remove();
405            return;
406        }
407
408        if (after > before) {
409            const value = after;
410
411            const $clone = $roomBlock.find('.room-group[data-room-group="1"]').first().clone();
412
413            $clone
414                .attr('data-room-group', value)
415                .find('.room-group-title')
416                .text(value + '部屋目');
417
418            // まずは一般入力をリセット
419            $clone.find('input.form-control').val('');
420            $clone.find('select.form-select').prop('selectedIndex', 0);
421
422            $clone.find('.form-required')
423                .removeAttr('style')
424                .css({ backgroundColor: '#FFEFF6' });
425
426            $clone.find('.room-group__check').prop('checked', false);
427
428            $clone.find('.room-group__transport').attr('name', 'transport_' + value);
429
430            $clone.find('.room-group__field').removeAttr('style');
431
432            // DOM追加
433            $roomBlock.append($clone);
434
435            // ★追加した部屋の「大人=1 / 子供=0」をセット
436            initNewRoomValues($clone);
437        }
438    };
439
440    // -------------------------
441    // 値の更新(+ / -)
442    // -------------------------
443    const beforeVal = getVal($input, 0);
444
445    const isRoomLimitedTarget = (name === 'number_of_adults' || name === 'number_of_children_need_futons');
446
447    let afterVal = beforeVal;
448
449    if ($btn.hasClass('js-qty__adjust--minus')) {
450        const minNum = Number.isNaN(min) ? 0 : min;
451        afterVal = clamp(beforeVal - 1, minNum, max);
452        $input.val(afterVal);
453
454    } else if ($btn.hasClass('js-qty__adjust--plus')) {
455        if (!Number.isNaN(max) && beforeVal >= max) {
456            setPlusDisabled($qty, true);
457            return;
458        }
459
460        if (isRoomLimitedTarget && $adult.length && $child.length) {
461            const ad = getVal($adult, 0);
462            const ch = getVal($child, 0);
463            const nextSum = (name === 'number_of_adults') ? (ad + 1 + ch) : (ad + ch + 1);
464
465            if (nextSum > LIMIT_PER_ROOM) {
466                updateRoomLimitButtons();
467                return;
468            }
469        }
470
471        afterVal = clamp(beforeVal + 1, min, max);
472        $input.val(afterVal);
473    } else {
474        return;
475    }
476
477    // -------------------------
478    // room add block
479    // -------------------------
480    syncRoomBlocks(beforeVal, afterVal);
481
482    // -------------------------
483    // このqty(クリックした行)の +/- disabled 制御
484    // -------------------------
485    if (!Number.isNaN(min)) {
486        setMinusDisabled($qty, afterVal <= min);
487    } else {
488        setMinusDisabled($qty, false);
489    }
490
491    if (!Number.isNaN(max)) {
492        setPlusDisabled($qty, afterVal >= max);
493    } else {
494        setPlusDisabled($qty, false);
495    }
496
497    // -------------------------
498    // 部屋ごとの上限10
499    // -------------------------
500    updateRoomLimitButtons();
501  });
502
503
504 /* reservation room
505  * ------------------------------------------------------- */
506  $(document).on('change', '.room-group__check' ,function(e){
507    let group = $(this).closest('.room-group'),
508        field = group.find('.room-group__field');
509    if ($(this).prop("checked") == true) {
510      field.slideDown(200);
511    } else {
512      field.slideUp(200);
513    }
514  });
515
516 /* reservation allergy
517  * ------------------------------------------------------- */
518  $(document).on('click', '.add-allergy-group' ,function(e){
519    let delete_btn = '<div class="d-flex justify-content-end"><button type="button" class="btn-text delete-allergy-group">×削除する</button></div>';
520    let last_id = $('.allergy-block .allergy-group:last-child').data('allergy-group');
521    let id = last_id + 1;
522    let clone = $('.allergy-block .allergy-group[data-allergy-group="1"]').clone();
523    $(clone).attr('data-allergy-group', id);
524    $(clone).find('.form-control').prop('value','');
525    $(clone).append(delete_btn);
526    $('.allergy-block').append(clone);
527  });
528  $(document).on('click', '.delete-allergy-group' ,function(e){
529    $(this).closest('.allergy-group').remove();
530  });
531
532 /* reservation form check (ここはテスト用)
533  * ------------------------------------------------------- */
534  $('.reservation-form .register-check').on('change', function(){
535    if ($(this).prop("checked") == true) {
536      $('.reservation-form').attr('action', 'reserve-complete-register.html');
537    } else {
538      $('.reservation-form').attr('action', 'reserve-complete-guest.html');
539    }
540  });
541
542 /* login form check (ここはテスト用)
543  * ------------------------------------------------------- */
544  $(document).on('click', '.login-form .btn-submit' ,function(e){
545    let email = $('.login-form .form-control[name="email"]').val(),
546        password = $('.login-form .form-control[name="password"]').val(),
547        $block = $('.login-form .form-block');
548    $('.login-form p.error').remove();
549    if (!email.length > 0) {
550      $block.prepend('<p class="error fc-red text-center">ご入力いただいたメールアドレスの<br>ご登録が見つかりません。</p>');
551    } else if (!password.length > 0) {
552      $block.prepend('<p class="error fc-red text-center">ご入力いただいたメールアドレスと<br>パスワードが一致しません。</p>');
553    }
554  });
555  $('.login-form .form-control').on('keydown keyup keypress change focus blur', function(){
556    let email = $('.login-form .form-control[name="email"]').val(),
557        password = $('.login-form .form-control[name="password"]').val();
558    if (email.length > 0 && password.length > 0) {
559      $('.login-form .btn-submit').attr('type', 'submit');
560    } else {
561      $('.login-form .btn-submit').attr('type', 'button');
562    }
563  });
564
565 /* restaurant
566  * ------------------------------------------------------- */
567  $('.reservation-form .meal-block .meal-select__time select').on('change', function(e){
568    let group = $(this).closest('.meal-group');
569    let field = group.find('.meal-select__field');
570    let val = $(this).children('option:selected').val();
571    if (val.length > 0) {
572      field.show();
573    } else {
574      field.hide();
575    }
576  });
577
578  /* cart
579   * ------------------------------------------------------- */
580   $(document).on('click', '.cart-main .cart-check' ,function(e){
581     const checks = $('.cart-check')
582     var cnt = 0;
583     for (var i = 0; i < checks.length; i++) {
584       if ($(checks[i]).prop('checked') == true) {
585         cnt++;
586       }
587     }
588     var btn_text = '予約の確認に進む('+cnt+'つのご予約)';
589     if (cnt > 0) {
590       $('.cart-check-count').prop('disabled', false)
591     } else {
592       $('.cart-check-count').prop('disabled', true)
593     }
594     $('.cart-check-count').text(btn_text)
595
596    // ここはテスト用
597    if ($(this).hasClass('no-stock')) {
598      var block = $(this).closest('.cart-result-block')
599      var no_stock = block.find('.cart-result-no-stock')
600      if ($(this).prop('checked') == true) {
601        no_stock.show();
602      } else {
603        no_stock.hide();
604      }
605    }
606   });
607
608   // ここもテスト用
609   if ($('#cartPaymentModal').length > 0) {
610     var form = $('#cartPaymentModal .form')
611     var payment_urls = ['cart.html','reserve-complete.html']
612     $('#cartPaymentModal .form input[name="payment"]').on('change', function(){
613       if ($(this).val() == 'local') {
614         form.attr('action',payment_urls[1])
615       } else {
616         form.attr('action',payment_urls[0])
617       }
618     })
619   }
620
621   // ここもテスト用
622   $(document).on('click', '.cart-main .point-apply-btn' ,function(e){
623     let block = $(this).closest('.cart-result-block')
624     let price = block.find('.block-price').find('.price-num')
625     let priceNum = removeComma(price.text())
626     let val = $(this).prev('input').val()
627     val = removeComma(val)
628
629     let result = priceNum - val;
630     if (result < 0) {
631       result = 0;
632     } else {
633       result = result.toLocaleString();
634     }
635     price.text(result)
636   });
637
638  const hotelSearchForm = document.getElementById('hotelSearchForm');
639  if (!hotelSearchForm) return;
640
641  hotelSearchForm.addEventListener('submit', function (e) {
642    e.preventDefault();
643
644    // datepicker-checkin を送信対象から外す
645    const checkinInput = hotelSearchForm.querySelector(
646      '[name="datepicker-checkin"]'
647    );
648    if (checkinInput) {
649      checkinInput.disabled = true;
650    }
651
652    hotelSearchForm.submit();
653  });
654});

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.