見出し画像

[Shopify]会員登録画面でバースデーと性別も入力できるようにする(Dawn)18/100

こんにちは。Shopify専門エンジニアのまりん(@crowd37cord)です。

Shopifyのデフォルトのアカウント新規登録画面では、お誕生日と性別設定画面がないので、追加してみました。管理画面で顧客メモにも反映されるので、マーケティングとかで活用してもらえるかなと思います!

さらに、おまけで、パスワード確認用も追加してます。
さらにさらに、アカウント作成と同時に顧客タグに自動的にVIPタグが付与されるようにもしてみました。

ちなみに、顧客タグは決済画面からアカウント作成した場合には反映されません><

✔️今回のゴール

アカウント作成画面でパスワード確認/生年月日/性別 追加


管理画面の顧客管理の各顧客メモに反映


メール・パスワード未入力の場合エラー(Shopifyデフォルト機能)
ここに、パスワード確認エリアを追加し一致しなければエラー表示を追加


おまけ:顧客タグにVIPタグが自動付与される

誕生月に合わせてバースデークーポン配布などで活用できます!

✔️手順

❶コード編集>Templates内>customers/register.liquidを開く

customers/register.liquidは既存ファイルですので新規作成は不要です。

以下のコードをformタグ内のお好きなところに挿入してください。ちなみに私は、buttonタグの上に挿入してます。

    <div class="field">     
      <input
        type="password"
        id="RegisterForm-password-confirm"
        name="customer[password_confirmation]"
        aria-required="true"
        {% if form.errors contains 'password' %}
          aria-invalid="true"
          aria-describedby="RegisterForm-password-error"
        {% endif %}
        placeholder="パスワード確認用"
      >
      <label for="RegisterForm-password-confirm">
        パスワード確認用
      </label>
    </div>
    <p class="js-confirm-error"></p>
    {%- if form.errors contains 'password' -%}
      <span id="RegisterForm-password-error" class="form__message form-error">
        {{ form.errors.translated_fields['password'] | capitalize }} {{ form.errors.messages['password'] }}
      </span>
    {%- endif -%}
    
    <p id="output-message" class="form__message form-error"></p>
      
    
    <div class="customer-birthday">
      <p>生年月日</p>
      <ul class="grid grid--3-col">
        <li class="grid__item"><select id="year" name="customer[note][Year]"><option value="0">Year</option></select></li>
        <li class="grid__item"><select id="month" name="customer[note][Month]"><option value="0">Month</option></select></li>
        <li class="grid__item"><select id="day" name="customer[note][Day]"><option value="0">Day</option></select></li>
      </ul> 
    </div>    
    
    <div class="customer-gender">
      <p>性別</p>
      <input type="radio" name="customer[note][性別]" value="男性" id="male">男性      
      <input type="radio" name="customer[note][性別]" value="女性" id="female">女性
      <input type="radio" name="customer[note][性別]" value="ひみつ" id="secret">ひみつ
    </div>
    
    <input type="hidden" id="customer_tags" name="customer[tags]" value="vip"/>

次に、デフォルトの以下のbuttonタグを

<button>
      {{ 'customer.register.submit' | t }}
</button>

▼こちらに置き換えてください

<button onclick="return Validate()">
      {{ 'customer.register.submit' | t }}
 </button>

onclick="return Validate()"を追記しています。

▼こちらはおまけで、「戻る」ボタンも作りました

  <div class="customer-backhome">
        <a href="{%- if customer -%}{{ routes.account_url }}{%- else -%}{{ routes.account_login_url }}{%- endif -%}" class="customer_link">戻る</a>
  </div> 

customers/register.liquidフルコード

{{ 'customer.css' | asset_url | stylesheet_tag }}

