如何使用 Bootstrap 5 创建多步骤表单

表单的基本目的是收集有特定目标的用户的信息。它是每个入站营销和数据收集的重要组成部分,最终可用于将常规网站访问者转化为潜在客户。

过去,单一表单是每个网站和登录页面的常态。但随着需要填写的信息字段越来越多,用户或网站访问者在看到长表单时很容易不知所措,有时会导致他们放弃表单页面。如今,多步骤表单在网站和登录页面上越来越流行,它通过分步逐条收集信息,部分消除了这个问题,而不会让用户感到害怕。

多步骤表单只是将信息字段分解为多个部分或一系列步骤的长表单,以避免填写表单时产生不必要的恐惧。用户只能看到该特定步骤需要填写的部分字段,然后在单击下一步按钮时,将显示更多要填写的数据字段。此外,用户还可以通过单击上一个按钮返回到他们已经填写的上一组字段。通过允许用户以较小的块填写字段,可以创造积极的用户体验并提高转化率。

在今天的教程中,我将向您展示如何使用Bootstrap 5和 JavaScript 创建多步骤表单应用程序。确切地说,我们将开发一款名为COVID-19 自我检查的简单应用程序,这是一种临床多步骤评估表,可帮助个人决定何时寻求检测或医疗护理,如果他们怀疑自己或他们认识的人感染了 COVID-19 或与 COVID-19 患者有过密切接触。

不用多说,我们开始吧。

在 Bootstrap 中创建多步骤表单

文件结构

在开始之前,让我们创建必要的文件和文件夹。我们需要按照以下结构创建以下文件和文件夹:

root/

|—css/
|——style.css
|—images/
|—js/
|——script.js
|—index.html

下载 Bootstrap 的源文件

接下来,我们需要下载 Bootstrap CSS 源文件并将其添加到我们的 CSS 文件夹中。为此,请转到 Bootstrap 5 下载页面并下载源文件。在下载的源文件中,我们需要将 bootstrap.min.css 文件复制我们的 CSS 文件夹中。本教程中不需要 bootstrap bundle JavaScript 文件,因为我们将编写自己的 JavaScript 代码来使我们要构建的 Bootstrap 多表单应用程序可以运行。

图片

我已经设置好了本教程所需的所有图片。你可以从这里下载它们,并将这些图片放在图片主题文件夹中。

如何使用 Bootstrap 5 创建多步骤表单-得设创意

基本标记

下载完所有必要的文件后,现在是时候设置基本的入门 html 代码以及我们的 CSS 和 JavaScript 文件的链接以及我们将要使用的 Google 字体的链接。在 index.html 文件中我们需要添加以下代码:

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <meta name="description" content="">
      <meta name="author" content="">
      <title>Bootstrap 5: COVID-19 Self Checker Multi-step Form</title>
      <!-- CSS -->
      <link href="css/bootstrap.min.css" rel="stylesheet">
      <link href="css/style.css" rel="stylesheet">
      <!-- FONT -->
      <link href="https://fonts.gstatic.com" rel="preconnect">
      <link href="https://fonts.googleapis.com/css2?family=Josefin+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,200;1,300;1,400;1,500;1,600&display=swap" rel="stylesheet">
   </head>
   <body>
      <script src="js/script.js"></script>
   </body>
</html>

容器和两列

现在,我不想用太多信息来打扰你,所以让我们一步一步来。让我们设置本教程所需的基本容器和两列布局。左列将包含我们的标题和描述,右列将包含我们的表单。

基本上,我们将有一个容器类,将其设置为显示为弹性框,并使用弹性框实用程序和间距实用程序将所有内容定位在屏幕中间。

<!-- CONTAINER -->
<div class="container d-flex align-items-center min-vh-100">
   <div class="row g-0 justify-content-center">
      <!-- TITLE -->
      <div class="col-lg-4 offset-lg-1 mx-0 px-0">
      </div>
      <!-- FORMS -->
      <div class="col-lg-7 mx-0 px-0">
      </div>
   </div>
</div>

标题和说明列

接下来,在左栏内,我们将设置一个带有  #title-container的<div>,并放置包含标题和描述的图像、标题和段落标签。

