見出し画像

【Shopify】九十九悪嵐のうぇぶでざいんびぼうろく。~年齢制限をかけてみる編~

※使用テーマは『Dawn』

バイト先で作っているECサイトの商品がお酒という、未成年買っちゃダメなやつのために作った年齢制限機能。何かと便利なのではと思ったので備忘録として残しておきます。

今回は商品タイプが「お酒」の商品を年齢制限の対象にしたいと思います。

【用意するもの】
・theme.liquid
・main-cart-footer.liquid

1.Layoutフォルダにあるtheme.liquidに以下のコードを追記する

  <script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
</head>

このコードを追記しないと、今回作る年齢制限機能が全く使えないので必ず入れましょう。

2.Sectionsフォルダにあるmain-cart-footer.liquidに以下のコードを追記する(HTML部分)

<div class="page-width{% if cart == empty %} is-empty{% endif %}" id="main-cart-footer" data-id="{{ section.id }}">
  <!-- ここから -->
  {% for item in cart.items %}
  {% if item.product.type == 'お酒' %}
  <div id="ageCheck" class="cart-attribute__field">  
    <div class="cart-birth">
      <div class="cart-birth__field">
        <label>大切な確認事項</label>
        <p class="caution">生年月日を選択してください。</p>
        <select required="" class="required birthday" id="birthday-year" name="attributes[年] attr1">
        </select>
        <span>年</span>
        <select required="" class="required birthday" id="birthday-month" name="attributes[月]">
        </select>
        <span>月</span>
        <select required="" class="required birthday" id="birthday-day" name="attributes[日]">
        </select> 
        <span>日</span>
      </div>
      <div class="consent">
        <div class="consent_box">
          <input type="hidden" name="attributes[以下の注意事項に同意します(必須)。]" value="No">
          <input required="" class="age-check required" type="checkbox" name="attributes[以下の注意事項に同意します(必須)。]" value="Yes" checked="">
          <label>以下の注意事項に同意します(必須)。</label>
        </div>
        <div class="consent_detail">
          <ul class="consent_list">
            <li class="consent_txt">生年月日が未入力または未成年者の場合、お酒の販売はお断りしております。</li>
            <li class="consent_txt">妊娠中や授乳期の飲酒は、胎児・乳児の発育に悪影響を与えるおそれがあります。</li>
          </ul>
        </div>  
      </div>
    </div>
  </div>
  {% break %}
  {% endif %}
  {% endfor %}
  <!-- ここまで追記 -->
  <div>
<!-- 省略 -->

3.checkout用のボタンにid属性を追加する

Windowsの場合はCtrl+F、Macの場合はcommand+Fを押下し、「name="checkout"」を検索して、出てきたコード(以下のようなコードのはず)を、

<button type="submit" class="cart__checkout-button button" name="checkout"{% if cart == empty %} disabled{% endif %} form="cart">
  {{ 'sections.cart.checkout' | t }}
</button>

以下のコードのようにしてあげます。

<button type="submit" id="checkout" class="cart__checkout-button button" name="checkout"{% if cart == empty %} disabled{% endif %} form="cart">
  {{ 'sections.cart.checkout' | t }}
</button>

id属性はなくてもいいですが、あった方が便利なので(JS的に)、追加してあげます。

4,Sectionsフォルダにあるmain-cart-footer.liquidに以下のコードを追記する(JS部分)