<div class="customer register">
  <svg style="display: none">
    <symbol id="icon-error" viewBox="0 0 13 13">
      <circle cx="6.5" cy="6.50049" r="5.5" stroke="white" stroke-width="2"/>
      <circle cx="6.5" cy="6.5" r="5.5" fill="#EB001B" stroke="#EB001B" stroke-width="0.7"/>
      <path d="M5.87413 3.52832L5.97439 7.57216H7.02713L7.12739 3.52832H5.87413ZM6.50076 9.66091C6.88091 9.66091 7.18169 9.37267 7.18169 9.00504C7.18169 8.63742 6.88091 8.34917 6.50076 8.34917C6.12061 8.34917 5.81982 8.63742 5.81982 9.00504C5.81982 9.37267 6.12061 9.66091 6.50076 9.66091Z" fill="white"/>
      <path d="M5.87413 3.17832H5.51535L5.52424 3.537L5.6245 7.58083L5.63296 7.92216H5.97439H7.02713H7.36856L7.37702 7.58083L7.47728 3.537L7.48617 3.17832H7.12739H5.87413ZM6.50076 10.0109C7.06121 10.0109 7.5317 9.57872 7.5317 9.00504C7.5317 8.43137 7.06121 7.99918 6.50076 7.99918C5.94031 7.99918 5.46982 8.43137 5.46982 9.00504C5.46982 9.57872 5.94031 10.0109 6.50076 10.0109Z" fill="white" stroke="#EB001B" stroke-width="0.7">
    </symbol>
  </svg>
  <h1>
    {{ 'customer.register.title' | t }}
  </h1>
  {%- form 'create_customer', novalidate: 'novalidate' -%}
    {%- if form.errors -%}
      <h2 class="form__message" tabindex="-1" autofocus>
        <svg aria-hidden="true" focusable="false" role="presentation">
          <use href="#icon-error" />
        </svg>
        {{ 'templates.contact.form.error_heading' | t }}
      </h2>
      <ul> 
        {%- for field in form.errors -%}
          <li>
            {%- if field == 'form' -%}
              {{ form.errors.messages[field] }}
            {%- else -%}
              <a href="#RegisterForm-{{ field }}">
                {{ form.errors.translated_fields[field] | capitalize }}
                {{ form.errors.messages[field] }}
              </a>
            {%- endif -%}
          </li>
        {%- endfor -%}
      </ul>
    {%- endif -%}
    <div class="field">      
      <input
        type="text"
        name="customer[first_name]"
        id="RegisterForm-FirstName"
        {% if form.first_name %}value="{{ form.first_name }}"{% endif %}
        autocomplete="given-name"
        placeholder="{{ 'customer.register.first_name' | t }}"
      >
      <label for="RegisterForm-FirstName">
        {{ 'customer.register.first_name' | t }}
      </label>
    </div>
    <div class="field">
      <input
        type="text"
        name="customer[last_name]"
        id="RegisterForm-LastName"
        {% if form.last_name %}value="{{ form.last_name }}"{% endif %}
        autocomplete="family-name"
        placeholder="{{ 'customer.register.last_name' | t }}"
      >
      <label for="RegisterForm-LastName">
        {{ 'customer.register.last_name' | t }}
      </label>
    </div>
    <div class="field">      
      <input
        type="email"
        name="customer[email]"
        id="RegisterForm-email"
        {% if form.email %} value="{{ form.email }}"{% endif %}
        spellcheck="false"
        autocapitalize="off"
        autocomplete="email"
        aria-required="true"
        {% if form.errors contains 'email' %}
          aria-invalid="true"
          aria-describedby="RegisterForm-email-error"
        {% endif %}
        placeholder="{{ 'customer.register.email' | t }}"
      >
      <label for="RegisterForm-email">
        {{ 'customer.register.email' | t }}
      </label>
    </div>
    {%- if form.errors contains 'email' -%}
      <span id="RegisterForm-email-error" class="form__message">
        <svg aria-hidden="true" focusable="false" role="presentation">
          <use href="#icon-error" />
        </svg>
        {{ form.errors.translated_fields['email'] | capitalize }} {{ form.errors.messages['email'] }}.
      </span>
    {%- endif -%}
    <div class="field">     
      <input
        type="password"
        name="customer[password]"
        id="RegisterForm-password"
        aria-required="true"
        {% if form.errors contains 'password' %}
          aria-invalid="true"
          aria-describedby="RegisterForm-password-error"
        {% endif %}
        placeholder="{{ 'customer.register.password' | t }}"
      >
      <label for="RegisterForm-password">
        {{ 'customer.register.password' | t }}
      </label>
    </div>
    {%- if form.errors contains 'password' -%}
      <span id="RegisterForm-password-error" class="form__message">
        <svg aria-hidden="true" focusable="false" role="presentation">
          <use href="#icon-error" />
        </svg>
        {{ form.errors.translated_fields['password'] | capitalize }} {{ form.errors.messages['password'] }}.
      </span>
    {%- endif -%}
         <div class="field">     
      <input
        type="password"
        id="RegisterForm-password-confirm"
        name="customer[password_confirmation]"
        aria-required="true"
        {% if form.errors contains 'password' %}
          aria-invalid="true"
          aria-describedby="RegisterForm-password-error"
        {% endif %}
        placeholder="パスワード確認用"
      >
      <label for="RegisterForm-password-confirm">
        パスワード確認用
      </label>
    </div>
    <p class="js-confirm-error"></p>
    {%- if form.errors contains 'password' -%}
      <span id="RegisterForm-password-error" class="form__message form-error">
        {{ form.errors.translated_fields['password'] | capitalize }} {{ form.errors.messages['password'] }}
      </span>
    {%- endif -%}
    
    <p id="output-message" class="form__message form-error"></p>
      
    
    <div class="customer-birthday">
      <p>生年月日</p>
      <ul class="grid grid--3-col">
        <li class="grid__item"><select id="year" name="customer[note][Year]"><option value="0">Year</option></select></li>
        <li class="grid__item"><select id="month" name="customer[note][Month]"><option value="0">Month</option></select></li>
        <li class="grid__item"><select id="day" name="customer[note][Day]"><option value="0">Day</option></select></li>
      </ul> 
    </div>    
    
    <div class="customer-gender">
      <p>性別</p>
      <input type="radio" name="customer[note][性別]" value="男性" id="male">男性      
      <input type="radio" name="customer[note][性別]" value="女性" id="female">女性
      <input type="radio" name="customer[note][性別]" value="ひみつ" id="secret">ひみつ
    </div>
    
    <input type="hidden" id="customer_tags" name="customer[tags]" value="vip"/>
    
    <button onclick="return Validate()">
      {{ 'customer.register.submit' | t }}
    </button>
  {%- endform -%}