<!-- TITLE -->
<div class="col-lg-4 offset-lg-1 mx-0 px-0">
   <div id="title-container">
      <img class="covid-image" src="./img/covid-check.png">
      <h2>COVID-19</h2>
      <h3>Self Checker Form</h3>
      <p>A clinical assessment multi-step form that will assist individuals on deciding when to seek testing or medical care if they suspect they or someone they know has contracted COVID-19 or has come into close contact with someone who has COVID-19</p>
   </div>
</div>

多步骤表单列

在右栏中,我们将在最顶部添加一个引导进度条组件,然后添加一个 id 为#qbox-container的<div>,然后在该容器内添加一个表单组件。

<!-- FORMS -->
<div class="col-lg-7 mx-0 px-0">
   <div class="progress">
      <div aria-valuemax="100" aria-valuemin="0" aria-valuenow="50" class="progress-bar progress-bar-striped progress-bar-animated bg-danger" role="progressbar" style="width: 0%"></div>
   </div>
   <div id="qbox-container">
      <form class="needs-validation" id="form-wrapper" method="post" name="form-wrapper" novalidate>
         <!-- STEPS HERE -->
      </form>
   </div>
</div>

现在,让我们开始处理每个步骤的标记。首先,我们需要创建一个容器<div>,其 id 为#steps-container,然后对于每个步骤,我们将把它们放在一个带有类.step的<div>中。接下来是问题,以<h4>标签的形式,其中包含引导表单控制字段组件和布局选项,以及用于创建各种表单字段的自定义类。

本教程至少包含六个步骤,最后有一个<div> , id为 #success 稍后单击提交按钮时会用到。我们将按钮包裹在内联块位置,位于右栏最底部的<div>内,id 为#q-box__buttons 。

