スライダー(Slick.js)の多重構造と自動計算フォームとプリント
2019/02/08
更新日:2020/05/04
デモページへ
仕様書
多順のスライダーで色々な商品を閲覧させたいという希望を叶えるスライダーです。
大カテゴリーで選別して、また子カテゴリーでもスライダーさせます。
今回使用しているプラグインはスライダーで使用しているslick
また下の価格表のテーブルも連動して該当の場所にカーレントンが当たるようになっています。
配送日もデータ属性を使い動的に操作できるようにしています。
フォームに関しては100個以上から3000以下のバリデーションの追加。
オプションによりカスタムな値段オプションに対応。
最後は計算結果をプリントに出力、もしくはPDF出力、そのままメールにお問い合わせを頂けるような運営を想定しています。
スライダーの実装
2つのスライダーの祖であるjs-slider-for
とjs-slider-tab
を初期化していきます。
$(function() {
$('.js-slider-for').slick({
slidesToShow: 1,
slidesToScroll: 1,
arrows: false,
fade: true,
asNavFor: '.js-slider-tab',
swipe: false,
infinite: false
});
$('.js-slider-tab').slick({
slidesToShow: 6,
slidesToScroll: 1,
asNavFor: '.js-slider-for',
arrows: false,
centerMode: true,
swipe: false,
focusOnSelect: true,
infinite: false
});
})
下のスライダーに対しての処理を追加
下のスライダーはスライダーの中でまたタブ繊維を行い、その中でcuurentのクラス付けclass="js-bgChange"
をつくようにします。
$(function() {
var $slider = $('.slider-lower');
$slider.each(function() {
var $sliderItem = $(this).find('.js-slider-lower');
var $typeItem = $(this)
.find('.js-slider-lower-page')
.children('.js-slider-lower-page-item');
var activeClass = 'js-type-active';
$typeItem.each(function() {
var index = $typeItem.index(this);
$(this).attr('data-index', index);
});
$sliderItem.on('init', function(slick) {
var index = $(this)
.find('.slick-slide.slick-current')
.attr('data-slick-index');
$(this)
.closest($slider)
.find(
'.js-slider-lower-page-item' +
'[data-index="' +
index +
'"]'
)
.addClass(activeClass);
$(this)
.closest($slider)
.find('.table__price:nth-of-type(' + index + 1 + ')')
.addClass('js-bgChange');
});
if ($(this).hasClass('js-slide-circle')) {
var showNum = 3;
} else if ($(this).hasClass('js-slide-square')) {
var showNum = 1;
} else {
var showNum = 0;
}
$sliderItem.slick({
arrows: true,
fade: true,
initialSlide: showNum,
infinite: false
});
$typeItem.on('click', function() {
var index = $(this).attr('data-index');
$sliderItem.slick('slickGoTo', index, false);
$(this)
.closest('.slider-lower')
.find('.table__price')
.removeClass('js-bgChange');
var $dataTr = $(this)
.closest('.slider-lower')
.find('tr');
$dataTr.each(function() {
$(this)
.find('.table__price')
.eq(index)
.addClass('js-bgChange')
.siblings()
.removeClass('js-bgChange');
});
});
$sliderItem.on('beforeChange', function(
event,
slick,
currentSlide,
nextSlide
) {
$typeItem.each(function() {
$(this).removeClass(activeClass);
});
$(this)
.closest($slider)
.find(
'.js-slider-lower-page-item' +
'[data-index="' +
nextSlide +
'"]'
)
.addClass(activeClass);
var $dataTr = $(this)
.closest('.slider-lower')
.find('tr');
$dataTr.each(function() {
$(this)
.find('.table__price')
.eq(nextSlide)
.addClass('js-bgChange')
.siblings()
.removeClass('js-bgChange');
});
});
});
});
次にフォームを設定していきます。
個数によって価格を変動させたいので、個数により元値を変えていきます。またオプションの追加により金額調整も行っていきます。
注文のロットが100以下の場合はエラーで入力の停止、また3001以上のロットは選択不可とする条件も追加しましょう。
$(function() {
var $item = $('.js-autocalc');
var $error = $('.js-error');
var $option = $('.js-autocalc-option').find('input[type="checkbox"]');
var $option1 = $('.js-autocalc-option1');
var $option2 = $('.js-autocalc-option2');
var $option3 = $('.js-autocalc-option3');
$item.each(function() {
var $input = $(this).find('.js-autocalc-input');
var $output = $(this).find('.js-autocalc-conf');
var $thisError = $(this).find($error);
$input.on('change', function() {
// 半角変換
var halfVal = $(this)
.val()
.replace(/[!-~]/g, function(tmpStr) {
// 文字コードをシフト
return String.fromCharCode(tmpStr.charCodeAt(0) - 0xfee0);
});
// 数字以外の不要な文字を削除
var val = $(this)
.val(halfVal.replace(/[^0-9]/g, ''))
.val();
//ロット数で条件分岐
if (val < 1) {
var price = null;
} else if (1 <= val && val < 100) {
var price = 0;
} else if (100 <= val && val < 300) {
var price = $(this)
.closest($item)
.find('.js-autocalc-price1')
.val();
} else if (300 <= val && val < 500) {
var price = $(this)
.closest($item)
.find('.js-autocalc-price2')
.val();
} else if (500 <= val && val < 1000) {
var price = $(this)
.closest($item)
.find('.js-autocalc-price3')
.val();
} else if (1000 <= val && val < 1500) {
var price = $(this)
.closest($item)
.find('.js-autocalc-price4')
.val();
} else if (1500 <= val && val < 2000) {
var price = $(this)
.closest($item)
.find('.js-autocalc-price5')
.val();
} else if (2000 <= val && val < 2500) {
var price = $(this)
.closest($item)
.find('.js-autocalc-price6')
.val();
} else if (2500 <= val && val < 3001) {
var price = $(this)
.closest($item)
.find('.js-autocalc-price7')
.val();
} else {
var price = 'over';
}
//オプション1
if ($option1.prop('checked')) {
var option1 = 5;
} else {
var option1 = 0;
}
//オプション2
if ($option2.prop('checked')) {
var option2 = -500;
} else {
var option2 = 0;
}
//オプション3
if ($option3.prop('checked')) {
var option3 = 20000;
} else {
var option3 = 0;
}
if (price === null) {
$thisError.text('');
$output.text('0');
} else if (price === 0) {
$thisError.text('ご注文は100以上からになります'); //指定個数未満時のアクrション
$output.text('0');
} else if (price === 'over') {
$thisError.text('3001個以上はお問い合わせください'); //指定個数未満時のアクrション
$output.text('0');
} else {
var result = val * price + val * option1 + option2 + option3; //合計
$output.text(result); //出力
$thisError.text('');
}
});
});
最後にフォームで設定したものをプリントとして出力します。
フォームで入力されたデータをもとにHTMLをappendしていきます。
$(function() {
var $item = $('.js-loop'); //連続するの要素
var $input = $item.find('.js-loop-input'); //値を取得する要素
var $output = $('.js-print-output'); //出力先の要素
var $total = $('.js-loop-total'); //出力先の要素
var $option1 = $('.js-autocalc-option1');
var $option2 = $('.js-autocalc-option2');
var $option3 = $('.js-autocalc-option3');
var total;
$input.on('change', function() {
$output.empty(); //出力先の要素を空にする
$item.each(function(i) {
//連続するの要素内の値を取得
var val1 = $(this)
.find('.js-loop-input1')
.text();
var val2 = $(this)
.find('.js-loop-input2')
.val();
var val3 = $(this)
.find('.js-loop-input3')
.text();
//値があったら取得した値を出力
if (val1 && 99 < val2 && val3 && 3001 > val2) {
var val3 = Number(val3);
var val3 = val3.toLocaleString();
$output.append(
'<div class="print__body-container loop-container-' +
[i] +
'"></div>'
); //出力する親要素を連番管理
$('.loop-container-' + [i]).append(
'<div class="print__body-info loop-div-' + [i] + '"></div>'
); //出力する親要素を連番管理
$('.loop-div-' + [i]).append(
'<p class="print__body-name">品目: ' + val1 + '</p>'
);
$('.loop-div-' + [i]).append(
'<p class="print__body-sum">合計金額 ' + val3 + ' 円</p>'
);
$('.loop-container-' + [i]).append(
'<ul class="print__body-list loop-ul-' + [i] + '"></ul>'
); //出力する親要素を連番管理
$('.loop-ul-' + [i]).append(
'<li class="print__body-list-item"><dl class="print__body-lot-definition"><dt class="print__body-lot-definition-title">個数</dt><dd class="print__body-lot-definition-text">' +
val2 +
'<span>個</span></dd></dl></li>'
);
$('.loop-container-' + [i]).append(
'<ul class="print__body-list loop-ul-option-' +
[i] +
'"></ul>'
); //出力する親要素を連番管理
if ($option1.prop('checked')) {
$('.loop-ul-option-' + [i]).append(
'<li class="print__body-list-item print__body-list-item--option">透明PP袋入れ</li>'
);
}
if ($option2.prop('checked')) {
$('.loop-ul-option-' + [i]).append(
'<li class="print__body-list-item print__body-list-item--option">デザイン6種類以上</li>'
);
}
if ($option3.prop('checked')) {
$('.loop-ul-option-' + [i]).append(
'<li class="print__body-list-item print__body-list-item--option">色校正</li>'
);
}
}
});