</div>

ちなみに、この画面で新規アカウント作成をすると、VIPという顧客タグが自動的につくようにしています。必要なければ削除してください。

▼ここ

<input type="hidden" id="customer_tags" name="customer[tags]" value="vip"/>


ログイン画面のフルコードものせておきます

◆customers/login.liquidフルコード

{{ 'customer.css' | asset_url | stylesheet_tag }}


<div class="customer login">
  <h1 id="recover" tabindex="-1">
    {{ 'customer.recover_password.title' | t }}
  </h1>
  <div>
    <p>
      {{ 'customer.recover_password.subtext' | t }}
    </p>

    {%- form 'recover_customer_password' -%}
      {% assign recover_success = form.posted_successfully? %}
      <div class="field">
        <input type="email"
          value=""
          name="email"
          id="RecoverEmail"
          autocorrect="off"
          autocapitalize="off"
          autocomplete="email"
          {% if form.errors %}
            aria-invalid="true"
            aria-describedby="RecoverEmail-email-error"
            autofocus
          {% endif %}
          placeholder="{{ 'customer.login_page.email' | t }}"
        >
        <label for="RecoverEmail">
          {{ 'customer.login_page.email' | t }}
        </label>
      </div>
      {%- if form.errors -%}
        <small id="RecoverEmail-email-error" class="form__message">
          <svg aria-hidden="true" focusable="false" role="presentation" viewBox="0 0 13 13">
            <circle cx="6.5" cy="6.50049" r="5.5" stroke="white" stroke-width="2"/>
            <circle cx="6.5" cy="6.5" r="5.5" fill="#EB001B" stroke="#EB001B" stroke-width="0.7"/>
            <path d="M5.87413 3.52832L5.97439 7.57216H7.02713L7.12739 3.52832H5.87413ZM6.50076 9.66091C6.88091 9.66091 7.18169 9.37267 7.18169 9.00504C7.18169 8.63742 6.88091 8.34917 6.50076 8.34917C6.12061 8.34917 5.81982 8.63742 5.81982 9.00504C5.81982 9.37267 6.12061 9.66091 6.50076 9.66091Z" fill="white"/>
            <path d="M5.87413 3.17832H5.51535L5.52424 3.537L5.6245 7.58083L5.63296 7.92216H5.97439H7.02713H7.36856L7.37702 7.58083L7.47728 3.537L7.48617 3.17832H7.12739H5.87413ZM6.50076 10.0109C7.06121 10.0109 7.5317 9.57872 7.5317 9.00504C7.5317 8.43137 7.06121 7.99918 6.50076 7.99918C5.94031 7.99918 5.46982 8.43137 5.46982 9.00504C5.46982 9.57872 5.94031 10.0109 6.50076 10.0109Z" fill="white" stroke="#EB001B" stroke-width="0.7">
          </svg>
          {{ form.errors.messages['form'] }}
        </small>
      {%- endif -%}

      <button>
        {{ 'customer.login_page.submit' | t }}
      </button>

      <div>
      <a href="#login">
        {{ 'customer.login_page.cancel' | t }}
      </a>
      </div>
    {%- endform -%}
  </div>

  <h1 id="login" tabindex="-1">
    {{ 'customer.login_page.title' | t }}
  </h1>
  <div>
    {%- if recover_success == true -%}
      <h3 class="form__message" tabindex="-1" autofocus>
        <svg aria-hidden="true" focusable="false" role="presentation" viewBox="0 0 13 13">
          <path d="M6.5 12.35C9.73087 12.35 12.35 9.73086 12.35 6.5C12.35 3.26913 9.73087 0.65 6.5 0.65C3.26913 0.65 0.65 3.26913 0.65 6.5C0.65 9.73086 3.26913 12.35 6.5 12.35Z" fill="#428445" stroke="white" stroke-width="0.7"/>
          <path d="M5.53271 8.66357L9.25213 4.68197" stroke="white"/>
          <path d="M4.10645 6.7688L6.13766 8.62553" stroke="white">
        </svg>
        {{ 'customer.recover_password.success' | t }}
      </h3>
    {%- endif -%}
    {%- form 'customer_login', novalidate: 'novalidate' -%}
      {%- if form.errors -%}
        <h2 class="form__message" tabindex="-1" autofocus>
          <span class="visually-hidden">{{ 'accessibility.error' | t }} </span>
          <svg aria-hidden="true" focusable="false" role="presentation" viewBox="0 0 13 13">
            <circle cx="6.5" cy="6.50049" r="5.5" stroke="white" stroke-width="2"/>
            <circle cx="6.5" cy="6.5" r="5.5" fill="#EB001B" stroke="#EB001B" stroke-width="0.7"/>
            <path d="M5.87413 3.52832L5.97439 7.57216H7.02713L7.12739 3.52832H5.87413ZM6.50076 9.66091C6.88091 9.66091 7.18169 9.37267 7.18169 9.00504C7.18169 8.63742 6.88091 8.34917 6.50076 8.34917C6.12061 8.34917 5.81982 8.63742 5.81982 9.00504C5.81982 9.37267 6.12061 9.66091 6.50076 9.66091Z" fill="white"/>
            <path d="M5.87413 3.17832H5.51535L5.52424 3.537L5.6245 7.58083L5.63296 7.92216H5.97439H7.02713H7.36856L7.37702 7.58083L7.47728 3.537L7.48617 3.17832H7.12739H5.87413ZM6.50076 10.0109C7.06121 10.0109 7.5317 9.57872 7.5317 9.00504C7.5317 8.43137 7.06121 7.99918 6.50076 7.99918C5.94031 7.99918 5.46982 8.43137 5.46982 9.00504C5.46982 9.57872 5.94031 10.0109 6.50076 10.0109Z" fill="white" stroke="#EB001B" stroke-width="0.7">
          </svg>
          {{ 'templates.contact.form.error_heading' | t }}
        </h2>
        {{ form.errors | default_errors }}
      {%- endif -%}

      <div class="field">        
        <input
          type="email"
          name="customer[email]"
          id="CustomerEmail"
          autocomplete="email"
          autocorrect="off"
          autocapitalize="off"
          {% if form.errors contains 'form' %}
            aria-invalid="true"
          {% endif %}
          placeholder="{{ 'customer.login_page.email' | t }}"
        >
        <label for="CustomerEmail">
          {{ 'customer.login_page.email' | t }}
        </label>
      </div>

      {%- if form.password_needed -%}
        <div class="field">          
          <input
            type="password"
            value=""
            name="customer[password]"
            id="CustomerPassword"
            autocomplete="current-password"
            {% if form.errors contains 'form' %}
              aria-invalid="true"
            {% endif %}
            placeholder="{{ 'customer.login_page.password' | t }}"
          >
          <label for="CustomerPassword">
            {{ 'customer.login_page.password' | t }}
          </label>
        </div>

        <a href="#recover" class="customer_link">
          {{ 'customer.login_page.forgot_password' | t }}
        </a>
      {%- endif -%}

      <button>
        {{ 'customer.login_page.sign_in' | t }}
      </button>

      <div class="customer-register">
        <a href="{{ routes.account_register_url }}" class="signup-btn">
          {{ 'customer.login_page.create_account' | t }}
        </a>
      </div>
          
   
      
    {%- endform -%}
  </div>
        
  <div class="customer-backhome">
        <a href="/" class="customer_link">HOMEへ戻る</a>
  </div> 
  
  {%- if shop.checkout.guest_login -%}
    <div>
      <hr>
      <h2>{{ 'customer.login_page.guest_title' | t }}</h2>

      {%- form 'guest_login' -%}
        <button>
          {{ 'customer.login_page.guest_continue' | t }}
        </button>
      {%- endform -%}
    </div>
  {%- endif -%}