<div class="col-lg-7 mx-0 px-0">
   <div class="progress">
      <div aria-valuemax="100" aria-valuemin="0" aria-valuenow="50" class="progress-bar progress-bar-striped progress-bar-animated bg-danger" role="progressbar" style="width: 0%"></div>
   </div>
   <div id="qbox-container">
      <form class="needs-validation" id="form-wrapper" method="post" name="form-wrapper" novalidate="">
         <div id="steps-container">
            <div class="step">
               <h4>Have you recently been in close contact with someone who has COVID-19?</h4>
               <div class="form-check ps-0 q-box">
                  <div class="q-box__question">
                     <input class="form-check-input question__input" id="q_1_yes" name="q_1" type="radio" value="Yes"> 
                     <label class="form-check-label question__label" for="q_1_yes">Yes</label>
                  </div>
                  <div class="q-box__question">
                     <input checked class="form-check-input question__input" id="q_1_no" name="q_1" type="radio" value="No"> 
                     <label class="form-check-label question__label" for="q_1_no">No</label>
                  </div>
               </div>
            </div>
            <div class="step">
               <h4>Are you experiencing a high fever, dry cough, tiredness and loss of taste or smell?</h4>
               <div class="form-check ps-0 q-box">
                  <div class="q-box__question">
                     <input class="form-check-input question__input" id="q_2_yes" name="q_2" type="radio" value="Yes"> 
                     <label class="form-check-label question__label" for="q_2_yes">Yes</label>
                  </div>
                  <div class="q-box__question">
                     <input checked class="form-check-input question__input" id="q_2_no" name="q_2" type="radio" value="No"> 
                     <label class="form-check-label question__label" for="q_2_no">No</label>
                  </div>
               </div>
            </div>
            <div class="step">
               <h4>Are you having diarrhoea, stomach pain, conjunctivitis, vomiting and headache?</h4>
               <div class="form-check ps-0 q-box">
                  <div class="q-box__question">
                     <input class="form-check-input question__input" id="q_3_yes" name="q_3" type="radio" value="Yes"> 
                     <label class="form-check-label question__label" for="q_3_yes">Yes</label>
                  </div>
                  <div class="q-box__question">
                     <input checked class="form-check-input question__input" id="q_3_no" name="q_3" type="radio" value="No"> 
                     <label class="form-check-label question__label" for="q_3_no">No</label>
                  </div>
               </div>
            </div>
            <div class="step">
               <h4>Have you traveled to any of these countries with the highest number of COVID-19 cases in the world for the past 2 weeks?</h4>
               <div class="row">
                  <div class="col-lg-6">
                     <div class="form-check ps-0 q-box">
                        <div class="q-box__question">
                           <input class="form-check-input question__input q-checkbox" id="q_4_uk" name="q_4" type="checkbox" value="uk"> 
                           <label class="form-check-label question__label" for="q_4_uk">UK</label>
                        </div>
                     </div>
                     <div class="form-check ps-0 q-box">
                        <div class="q-box__question">
                           <input class="form-check-input question__input" id="q_4_us" name="q_4" type="checkbox" value="us"> 
                           <label class="form-check-label question__label" for="q_4_us">US</label>
                        </div>
                     </div>
                     <div class="form-check ps-0 q-box">
                        <div class="q-box__question">
                           <input class="form-check-input question__input" id="q_4_br" name="q_3" type="checkbox" value="br"> 
                           <label class="form-check-label question__label" for="q_4_br">Brazil</label>
                        </div>
                     </div>
                  </div>
                  <div class="col-lg-6">
                     <div class="form-check ps-0 q-box">
                        <div class="q-box__question">
                           <input class="form-check-input question__input" id="q_4_de" name="q_4" type="checkbox" value="de"> 
                           <label class="form-check-label question__label" for="q_4_de">Germany</label>
                        </div>
                     </div>
                     <div class="form-check ps-0 q-box">
                        <div class="q-box__question">
                           <input class="form-check-input question__input" id="q_4_in" name="q_4" type="checkbox" value="in"> 
                           <label class="form-check-label question__label" for="q_4_in">India</label>
                        </div>
                     </div>
                     <div class="form-check ps-0 q-box">
                        <div class="q-box__question">
                           <input class="form-check-input question__input" id="q_4_eu" name="q_4" type="checkbox" value="eu"> 
                           <label class="form-check-label question__label" for="q_4_eu">Europe</label>
                        </div>
                     </div>
                  </div>
                  <div class="col-lg-12">
                     <div class="form-check ps-0 q-box">
                        <div class="q-box__question">
                           <input class="form-check-input question__input" id="q_4_none" name="q_4" type="checkbox" value="none"> 
                           <label class="form-check-label question__label" for="q_4_none">I did not travelled to any of these countries</label>
                        </div>
                     </div>
                  </div>
               </div>
            </div>
            <div class="step">
               <h4>Are you experiencing any of these serious symptoms of COVID-19 below?</h4>
               <div class="row">
                  <div class="form-check ps-0 q-box">
                     <div class="q-box__question">
                        <input class="form-check-input question__input" id="q_5_breathing" name="q_5_breathing" type="checkbox" value="breathing"> 
                        <label class="form-check-label question__label" for="q_5_breathing">Difficulty breathing or shortness of breath</label>
                     </div>
                  </div>
                  <div class="form-check ps-0 q-box">
                     <div class="q-box__question">
                        <input class="form-check-input question__input" id="q_5_chest" name="q_5_chest" type="checkbox" value="chest pain"> 
                        <label class="form-check-label question__label" for="q_5_chest">Chest pain or pressure</label>
                     </div>
                  </div>
                  <div class="form-check ps-0 q-box">
                     <div class="q-box__question">
                        <input class="form-check-input question__input" id="q_5_speech" name="q_5_speech" type="checkbox" value="speech problem"> 
                        <label class="form-check-label question__label" for="q_5_speech">Loss of speech or movement</label>
                     </div>
                  </div>
                  <div class="form-check ps-0 q-box">
                     <div class="q-box__question">
                        <input class="form-check-input question__input" id="q_5_pale" name="q_5_pale" type="checkbox" value="pale"> 
                        <label class="form-check-label question__label" for="q_5_pale">Pale, gray or blue-colored skin, lips or nail beds</label>
                     </div>
                  </div>
               </div>
            </div>
            <div class="step">
               <h4>Provide us with your personal information:</h4>
               <div class="mt-1">
                  <label class="form-label">Complete Name:</label> 
                  <input class="form-control" id="full_name" name="full_name" type="text">
               </div>
               <div class="mt-2">
                  <label class="form-label">Complete Address:</label> 
                  <input class="form-control" id="address" name="address" type="text">
               </div>
               <div class="mt-2">
                  <label class="form-label">Email:</label> 
                  <input class="form-control" id="email" name="email" type="email">
               </div>
               <div class="mt-2">
                  <label class="form-label">Phone / Mobile Number:</label> 
                  <input class="form-control" id="phone" name="phone" type="text">
               </div>
               <div class="row mt-2">
                  <div class="col-lg-2 col-md-2 col-3">
                     <label class="form-label">Age:</label>
                     <div class="input-container">
                        <input class="form-control" id="age" name="age" type="text">
                     </div>
                  </div>
                  <div class="col-lg-8">
                     <div id="input-container">
                        <input class="form-check-input" name="gender" type="radio" value="male"> 
                        <label class="form-check-label radio-lb">Male</label> 
                        <input class="form-check-input" name="gender" type="radio" value="female"> 
                        <label class="form-check-label radio-lb">Female</label> 
                        <input checked class="form-check-input" name="gender" type="radio" value="undefined"> 
                        <label class="form-check-label radio-lb">Rather not say</label>
                     </div>
                  </div>
               </div>
            </div>
            <div class="step">
               <div class="mt-1">
                  <div class="closing-text">
                     <h4>That's about it! Stay healthy!</h4>
                     <p>We will assess your information and will let you know soon if you need to get tested for COVID-19.</p>
                     <p>Click on the submit button to continue.</p>
                  </div>
               </div>
            </div>
            <div id="success">
               <div class="mt-5">
                  <h4>Success! We'll get back to you ASAP!</h4>
                  <p>Meanwhile, clean your hands often, use soap and water, or an alcohol-based hand rub, maintain a safe distance from anyone who is coughing or sneezing and always wear a mask when physical distancing is not possible.</p>
                  <a class="back-link" href="">Go back from the beginning ➜</a>
               </div>
            </div>
         </div>
         <div id="q-box__buttons">
            <button id="prev-btn" type="button">Previous</button> 
            <button id="next-btn" type="button">Next</button> 
            <button id="submit-btn" type="submit">Submit</button>
         </div>
      </form>
   </div>
