1画面内でステップが進むフォーム
解説
1画面内で進んだり戻れたりするステップフォームです。
bootstrap4、ContactForm7、jQueryを使っています。
次に進むボタンを押すと、c-form-step__wrapper-boxで囲まれた要素が切り替わります。
ショートコードで書かれた部分はContactForm7のフォーム部分に記載するとhtmlが生成されます。
改行がたくさん出てしまう場合は、スペースと改行を削除するか、funcions.phpに以下の一文を入れるとContactForm7の自動改行が停止します。
add_filter( 'wpcf7_autop_or_not', '__return_false' ); //Contact Form 7の自動整形を停止 version 5.2以上
コードの精査はできていないので、このままでは綺麗に表示できないかもしれません。
スタイルシートの調整は適宜お願いします。
html
<div class="form-horizontal c-form-step">
<div class="c-form-step__step-items">
<div class="c-form-step__step-items__item-box current">1</div>
<!-- /.c-form-step__step-items__item-box -->
<div class="c-form-step__step-items__item-box">2</div>
<!-- /.c-form-step__step-items__item-box -->
<div class="c-form-step__step-items__item-box">3</div>
<!-- /.c-form-step__step-items__item-box -->
<div class="c-form-step__step-items__item-box">4</div>
<!-- /.c-form-step__step-items__item-box -->
<div class="c-form-step__step-items__item-box">5</div>
<!-- /.c-form-step__step-items__item-box -->
</div>
<!-- /.c-form-step__step-items -->
<div class="c-form-step__wrapper-box current">
<button type="button" class="btn__link btn__link-primary px4-xs py2-xs" onClick="nextStep()" disabled>次に進む</button>
</div><!-- /.c-form-step__wrapper-box -->
<div class="c-form-step__wrapper-box">
...
<span class="mt1-xs btn__link btn__link-previous" onClick="prevStep()">戻る</span>
</div>
<button type="button" class="btn__link btn__link-primary px4-xs py2-xs" class="c-form-step__wraper-box__btn-next" onClick="nextStep()" disabled>次に進む</button>
</div><!-- /.c-form-step__wrapper-box -->
<div class="c-form-step__wrapper-box">
...
<span class="mt1-xs btn__link btn__link-previous" onClick="prevStep()">戻る</span>
<button type="button" class="btn__link btn__link-primary px4-xs py2-xs" class="c-form-step__wraper-box__btn-next" onClick="nextStep()" disabled>次に進む</button>
</div><!-- /.c-form-step__wrapper-box -->
<div class="c-form-step__wrapper-box">
...
<span class="mt1-xs btn__link btn__link-previous" onClick="prevStep()">戻る</span>
<button type="button" class="btn__link btn__link-primary px4-xs py2-xs" class="c-form-step__wraper-box__btn-next" onClick="nextStep()" disabled>次に進む</button>
</div><!-- /.c-form-step__wrapper-box -->
<div class="c-form-step__wrapper-box">
...
[submit class:btn__link class:btn__link-primary "申込む"]
</div><!-- /.c-form-step__wrapper-box -->
</div><!-- /.form-horizontal c-form-step -->
jQuery
function nextStep(){
const stepWrappers = $('.c-form-step__wrapper-box'); //stepのフォーム要素
const stepItem = $('.c-form-step__step-items__item-box'); //stepの数字要素
// current classがどこにあるか調べる
stepWrappers.each(function(i, stepWrapper){
var stepWrapper_class = $(stepWrapper).attr('class');
// currentを見つけたら、その要素のcurrentを削除し、次の要素にcurrentをつける
if (stepWrapper_class.indexOf('current') !== -1) {
$(stepWrappers[i]).removeClass('current');
$(stepWrappers[i]).css('display','');
$(stepItem[i]).removeClass('current');
$(stepWrappers[i+1]).fadeIn('800');
$(stepWrappers[i+1]).addClass('current');
$(stepItem[i+1]).addClass('current');
return false;
}
});
}
// 前の要素に戻る
function prevStep(){
const stepWrappers = $('.c-form-step__wrapper-box'); //stepのフォーム要素
const stepItem = $('.c-form-step__step-items__item-box'); //stepの数字要素
// current classがどこにあるか調べる
stepWrappers.each(function(i, stepWrapper){
var stepWrapper_class = $(stepWrapper).attr('class');
// currentを見つけたら、その要素のcurrentを削除し、次の要素にcurrentをつける
if (stepWrapper_class.indexOf('current') !== -1) {
$(stepWrappers[i]).removeClass('current');
$(stepWrappers[i]).css('display','');
$(stepItem[i]).removeClass('current');
$(stepWrappers[i-1]).fadeIn('800');
$(stepWrappers[i-1]).addClass('current');
$(stepItem[i-1]).addClass('current');
return false;
}
});
}
// フォームの入力要素が変更されたときに次へボタンを押せるようにする
function checkStepFormValue (){
const stepCurrentInputs = $('.c-form-step__wrapper-box.current input, .c-form-step__wrapper-box.current select');
let stepCurrentInputsValueCount = 0;
stepCurrentInputs.each(function(i, input){
if (input.type === 'radio' || input.type === 'checkbox') {
if (input.checked === true) {
$('.c-form-step__wrapper-box.current button,.c-form-step__wrapper-box.current input[type="button"]').prop('disabled',false);
return false;
}
} else {
if (input.value !== 0 && input.value !== '') {
stepCurrentInputsValueCount++;
if (stepCurrentInputsValueCount === stepCurrentInputs.length) {
$('.c-form-step__wrapper-box.current button,.c-form-step__wrapper-box.current input[type="button"]').prop('disabled',false);
return false;
}
}
}
});
}
// 次に進むボタンをdisabledにする
function stepFormButtonDisabled (){
const stepButtons = $('.c-form-step__wraper-box__btn-next');
stepButtons.each(function(i, button) {
$(button).prop('disabled',true);
});
};
stepFormButtonDisabled();
$('.c-form-step__wrapper-box input, .c-form-step__wrapper-box select').on('click change',function(){
checkStepFormValue();
});
CSS
.c-form-step__step-items {
display: flex;
justify-content: space-around;
padding: 10px 0;
}
.c-form-step__step-items::after {
content: none !important;
}
.c-form-step__step-items__item-box {
position: relative;
width: 40px;
height: 40px;
text-align: center;
padding: 5px;
border: 1px solid #212529;
border-radius: 100%;
}
.c-form-step__step-items__item-box.current {
transition: 0.8s;
background-color: #e9c551;
}
.c-form-step__step-items__item-box::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
right: -35%;
width: 8px;
height: 8px;
margin: auto;
border-top: 1px solid;
border-right: 1px solid;
transform: rotate(45deg);
}
.c-form-step__step-items__item-box:last-child::before {
content: none;
}
.c-form-step__wrapper-box {
display: none;
}
.c-form-step__wrapper-box.current {
display: block;
}
.c-form-step .btn__link-previous {
border: 1px solid #212529;
border-radius: 30px;
box-shadow: #4e5862 0px 1px 0px;
font-size: 1.4rem;
padding: 2px 12px 2px 20px;
}
.c-form-step .btn__link-previous::before {
left: 10px;
right: auto;
border-top: 0;
border-right: 0;
border-left: 1px solid;
border-bottom: 1px solid;
}
.c-form-step. btn__link-primary {
padding: 15px 40px;
background: #a83f3f;
border-radius: 10em;
border: none;
border-bottom: solid 3px rgba(0,0,0,.25);
font-size: 1.4rem;
font-weight: 700;
color: #212529;
background-color: #dbb934;
overflow: hidden;
line-height: normal;
position: relative;
display: inline-block;
cursor: pointer;
transition: .15s;
}
SCSS
.c-form-step {
&__step-items {
display: flex;
justify-content: space-around;
padding: 10px 0;
&::after {
content: none!important;
}
&__item-box {
position: relative;
width: 40px;
height: 40px;
text-align: center;
padding: 5px;
border: 1px solid $shblack;
border-radius: 100%;
&.current {
transition: 0.8s;
background-color: $shyellow;
}
&::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
right: -35%;
width: 8px;
height: 8px;
margin: auto;
border-top: 1px solid;
border-right: 1px solid;
transform: rotate(45deg);
}
&:last-child::before {
content: none;
}
} //__item-box
} //__step-items
&__wrapper-box {
display: none;
&.current {
display: block;
}
} //__wrapper-box
.btn__link-previous {
border: 1px solid $shblack;
border-radius: 30px;
box-shadow: lighten($shblack,20%) 0px 1px 0px;
font-size: 1.4rem;
padding: 2px 12px 2px 20px;
&::before {
left: 10px;
right: auto;
border-top: 0;
border-right: 0;
border-left: 1px solid;
border-bottom: 1px solid;
}
} //.btn__link-previous
} // c-form-step
.c-form-step. btn__link-primary {
padding: 15px 40px;
background: #a83f3f;
border-radius: 10em;
border: none;
border-bottom: solid 3px rgba(0,0,0,.25);
font-size: 1.4rem;
font-weight: 700;
color: #212529;
background-color: #dbb934;
overflow: hidden;
line-height: normal;
position: relative;
display: inline-block;
cursor: pointer;
transition: .15s;
}