</div>


❷Assets>global.jsにコピペ

JSファイルに追記します

global.jsの一番最後の行に以下のコードをコピペ

// --------------------▼ 誕生日 ▼--------------------

var time = new Date();
var year = time.getFullYear();

for (var i = year; i >= 1900; i--) {
  createOptionElements(i,'year');
}

for (var i = 1; i <= 12; i++) {
  createOptionElements(i,'month');
}

for (var i = 1; i <= 31; i++) {
  createOptionElements(i,'day');
}

function createOptionElements(num,parentId){
    var doc = document.createElement('option');
    doc.value = doc.innerHTML = num;
    document.getElementById(parentId).appendChild(doc);
}

// --------------------▲ 誕生日 ▲--------------------


// --------------------▼ パスワード一致 ▼--------------------

function Validate() {
        var password = document.getElementById("RegisterForm-password").value;
        var confirmPassword = document.getElementById("RegisterForm-password-confirm").value;
        if (password != confirmPassword) {
            
            document.getElementById("output-message").innerHTML = "パスワードが一致しません";
            return false;
        }
        return true;
}

// --------------------▲ パスワード一致 ▲--------------------

以上で完了です!

CSSはお好きにご変更ください。

✔️CSSフルコード

デザインはお好みで変更でき流のですが、一応以下のデザインのCSSもご紹介しておきます♪