</div>

预加载器

接下来,让我们添加一个预加载器。我们特意将其放在标记的最底部(引导容器之外),因为我们不会在每次加载页面时都加载它,而只会在单击提交按钮时加载它。

预加载器标记非常简单。我们有一个包装器 <div>,id 为#preloader-wrapper,实际的预加载器位于以下<div>中,其 id 为#preloader。我们里面还有另外两个<div>标签,类名为.preloader-section和 .section -left用于左侧窗口,类名为.preloader-section和 .section -right用于右侧窗口。最后两个<div>标签的目的是以一种方式显示内容,即屏幕在加载时间三秒后会在中间分裂,从而产生很酷的过渡效果。

<div id="preloader-wrapper">
   <div id="preloader"></div>
   <div class="preloader-section section-left"></div>
   <div class="preloader-section section-right"></div>
</div>

添加完所有标记后,多步骤表单应用程序看起来会很乱,因为尚未添加任何样式。我们将在本教程的下一部分中将一些 CSS 样式放入 style.css 中,使其看起来更美观。

添加样式表

为了使我们的多步骤表单的设计更加生动,我们现在将在style.css文件内为每一列添加 CSS  。

通用 CSS

在继续操作之前,我们需要添加常规 CSS 样式。这些 CSS 样式将简单地格式化我们的基本标记,例如我们将在整个多步骤表单中使用的字体、背景和标准 HTML 标签(例如标题标签、段落和标签)的基本样式。

/* GENERAL */
 
body {
    background: #f7f9ff;
    font-family: 'Josefin Sans', sans-serif;
    font-size: 16px;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.4;
    color: #555;
}
 
h1,
h2,
h3,
h4,
h5,
h6 {
    color: #00011c;
}
 
p {
    margin-bottom: 24px;
    line-height: 1.9;
}
 
label {
    font-size: 16px;
    font-size: 1rem;
    font-weight: 600;
    margin-bottom: 5px;
    color: #00011c;
}

标题和说明列

接下来,让我们处理包含图片、标题和说明的左栏。我们将在#title-container id 上添加样式以及其中关联的 HTML 标签,并确保所有内容都具有正确的样式,包括字体、背景颜色和间距。

/* TITLE */
 
#title-container {
    min-height: 460px;
    height: 100%;
    color: #fff;
    background-color: #DC3545;
    text-align: center;
    padding: 105px 28px 28px 28px;
    box-sizing: border-box;
    position: relative;
    box-shadow: 10px 8px 21px 0px rgba(204, 204, 204, 0.75);
    -webkit-box-shadow: 10px 8px 21px 0px rgba(204, 204, 204, 0.75);
    -moz-box-shadow: 10px 8px 21px 0px rgba(204, 204, 204, 0.75);
}
 
