通貨セレクター(国/地域セレクター)の作り方について解説します
※以下通貨セレクターで進めます
Dawnだとこんな通貨セレクターがありますよね!!
こちらをオリジナルで作って自由にカスタマイズしていきたいと思います
完成系はこちら
右上のものが自作した言語セレクターになります
※わかりやすいようにあえてヘッダーの上に配置しています。※下のセレクターはDawnデフォルトのもの
{% if localization.available_countries.size > 1 %}
<localization-form>
{% form 'localization' %}
<div class="c_currency-container">
<div type="button " class="c_disclosure__button c_currency-title" aria-expanded="false" aria-controls="CountryList">
{{ localization.country.name }} ({{ localization.country.currency.iso_code }} {{ localization.country.currency.symbol }}){% render 'icon-caret' %}
</div>
<ul id="CountryList" role="list" class="c_currency-list">
{% for country in localization.available_countries %}
<li class="c_disclosure__item" tabindex="-1">
<a href="#" {% if country.iso_code == localization.country.iso_code %} aria-current="true" {% endif %}
data-value="{{ country.iso_code }}" onclick="updateCountry('{{ country.iso_code }}'); return false;">
{{ country.name }} ({{ country.currency.iso_code }} {{ country.currency.symbol }})
</a>
</li>
{% endfor %}
</ul>
<input type="hidden" name="country_code" value="{{ localization.country.iso_code }}" id="country_code_hidden">
</div>
{% endform %}
</localization-form>
<script>
//クリック時にformを送信
function updateCountry(isoCode) {
document.getElementById("country_code_hidden").value = isoCode;
document.querySelector("localization-form form").submit();
}
document.addEventListener("DOMContentLoaded", function() {
const titleElement = document.querySelector(".c_currency-title");
const listElement = document.querySelector(".c_currency-list");
titleElement.addEventListener("click", function(event) {
event.stopPropagation();
listElement.classList.toggle("show");
});
document.addEventListener("click", function(event) {
if (!listElement.contains(event.target)) {
listElement.classList.remove("show");
}
});
});
</script>
<style>
.c_currency-container {
position: relative;
display: inline-block;
padding: 0 10px;
z-index: 1;
}
.c_currency-container svg {
width: 10px;
}
.c_currency-title {
display: inline-block;
cursor: pointer;
}
.c_currency-list {
position: absolute;
display: none;
top: 100%;
right: 0;
min-width: 100%;
width: max-content;
background: #fff;
margin: 0;
padding: 10px;
list-style: none;
}
.c_currency-list.show {
display: block;
}
.c_currency-list a {
font-size: 14px;
}
</style>
{% endif %}
上記コードを埋め込みたい箇所に貼り付けていただければ大丈夫です!
あとはて適宜CSSを調整していただければ自由にカスタマイズができます!
コードの解説
各種オブジェクト(localization)
今回のコードではlocalizationオブジェクトを使用しています
こちらのオブジェクトを使用して利用可能な国とその言語に対する情報を使用できます
{{ localization.country.name }} → 選択中の国の名前(日本)
{{ localization.country.iso_code }} → 選択中の国のISOコード(JPY)
{{ localization.country.currency.symbol }} → 選択中のシンボルマーク(¥)
利用可能な国をfor文で回して1つずつ出力させます セレクターの中身の部分(添付の赤枠)
{% for country in localization.available_countries %}
<li class="c_disclosure__item" tabindex="-1">
<a href="#" {% if country.iso_code == localization.country.iso_code %} aria-current="true" {% endif %}
data-value="{{ country.iso_code }}" onclick="updateCountry('{{ country.iso_code }}'); return false;">
{{ country.name }} ({{ country.currency.iso_code }} {{ country.currency.symbol }})
</a>
</li>
{% endfor %}
カスタムHTML<localization-form>
ん?なんか変なタグで囲ってるぞ?ってなりますよね!
私もなりましたw
こちらはカスタム要素というものでして、 HTMLのカスタム要素を使って独自のHTML(localization-form)を定義しています。
↓↓もうちょっと詳しく、カスタム要素とは?
formタグ{% form 'localization' %}{% endform %}
国セレクター、言語セレクター用のformタグがあらかじめShopifyで準備されていています
参考サイトこちらのコードで囲ってあげることで自動でformタグとinputタグが出力されます
自動で出力されるHTMLタグ↓↓
<form method="post" action="/localization" id="localization_form" accept-charset="UTF-8" class="shopify-localization-form" enctype="multipart/form-data">
<input type="hidden" name="form_type" value="localization" />
<input type="hidden" name="utf8" value="✓" />
<input type="hidden" name="_method" value="put" />
<input type="hidden" name="return_to" value="/" />
</form>
あとはJSで下記のinputのvalueに値を入れて送信するコードを書いてあげればうまく動作します。
formタグなので送信する必要がありますのでJavaScriptを使って値を送信しています
<script>
//クリック時にformを送信
function updateCountry(isoCode) {
document.getElementById("country_code_hidden").value = isoCode;
document.querySelector("localization-form form").submit();
}
document.addEventListener("DOMContentLoaded", function() {
const titleElement = document.querySelector(".c_currency-title");
const listElement = document.querySelector(".c_currency-list");
titleElement.addEventListener("click", function(event) {
event.stopPropagation();
listElement.classList.toggle("show");
});
document.addEventListener("click", function(event) {
if (!listElement.contains(event.target)) {
listElement.classList.remove("show");
}
});
});
</script>
Dawnだとこの記述でも動きます
{{ 'component-localization-form.css' | asset_url | stylesheet_tag: preload: true }}
{%- if localization.available_countries.size > 1 -%}
<localization-form class="header__icons--localization" >
{%- form 'localization', id: 'HeaderCountryForm', class: 'localization-form' -%}
<div>
<h2 class="visually-hidden" id="HeaderCountryLabel">{{ 'localization.country_label' | t }}</h2>
{%- render 'country-localization', localPosition: 'HeaderCountry' -%}
</div>
{%- endform -%}
</localization-form>
{% endif %}
<script src="{{ 'localization-form.js' | asset_url }}" defer="defer"></script>
こちらも適宜CSSでデザインを調整していただければと思います。
※Dawnのバージョンによってはうまく動かない可能性があるのでご注意ください
form用のCSSとJavaScriptを読み込んでいるんだなーと思っていただければ少しは理解ができるかと
通貨形式は非推奨
通貨形式は非推奨となり、ローカライズ形式に置き換えられました。
通貨形式がcurrencyを使ったものローカライズ形式はlocalizationを使ったものです!
今回紹介したものはローカライズ形式を使っていますのでご安心ください
{% form 'currency' %}
form_content
{% endform %}
currencyオブジェクトを使った通貨セレクターは非推奨となっていますのでご注意くださいね!
一応動きはしますがいつ使えなくなるかわからないので使わない事に越したことはないかと。。
まとめ
formを使った実装ができるようになると通貨セレクターだけではなく
カート周り、アカウント周り、お問い合わせのカスタマイズができるようになりますのでぜひ一度触ってみてください!
一旦はコピペで動きを見てみて
その後、記事を深く読んでみたり色々とググってみたりと色々といじいじしてみて下さい
localizationオブジェクト