ログイン画面


アカウント作成画面


❶Assets>base.cssにコピペ

以下のコードを一番下へ追加し保存

◆base.css

/* 追加 */
  .customer button {
    box-shadow: none;  
  }
  
.field__label,
.customer .field label {
  font-size: 1.4rem; 
  padding-top: 0.2rem;  
  opacity: 0.6;  
}
  
.field__input,
.select__select,
.customer .field input,
.customer select {
 border-radius: 10px; 
}
  
.button,
.shopify-challenge__button,
.customer button {
  border-radius: 50px; 
  padding: 1.3em 2em;  
  width: 300px; 
}  

❷Assets>customer.cssにコピペ

以下のコードを一番下へコピペ

◆customer.css

/* =========== 追加 =========== */


.customer h1 {
  font-size: 1em;
 }
  
  a.customer_link {
    text-align: right;
    width: 100%;
    font-size: 0.9em;
    color: #4888cb;
    text-decoration: none;
    letter-spacing: 0.2em;
  }
  
  a.customer_link:hover {
    text-decoration: underline;
    color: #4888cb;
    opacity: 0.5;
  }
  
  .customer button,
  .customer button:hover,
  a.signup-btn,
  a.signup-btn:hover {
   transition: 0.4s;
  }
  
  .customer button:hover,
  a.signup-btn {
    color: #727272;
  }
  
  
  .customer button:hover {
    background-color: transparent;
    border: 1px solid #727272;
    box-shadow: none;
  }
  
  a.signup-btn {
    border: 1px solid #727272;
    width: 300px;
    border-radius: 50px;
    padding: 1em 2em;
    text-decoration: none;
  }
  
  a.signup-btn:hover {
    background-color: #000;
    color:#fff;
  }
  
  .customer-register {
    margin-top: 1em;
  }
  
  .customer-backhome {
   margin-top: 3em;
    padding: 2em;
  }
  
  .customer-backhome a {
    text-align: center !important;
  }
 
  .customer.register ul {
    padding-left: 0;
    margin-bottom: 1rem;
  }
  
  .customer-birthday {
    margin-top: 3rem;
    text-align: left;
    font-size: 1.4rem;
  }
  
  .customer-gender {
    margin-top: 2rem;
    font-size: 1.1em;
    text-align: left;
  }
  
  .customer-gender p {
    margin-bottom: 0;
     font-size: 0.8em;
  }
  
  .form-error {
    color: #ff0000;
  }


@media only screen and (max-width: 749px) {
 a.customer_link {
    text-align: center;
 }
}


base.cssとcustomer.cssのそれぞれのフルコードもこちらへご紹介しておきますね。

【ご注意】
※返金&サポートはしておりません。
※Dawnテーマ対象です。
※コードのみのご紹介で解説などはしておりません。
※2021.12.29時点のコードです。メンテナンスは今後する予定はありません。
※CSSのみのコードになります。

そのままのフルコードをコピペしてご使用いただいてもOKですが、すでに他の修正とかされている場合は対象箇所のみご使用ください。


ここから先は

58,523字

¥ 500

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