#title-container h2 {
    font-size: 45px;
    font-weight: 800;
    color: #fff;
    padding: 0;
    margin-bottom: 0px;
}
 
#title-container h3 {
    font-size: 25px;
    font-weight: 600;
    color: #82000a;
    padding: 0;
}
 
#title-container p {
    font-size: 13px;
    padding: 0 25px;
    line-height: 20px;
}
 
.covid-image {
    width: 214px;
    margin-bottom: 15px;
}

多步骤表单列

现在对于多步骤列,我们需要将 CSS 样式添加到我们的#qbox-container id,后跟将保存我们的步骤表单及其内容的#step-container id。

我们将为容器提供一个漂亮的背景图案图像,并将其与适当宽度的 flexbox 对齐和 box-shadow 一起定位以创建阴影效果。

我们应该首先隐藏我们的步骤及其内部元素,因为我们稍后要使用自定义 JavaScript 代码来操纵屏幕上显示的内容。

最后,我们还将为复选框、单选按钮、输入和按钮添加一些 CSS 样式,包括它们的焦点状态,以创建良好的选择效果,而不是依赖于典型的引导自定义样式。

/* FORMS */
 
#qbox-container {
    background: url(../img/corona.png);
    background-repeat: repeat;
    position: relative;
    padding: 62px;
    min-height: 630px;
    box-shadow: 10px 8px 21px 0px rgba(204, 204, 204, 0.75);
    -webkit-box-shadow: 10px 8px 21px 0px rgba(204, 204, 204, 0.75);
    -moz-box-shadow: 10px 8px 21px 0px rgba(204, 204, 204, 0.75);
}
 
#steps-container {
    margin: auto;
    width: 500px;
    min-height: 420px;
    display: flex;
    vertical-align: middle;
    align-items: center;
}
 
.step {
    display: none;
}
 
.step h4 {
    margin: 0 0 26px 0;
    padding: 0;
    position: relative;
    font-weight: 500;
    font-size: 23px;
    font-size: 1.4375rem;
    line-height: 1.6;
}
 
button#prev-btn,
button#next-btn,
button#submit-btn {
    font-size: 17px;
    font-weight: bold;
    position: relative;
    width: 130px;
    height: 50px;
    background: #DC3545;
    margin: 0 auto;
    margin-top: 40px;
    overflow: hidden;
    z-index: 1;
    cursor: pointer;
    transition: color .3s;
    text-align: center;
    color: #fff;
    border: 0;
    -webkit-border-bottom-right-radius: 5px;
    -webkit-border-bottom-left-radius: 5px;
    -moz-border-radius-bottomright: 5px;
    -moz-border-radius-bottomleft: 5px;
    border-bottom-right-radius: 5px;
    border-bottom-left-radius: 5px;
}
 
button#prev-btn:after,
button#next-btn:after,
button#submit-btn:after {
    position: absolute;
    top: 90%;
    left: 0;
    width: 100%;
    height: 100%;
    background: #cc0616;
    content: "";
    z-index: -2;
    transition: transform .3s;
}
 
button#prev-btn:hover::after,
button#next-btn:hover::after,
button#submit-btn:hover::after {
    transform: translateY(-80%);
    transition: transform .3s;
}
 
.progress {
    border-radius: 0px !important;
}
 
.q__question {
    position: relative;
}
 
.q__question:not(:last-child) {
    margin-bottom: 10px;
}
 
.question__input {
    position: absolute;
    left: -9999px;
}
 
.question__label {
    position: relative;
    display: block;
    line-height: 40px;
    border: 1px solid #ced4da;
    border-radius: 5px;
    background-color: #fff;
    padding: 5px 20px 5px 50px;
    cursor: pointer;
    transition: all 0.15s ease-in-out;
}
 
.question__label:hover {
    border-color: #DC3545;
}
 
.question__label:before,
.question__label:after {
    position: absolute;
    content: "";
}
 
.question__label:before {
    top: 12px;
    left: 10px;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background-color: #fff;
    box-shadow: inset 0 0 0 1px #ced4da;
    -webkit-transition: all 0.15s ease-in-out;
    -moz-transition: all 0.15s ease-in-out;
    -o-transition: all 0.15s ease-in-out;
    transition: all 0.15s ease-in-out;
}
 
