楽天やAmazonでは当たり前の「配送日時指定」。当然ストア構築時のご要望としても多いのですが、残念ながらShopifyの基本機能では対応していません。
アプリを使えば簡単に実装ができるのですが、日時指定のためだけに月額費用を払うのもなー・・ということで、自分で実装できないか試してみたところ、思ったよりも簡単にできたので内容を共有しておきます。
サンプルのコードも載せていますので、参考にして下さい。
カレンダーを表示させるために「jQueryUI」を読み込む
jQueryUIとは、jQueryの便利な機能をさらにパッケージ化したものです。今回必要なカレンダー表示など、自分で実装をしようと思うと少し面倒なものがすぐに実装できるので非常に便利です。
では、配送日指定のためのカレンダーを表示させるために、theme.liquidで以下のコードを読み込みます。
{{ 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/base/jquery-ui.css' | stylesheet_tag }}
{{ 'https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js' | script_tag }}
{{ 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js' | script_tag }}
{{ 'https://rawgit.com/jquery/jquery-ui/master/ui/i18n/datepicker-ja.js' | script_tag }}
埋め込む位置に悩んだらheadタグの直前にしておきましょう。
上から順に
- jQueryUIのデザインを決めるもの(今回は一番ベーシックな base を使用)
- jQuery本体*必ず以下のUIよりも先に読み込む
- jQueryUI本体
- 日本語化のためのファイル
となっています。
配送日時のパーツを読み込むためのスニペットを作成する
次に配送日時のパーツを読み込むためのスニペットを作成します。
「新しいSnippetを追加する」から「date-picker.liquid」というファイルを作成します。(名前は自由ですが、コピペで実装をする際は合わせて下さい)
作成した空の「date-picker.liquid」に配送日指定を表示するためのコードを埋め込む
「date-picker.liquid」に以下のコードを埋め込みます。
{% comment %}
/**配送日時の指定**/
{% endcomment %}
<div style="width:200px; margin: 20px 0 20px auto;">
<span style="display:block; margin-bottom: 5px;">配送希望日</span>
<input type="radio" name="attributes[配送日指定の有無]" value="指定しない" id="datePicker__label--false" {% unless cart.attributes["配送指定の有無"] == "指定する" %} checked{% endunless %}>
<label for="datePicker__label--false">指定しない</label>
<input type="radio" name="attributes[配送日指定の有無]" value="指定する" id="datePicker__label--true" {% if cart.attributes["配送指定の有無"] == "指定する" %} checked{% endif %}>
<label for="datePicker__label--true">指定する</label>
<input id="datepicker" type="text" name="attributes[配送希望日]" value="{{ cart.attributes.date }}" placeholder="配送希望日を選択する" readonly disabled/>
</div>
<script>
//土日祝日指定
$.get("https://holidays-jp.github.io/api/v1/date.json", function(holidaysData) {
$("#datepicker").datepicker({
minDate: '+3D', //最短日の指定*3日後から指定可能
maxDate: '+2M', //最長日の指定*2ヶ月後まで指定可能
beforeShowDay: function(date) {
if (date.getDay() == 0) {
return [false, 'day-sunday', null];//trueで土曜日を選択可に変更
} else if (date.getDay() == 6) {
return [false, 'day-saturday', null];//trueで日曜日を選択可に変更
}
var holidays = Object.keys(holidaysData);
for (var i = 0; i < holidays.length; i++) {
var holiday = new Date(Date.parse(holidays[i]));
if (holiday.getYear() == date.getYear() &&
holiday.getMonth() == date.getMonth() &&
holiday.getDate() == date.getDate()) {
return [false, 'day-holiday', null];//trueで祝日を選択可に変更
}
}
return [true, 'day-weekday', null];
}
});
});
//配送指定がない場合に配送希望日を選択できないようにする
$(function(){
$( 'input[name="attributes[配送日指定の有無]"]:radio' ).change( function() {
var radioval = $(this).val();
if(radioval == "指定する"){
$('#datepicker').removeAttr('disabled');
}else{
$('#datepicker').attr('disabled','disabled').val("");
}
});
});
</script>
以下のような表示になっていればOKです。「保存」をクリックで変更した内容を保存しましょう。
コードの説明
スクリプトの部分にもコメントアウトをしていますが、ここでも簡単に説明します。
土日祝日(日本基準)の設定
上記のコードでは「土日祝日」を選択不可にしています。土日祝日も含めて選択をさせたい場合は、「day-sunday」や「day-holiday」の左側にある”false”を”true”という表記に変更して下さい。
日本基準の祝日の指定は以下を参考に設定しています。
https://www.site-convert.com/archives/2190#outline__4_2
最短発送日、最長の指定日の設定
「minDate: ‘+3D’」で指定できる最短の発送日を、「maxDate: ‘+2M’」で指定できる最長の指定日を設定しています。”D”は日(上記のコードなら3日後から指定可能)、”M”は月(2ヶ月後まで指定可能)です。
また、上記のコードはコードの簡略化のため「配送日」指定のみを実装しています。「配送希望時間帯」の実装方法は記事の後半に記載があります。
作成したスニペットをカートページに埋め込む
これでパーツ(date-picker.liquid)の用意ができました。実際にサイト上に表示するために、カートページで上記のスニペットを読み込みます。
「templates」の中からカートページのテンプレートの「cart-template.liquid」を選択します。(テーマによって名称が異なる場合があります。)
ここだけ少し難易度が高いです。cart-templateの中から配送日指定を表示させたい箇所の記述を見つけます。具体的には”合計金額が表示されてるっぽい箇所”を探しましょう。「subtotal」などで検索をすると見つかることが多いです。
合計金額を表示している箇所の真上に以下のコードを挿入します。
{% render 'date-picker' %}
先ほど作成した「date-picker.liquid」を読み込みますよーという記述です。こんな感じになっていればOK。
無事コードが挿入できたら「保存」をクリック。ここまでの内容を保存します。
これで配送日指定を表示させるための設定は完了です。
実際のページで表示を確認してみる
それでは実際のページで確認してみましょう。サンプルではデフォルトのテーマである「Debut」に埋め込んでいます。
このように配送日指定の項目が表示されていればOKです!「指定する」を選択することで、以下のようにカレンダーが表示されます。
ちゃんと土日祝日も選択不可になっていますね。
注文データの確認
実際に商品を注文してみると、注文情報の「メモ」の部分に以下のような情報が追加されているはずです。
配送時間帯の設定を追加する
配送日だけでなく配送時間帯も設定したい場合は、先ほど作成した「date-picker.liquid」に以下のコードを追加します。
<div style="width:200px; margin: 20px 0 20px auto;">
<span style="display:block; margin-bottom: 5px;">配送希望時間帯</span>
<select id="delivery-time" name="attributes[配送希望時間帯]">
<option value="指定なし" {% if cart.attributes["配送希望時間帯"] == "指定なし" %} selected{% endif %}>指定なし</option>
<option value="午前中" {% if cart.attributes["配送希望時間帯"] == "午前中" %} selected{% endif %}>午前中</option>
<option value="14時から16時" {% if cart.attributes["配送希望時間帯"] == "14時から16時" %} selected{% endif %}>14時から16時</option>
<option value="16時から18時" {% if cart.attributes["配送希望時間帯"] == "16時から18時" %} selected{% endif %}>16時から18時</option>
<option value="18時から20時" {% if cart.attributes["配送希望時間帯"] == "18時から20時" %} selected{% endif %}>18時から20時</option>
<option value="19時から21時" {% if cart.attributes["配送希望時間帯"] == "19時から21時" %} selected{% endif %}>19時から21時</option>
</select>
</div>
挿入位置は14行目辺りのHTMLとスクリプトの間にします。
変更をしたら「保存」をして、実際の画面で確認してみましょう。
こんな感じで表示されていればOK!時間帯はセレクトボックスで選択式になっています。
コードの説明
こちらも構造は単純でoptionのvalueとして設定している値が注文情報に登録されます。今回はクロネコヤマトの時間帯に合わせて設定をしていますが、日本郵便や佐川急便の日時指定に合わせる場合は値を変更して下さい。項目の追加もをコピペで、該当箇所を書き換えれば問題無しです。
注文データの確認
注文情報にはこんな感じで表示されます。
【サンプルコード】説明を読むのが面倒な方はこちら!
とりあえずコードだけコピペさせてくれ!という方は、以下のコードを入れた「date-picker.liquid」というスニペットを作成して下さい。
あとは日時指定を表示させたい箇所(cart-template.liquid内)に読み込ませればOKです。
(カレンダーを表示させるためには、jQueryUIを読み込む必要があります。)
{% comment %}
/**配送日時の指定**/
{% endcomment %}
<div style="width:200px; margin: 20px 0 20px auto;">
<span style="display:block; margin-bottom: 5px;">配送希望日</span>
<input type="radio" name="attributes[配送日指定の有無]" value="指定しない" id="datePicker__label--false" {% unless cart.attributes["配送指定の有無"] == "指定する" %} checked{% endunless %}>
<label for="datePicker__label--false">指定しない</label>
<input type="radio" name="attributes[配送日指定の有無]" value="指定する" id="datePicker__label--true" {% if cart.attributes["配送指定の有無"] == "指定する" %} checked{% endif %}>
<label for="datePicker__label--true">指定する</label>
<input id="datepicker" type="text" name="attributes[配送希望日]" value="{{ cart.attributes.date }}" placeholder="配送希望日を選択する" readonly disabled/>
</div>
<div style="width:200px; margin: 20px 0 20px auto;">
<span style="display:block; margin-bottom: 5px;">配送希望時間帯</span>
<select id="delivery-time" name="attributes[配送希望時間帯]">
<option value="指定なし" {% if cart.attributes["配送希望時間帯"] == "指定なし" %} selected{% endif %}>指定なし</option>
<option value="午前中" {% if cart.attributes["配送希望時間帯"] == "午前中" %} selected{% endif %}>午前中</option>
<option value="14時から16時" {% if cart.attributes["配送希望時間帯"] == "14時から16時" %} selected{% endif %}>14時から16時</option>
<option value="16時から18時" {% if cart.attributes["配送希望時間帯"] == "16時から18時" %} selected{% endif %}>16時から18時</option>
<option value="18時から20時" {% if cart.attributes["配送希望時間帯"] == "18時から20時" %} selected{% endif %}>18時から20時</option>
<option value="19時から21時" {% if cart.attributes["配送希望時間帯"] == "19時から21時" %} selected{% endif %}>19時から21時</option>
</select>
</div>
<script>
//土日祝日指定
$.get("https://holidays-jp.github.io/api/v1/date.json", function(holidaysData) {
$("#datepicker").datepicker({
minDate: '+3D',
maxDate: '+5M',
beforeShowDay: function(date) {
if (date.getDay() == 0) {
return [false, 'day-sunday', null];//trueで土曜日を選択可に変更
} else if (date.getDay() == 6) {
return [false, 'day-saturday', null];//trueで日曜日を選択可に変更
}
var holidays = Object.keys(holidaysData);
for (var i = 0; i < holidays.length; i++) {
var holiday = new Date(Date.parse(holidays[i]));
if (holiday.getYear() == date.getYear() &&
holiday.getMonth() == date.getMonth() &&
holiday.getDate() == date.getDate()) {
return [false, 'day-holiday', null];//trueで祝日を選択可に変更
}
}
return [true, 'day-weekday', null];
}
});
});
//配送指定がない場合に配送希望日を選択できないようにする
$(function(){
$( 'input[name="attributes[配送日指定の有無]"]:radio' ).change( function() {
var radioval = $(this).val();
if(radioval == "指定する"){
$('#datepicker').removeAttr('disabled');
}else{
$('#datepicker').attr('disabled','disabled').val("");
}
});
});
</script>
難しいと思ったらアプリの利用がおすすめ
いろいろやってみたけど上手くいかない・・という方は、以下のアプリがおすすめです!
https://apps.shopify.com/d?locale=ja
まとめ
カレンダーを表示するのにjQueryUIを使用しましたが、基本的には「name=”attributes[]”」の形で項目を増やしているだけなので、一度理解してしまえば簡単な内容だと思います。
よかったら本記事を参考にいろいろとカスタマイズしてみて下さい!
*本記事はHTMLやLiquidの基礎知識があることを前提に作成しています。掲載している内容は、ご自身で動作の確認や修正を行なっていただく事を前提に、自己責任でお願します。