no-image

jQueryとContactForm7で作るステップ式フォーム(Bootstrap・WordPress)

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;
}
pocketlinehatebuimagegalleryaudiovideocategorytagchatquotegoogleplusfacebookinstagramtwitterrsssearchenvelopeheartstaruserclosesearch-plushomeclockupdateeditshare-squarechevron-leftchevron-rightleafexclamation-trianglecalendarcommentthumb-tacklinknaviconasideangle-double-upangle-double-downangle-upangle-downstar-halfstatus