.question__input:checked+.question__label:before {
    background-color: #DC3545;
    box-shadow: 0 0 0 0;
}
 
.question__input:checked+.question__label:after {
    top: 22px;
    left: 18px;
    width: 10px;
    height: 5px;
    border-left: 2px solid #fff;
    border-bottom: 2px solid #fff;
    transform: rotate(-45deg);
}
 
.form-check-input:checked,
.form-check-input:focus {
    background-color: #DC3545 !important;
    outline: none !important;
    border: none !important;
}
 
input:focus {
    outline: none;
}
 
#input-container {
    display: inline-block;
    box-shadow: none !important;
    margin-top: 36px !important;
}
 
label.form-check-label.radio-lb {
    margin-right: 15px;
}
 
#q-box__buttons {
    text-align: center;
}
 
input[type="text"],
input[type="email"] {
    padding: 8px 14px;
}
 
input[type="text"]:focus,
input[type="email"]:focus {
    border: 1px solid #DC3545;
    border-radius: 5px;
    outline: 0px !important;
    -webkit-appearance: none;
    box-shadow: none !important;
    -webkit-transition: all 0.15s ease-in-out;
    -moz-transition: all 0.15s ease-in-out;
    -o-transition: all 0.15s ease-in-out;
    transition: all 0.15s ease-in-out;
}
 
.form-check-input:checked[type=radio],
.form-check-input:checked[type=radio]:hover,
.form-check-input:checked[type=radio]:focus,
.form-check-input:checked[type=radio]:active {
    border: none !important;
    -webkit-outline: 0px !important;
    box-shadow: none !important;
}
 
.form-check-input:focus,
input[type="radio"]:hover {
    box-shadow: none;
    cursor: pointer !important;
}
 
#success {
    display: none;
}
 
#success h4 {
    color: #DC3545;
}
 
.back-link {
    font-weight: 700;
    color: #DC3545;
    text-decoration: none;
    font-size: 18px;
}
 
.back-link:hover {
    color: #82000a;
}

预加载器

我们还需要为预加载器添加一些样式。只有在多步骤表单末尾单击提交按钮后,才会加载。

我们首先为#preloader-wrapper id定义宽度和高度,然后通过#preloader  id 定义预加载器本身。

我们还将使用 CSS 动画提供出色的旋转效果。我们将使用 rotate 属性为动画指定正确的关键帧。关键帧在特定持续时间内保存预加载器的样式。

最后,我们将为左右窗口添加一个漂亮的过渡效果,该效果将在屏幕中间分割,左侧窗口使用#preloader-wrapper id、.preloader -section.section-left类,右侧窗口使用#preloader-wrapper id、.preloader -section.section-right类。一旦动画最终使用我们的自定义 JavaScript 代码完成, .loaded类将添加到 body 类中。

/* PRELOADER */
 
#preloader-wrapper {
    width: 100%;
    height: 100%;
    z-index: 1000;
    display: none;
    position: fixed;
    top: 0;
    left: 0;
}
 
#preloader {
    background-image: url('../img/preloader.png');
    width: 120px;
    height: 119px;
    border-top-color: #fff;
    border-radius: 100%;
    display: block;
    position: relative;
    top: 50%;
    left: 50%;
    margin: -75px 0 0 -75px;
    -webkit-animation: spin 2s linear infinite;
    animation: spin 2s linear infinite;
    z-index: 1001;
}
 
@-webkit-keyframes spin {
    0% {
        -webkit-transform: rotate(0deg);
        -ms-transform: rotate(0deg);
        transform: rotate(0deg);
    }
    100% {
        -webkit-transform: rotate(360deg);
        -ms-transform: rotate(360deg);
        transform: rotate(360deg);
    }
}
 
@keyframes spin {
    0% {
        -webkit-transform: rotate(0deg);
        -ms-transform: rotate(0deg);
        transform: rotate(0deg);
    }
    100% {
        -webkit-transform: rotate(360deg);
        -ms-transform: rotate(360deg);
        transform: rotate(360deg);
    }
}
 
#preloader-wrapper .preloader-section {
    width: 51%;
    height: 100%;
    position: fixed;
    top: 0;
    background: #F7F9FF;
    z-index: 1000;
}
 
#preloader-wrapper .preloader-section.section-left {
    left: 0
}
 
#preloader-wrapper .preloader-section.section-right {
    right: 0;
}
 