{% endjavascript %}
<!-- ここから -->
{% for item in cart.items %}
{% if item.product.type == 'お酒' %}
<script>
  /**
   *
   * 変数
   *
  **/
  let i;  // 生年月日の数値用
  const cartSubmit = $('.cart__footer #checkout');  // 購入手続きボタン
  let birthdayYear = document.getElementById("birthday-year");  // 生年月日[年]
  let birthdayMonth = document.getElementById("birthday-month");  // 生年月日[月]
  let birthdayDay = document.getElementById("birthday-day");  // 生年月日[日]
  const ageCheck = $(' .age-check ');  // 同意チェックボックス
  
  /**
   *
   * 初期値
   *
  **/
  ageCheck.prop('checked', false);  // 同意チェックボックス(チェックなし)
  cartSubmit.prop('disabled', true);  // 購入手続きボタン(押下不可)
  
  /* 生年月日[年]の設定 */
  function $set_year() {
    const selectYear = new Date();
    // 「未選択」用
    let not_select = document.createElement('option');
    not_select.value = '';
    not_select.text = '未選択';
    not_select.hidden = 'hidden';
    birthdayYear.appendChild(not_select);
    // 年を生成
    for(i = 1900; i < selectYear.getFullYear(); i++){
      let op = document.createElement('option');
      op.value = i;
      op.text = i;
      birthdayYear.appendChild(op);
    }
  }
  
  // 生年月日[月]の設定
  function $set_month(){
    // 「未選択」用
    const not_select = document.createElement('option');
    not_select.value = '';
    not_select.text = '未選択';
    not_select.hidden = 'hidden';
    birthdayMonth.appendChild(not_select);
    // 月を生成
    for(i = 1; i <= 12; i++){
      let op = document.createElement('option');
      op.value = i;
      op.text = i;
      birthdayMonth.appendChild(op);
    }
  }
  
  // 生年月日[日]の設定
  function $set_day(){
    //日の選択肢を空にする
    let children = birthdayDay.children;
    while(children.length){
      children[0].remove();
    }
    // 日を生成(動的に変える)
    if(birthdayYear.value !== '' &&  birthdayMonth.value !== ''){
      const last_day = new Date(birthdayYear.value,birthdayMonth.value,0).getDate();
      for (i = 1; i <= last_day; i++) {
        let op = document.createElement('option');
        op.value = i;
        op.text = i;
        birthdayDay.appendChild(op);
      }
    }else {
      // 「未選択」用
      let not_select = document.createElement('option');
      not_select.value = '';
      not_select.text = '未選択';
      birthdayDay.appendChild(not_select);
    }
  }
  
  /**
   *
   * イベント
   *
  **/
  // 「同意する」チェックボックス押下イベント
  ageCheck.on('click', function() {
    if( $(this).prop('checked') == true ) {  // 「同意する」チェックボックスにチェックが入っている場合
      if(birthdayYear.value != '' && birthdayMonth.value != '' && birthdayDay.value != '') {  // 生年月日が空白ではない場合
        // 年齢確認
        let age = getUserAge( birthdayYear.value, birthdayMonth.value, birthdayDay.value );
        if( age < 20) {  // 年齢が20歳未満の場合
          ageCheck.prop('checked', false);
          cartSubmit.prop('disabled', true);
        }else {  // 年齢が20歳以上の場合
          cartSubmit.prop('disabled', false);
        }
      }else {  // 生年月日が空白の場合
        ageCheck.prop('checked', false);
        cartSubmit.prop('disabled', true);
      }
    }else {  // 「同意する」チェックボックスにチェックが入っていない場合
      cartSubmit.prop('disabled', true);
    }
  });
  
  // 「ご購入の手続きへ」ボタン押下イベント
  cartSubmit.on('click', function() {
    if(ageCheck.prop('checked') == true ) {  // 「同意する」チェックボックスにチェックが入っている場合
      if(birthdayYear.value != '' && birthdayMonth.value != '' && birthdayDay.value != '') {  // 生年月日が空白ではない場合
        // 年齢確認
        let age = getUserAge( birthdayYear.value, birthdayMonth.value, birthdayDay.value );
        if( age < 20) {  // 年齢が20歳未満の場合
          ageCheck.prop('checked', false);
          cartSubmit.prop('disabled', true);
        }else {  // 年齢が20歳以上の場合
          cartSubmit.prop('disabled', false);
        }
      }else {  // 生年月日が空白の場合
        ageCheck.prop('checked', false);
        cartSubmit.prop('disabled', true);
      }
    }else {  // 「同意する」チェックボックスにチェックが入っていない場合
      cartSubmit.prop('disabled', true);
    }
  });
  
  // load時、年月変更時に実行する
  window.onload = function(){
    $set_year();
    $set_month();
    $set_day();
    birthdayYear.addEventListener('change',$set_day)
    birthdayMonth.addEventListener('change',$set_day)
  }
  
  /**
   *
   * 関数
   *
  **/
  // 年齢確認
  function getUserAge( year, month, day ) {
    //誕生日を一旦 Date クラスに変換する
    const birthdayDate = new Date(year, month - 1, day);
    
    if( year != birthdayDate.getFullYear() || (month - 1) != birthdayDate.getMonth() || day != birthdayDate.getDate() ) { // 不正の値判定
      return null;
    }
    
    //今日の日付けを取得する
    var todayDate = new Date();
    //誕生日を計算する
    var userAge = todayDate.getFullYear() - birthdayDate.getFullYear();
    // 誕生日
    var currentYearDate = new Date(todayDate.getFullYear(), birthdayDate.getMonth(), birthdayDate.getDate());
    if(currentYearDate > todayDate) {  // 今年の誕生日を迎えていない場合
      userAge = ( userAge - 1 );
    }
    
    return userAge;  // 年齢を返す
  }
</script>
{% break %}
{% endif %}
{% endfor %}
<!-- ここまで追記 -->
{% schema %}

これで完成です!

【初期画面】

【未成年の場合】

未成年の場合は必須のチェックすら押せないので、チェックアウト(購入)できない

【成人している場合】

成人している場合でも必須のチェックをしていないとチェックアウト(購入)できないけど、必須のチェックすればチェックアウト(購入)できる

CSSに関しては今回何も設定していないので、とてもシンプルなものになっていますが…。お好きなようにデザインしてください~。

参考サイト
https://qiita.com/doitokatsuki/items/28754d838397e4f2fb7f
https://www.t3a.jp/blog/web-develop/javascript-get-age/
https://takblog.site/web/?p=218
https://shopify.dev/api/liquid/objects

P.S.解説編作りました!

https://note.com/alarn99/n/ncbf334ecc1ff

この記事が気に入ったらサポートをしてみませんか?