.loaded #preloader-wrapper .preloader-section.section-left {
    transform: translateX(-100%);
    transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
}
 
.loaded #preloader-wrapper .preloader-section.section-right {
    transform: translateX(100%);
    transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
}
 
.loaded #preloader {
    opacity: 0;
    transition: all 0.3s ease-out;
}
 
.loaded #preloader-wrapper {
    visibility: hidden;
    transform: translateY(-100%);
    transition: all 0.3s 1s ease-out;
}

响应式 CSS

最后,我们将添加一些媒体查询,以允许我们的内容渲染在调整大小或在特定设备中查看时适应不同的屏幕分辨率或视口宽度。

我们将特别管理#title-container#qbox-container#steps-container  ids上不同屏幕分辨率或视口上的内容渲染适配。

/* MEDIA QUERIES */
 
@media (min-width: 990px) and (max-width: 1199px) {
    #title-container {
        padding: 80px 28px 28px 28px;
    }
    #steps-container {
        width: 85%;
    }
}
 
@media (max-width: 991px) {
    #title-container {
        padding: 30px;
        min-height: inherit;
    }
}
 
@media (max-width: 767px) {
    #qbox-container {
        padding: 30px;
    }
    #steps-container {
        width: 100%;
        min-height: 400px;
    }
    #title-container {
        padding-top: 50px;
    }
}
 
@media (max-width: 560px) {
    #qbox-container {
        padding: 40px;
    }
    #title-container {
        padding-top: 45px;
    }
}

此时,多步骤表单应用程序应该看起来不错,但您会看到带有表单字段的表单屏幕目前默认为空白,因为我们的 CSS 样式将步骤设置为隐藏。但是,您可以看到三个按钮都显示在底部,但情况并非如此。我们需要使用 JavaScript 来管理每个步骤的显示。

添加 JavaScript 代码

现在是时候通过在我们的script.js文件中添加一些 JavaScript 代码来为我们的多步骤表单增添一些魔力了 。

首先,我们将通过实时节点列表使用不同的文档方法(例如document.getElementByIddocument.getElementsByClassNamedocument.getElementsByTagNamedocument.querySelector)选择所需的 HTML 特定标签。  所有这些接口方法都继承自 Node 和 EventTarget 接口。

确切地说,我们将捕捉以下元素:

  • 带有.step<div>
  • id为#prev-btn的<button>
  • id#next-btn的<button> 。
  • id为#submi-btn的<button>
  • 第一个初始形态
  • id#preloader-wrapper的<div> 。
  • 身体
  • id 为#preloader-success<div> 。
let step = document.getElementsByClassName('step');
let prevBtn = document.getElementById('prev-btn');
let nextBtn = document.getElementById('next-btn');
let submitBtn = document.getElementById('submit-btn');
let form = document.getElementsByTagName('form')[0];
let preloader = document.getElementById('preloader-wrapper');
let bodyElement = document.querySelector('body');
let succcessDiv = document.getElementById('success');

接下来,让我们默认阻止表单提交,然后为current_step(当前显示的具有.step类的<div>)以及stepCount或所有步骤的数量设置变量。

我们将添加 bootstrap 显示属性类.d-block来显示当前需要填写的步骤。在第一步中,只需通过.d-inline-block显示属性类显示下一步按钮。

form.onsubmit = () => {
    return false
}
let current_step = 0;
let stepCount = 6
step[current_step].classList.add('d-block');
if (current_step == 0) {
    prevBtn.classList.add('d-none');
    submitBtn.classList.add('d-none');
    nextBtn.classList.add('d-inline-block');
}

我们讨论三个主要按钮事件之前,让我先向您介绍进度 函数,它将启动我们在右栏标记内设置的引导进度条标记。

此函数将简单地从文档中选择引导进度条,并使用在上一个和下一个按钮内传递的值参数,提供每个步骤前进时在进度条中显示的特定宽度。

const progress = (value) => {
    document.getElementsByClassName('progress-bar')[0].style.width = `${value}%`;
}

接下来,让我们为每个按钮添加一个addEventListener()方法: previousnextsubmit。这将设置一个函数,每当触发‘click’事件时都会调用该函数。

下一个按钮和上一个按钮的思路几乎相似,但方向相反。在下一个按钮上,我们将简单地增加步骤,然后在单击按钮时不断删除并逐步将.d-none.d-block类添加到包含<div>的步骤以及三个定义的按钮中。同样,对于上一个按钮,我们将减少步骤数,但概念几乎相同。

我们还将设置一些 if 语句,检查步骤是否已达到最大步数或仅处于最后一步,以及在特定步骤上显示哪个按钮。

此外,我们在下一个和上一个按钮addEventListener()方法的底部调用进度函数,并传入 100 除以stepCount再乘以当前步数的值。简而言之,我们只是简单地将 100% 分成几部分,这样我们才能仅显示特定步数的正确进度量。

最后,对于提交按钮addEventListener()方法,我们将通过将.d-block的显示属性类添加到 body 元素来显示预加载器,然后设置一个计时器,该计时器将在计时器结束时添加类 . loaded,持续时间为三秒。在 Promise 异步操作的最后一部分,我们将隐藏所有按钮以及最后一步,并使用.d-block显示属性类显示带有#success id 的<div>。当然,我们需要删除并添加.d-inline-block.d-none显示属性类,以便最后一步<div>、上一个按钮和提交按钮。

nextBtn.addEventListener('click', () => {
    current_step++;
    let previous_step = current_step - 1;
    if ((current_step > 0) && (current_step <= stepCount)) {
        prevBtn.classList.remove('d-none');
        prevBtn.classList.add('d-inline-block');
        step[current_step].classList.remove('d-none');
        step[current_step].classList.add('d-block');
        step[previous_step].classList.remove('d-block');
        step[previous_step].classList.add('d-none');
        if (current_step == stepCount) {
            submitBtn.classList.remove('d-none');
            submitBtn.classList.add('d-inline-block');
            nextBtn.classList.remove('d-inline-block');
            nextBtn.classList.add('d-none');
        }
    } else {
        if (current_step > stepCount) {
            form.onsubmit = () => {
                return true
            }
        }
    }
    progress((100 / stepCount) * current_step);
});
 
 
prevBtn.addEventListener('click', () => {
    if (current_step > 0) {
        current_step--;
        let previous_step = current_step + 1;
        prevBtn.classList.add('d-none');
        prevBtn.classList.add('d-inline-block');
        step[current_step].classList.remove('d-none');
        step[current_step].classList.add('d-block')
        step[previous_step].classList.remove('d-block');
        step[previous_step].classList.add('d-none');
        if (current_step < stepCount) {
            submitBtn.classList.remove('d-inline-block');
            submitBtn.classList.add('d-none');
            nextBtn.classList.remove('d-none');
            nextBtn.classList.add('d-inline-block');
            prevBtn.classList.remove('d-none');
            prevBtn.classList.add('d-inline-block');
        }
    }
 
    if (current_step == 0) {
        prevBtn.classList.remove('d-inline-block');
        prevBtn.classList.add('d-none');
    }
    progress((100 / stepCount) * current_step);
});
 
 
submitBtn.addEventListener('click', () => {
    preloader.classList.add('d-block');
 
    const timer = ms => new Promise(res => setTimeout(res, ms));
 
    timer(3000)
        .then(() => {
            bodyElement.classList.add('loaded');
        }).then(() => {
            step[stepCount].classList.remove('d-block');
            step[stepCount].classList.add('d-none');
            prevBtn.classList.remove('d-inline-block');
            prevBtn.classList.add('d-none');
            submitBtn.classList.remove('d-inline-block');
            submitBtn.classList.add('d-none');
            succcessDiv.classList.remove('d-none');
            succcessDiv.classList.add('d-block');
        })
 
});

现在我们的项目已经完成。您现在可以浏览我们在 Bootstrap 中创建的多步骤表单。

注意:这只是在 JavaScript 中实现此目的的一种方法。有多种方法可以创建相同的功能。从技术上讲,实际上有大量程序可以在每种情况下实现特定的算法或功能。请随意探索和修改程序。

如何使用 Bootstrap 5 创建多步骤表单-得设创意

结论

如果您想为您的登录页面或转换率较高的网站创建整洁的表格,Bootstrap 多步骤表格是您的最佳选择。

使用 Bootstrap,可以轻松创建表单并使用其他组件来实现此目的。通过使用 JavaScript 以及可用的 bootstrap 组件,您可以快速分解表单问题并将其分组为特定主题,以帮助用户集中注意力并尽可能完成您的表单。

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情

    暂无评论内容