【问题标题】:Error messages for form validation not appearing表单验证的错误消息未出现
【发布时间】:2021-03-07 08:01:56
【问题描述】:

我目前正在一个网站上构建一个窗口,用户可以在其中预订乘船旅行,这需要多个步骤,并且 3/5 步骤包括表单(我只在 html 中包含第一个表单,否则它会变得太长 -见下文)。

我目前正在处理第一个表单的验证,您可以在下面看到 (".availability step1")。我在此验证上花费了相当长的时间,但是,我似乎无法弄清楚如何只制作“空”,因此无效的字段会显示错误消息 (.error) 。现在它正在识别那些无效的,并且我将 CSS 连接到无效(我得到 输入字段周围的红色边框),但是,我没有通过 html标记,这是一个位于输入字段下方的段落。

function init() {
    setUpBooking();
}

function setUpBooking(){
    formValidation();
}

function formValidation() {
    /* ------------ form & elements ----------- */
    const form1 = document.querySelector(".availability");
    window.form1 = form1;
    const elements = form1.elements;
    window.elements = elements;

    /* --------- delete default validation ------- */
    form1.setAttribute("novalidate", true);

    /* ------------ custom validation ------------ */
    document.querySelector(".next").addEventListener("click", (e) => {
    e.preventDefault();

    // 1. select all inputs
    const formElements = form1.querySelectorAll("input, select");

    /* ------------ date ------------ */
    if (form1.checkValidity()) {
        console.log("form is valid");
        
        // loop through form elements and check if are valid or not
        formElements.forEach((el) => {
            if (el.checkValidity()) { 
                el.classList.add("valid");
            }

            // enable "next" btn when form is valid
            var counter = 1, step = "step";
            step = ".step" + counter;
            if (counter <= 5) {
                document.querySelector(step).classList.add("show");
            }
            counter++;
            if (counter > 5) {
                counter = 5;
            }
            step = ".step" + counter; // step is the class and we are appending counter with step so that it looks like the same class in the given class(like counter 1 means step1)

            document.querySelector(step).classList.remove("show");

            // enable "previous" btn when form is valid
            document.querySelector(".previous").addEventListener('click', function () {

                if (counter > 1) { // we don't want to remove the first step, it will always be shown
                    step = ".step" + counter;
            
                    document.querySelector(step).classList.add("show");
                }
                counter--;
                
                if (counter < 1) {
                    counter = 1;
                }
                step = ".step" + counter;
            
                document.querySelector(step).classList.remove("show");
            });
        });
    } else {
        formElements.forEach((el) => {
            
            if (!el.checkValidity()) {
                console.log("form is invalid");

                    el.classList.add("invalid");

                    document.querySelector(".error").style.display = "block";
                } else {
                    el.classList.remove("invalid");
                }
            })
        }
    })
}
.valid {
  border: 1px solid green;
}

.invalid {
  border: 1px solid red;
  border-top-left-radius: 3px;
  border-top-right-radius: 3px;
}

.error {
  text-transform: initial;
  margin-bottom: 20px;
  margin-top: -1px;
  border: 1px solid red;
  padding: 4px;
  z-index: 10;
  border-bottom-left-radius: 3px;
  border-bottom-right-radius: 3px;
  display: none;
}
<!-- AVAILABILITY -->
<form class="availability step1">
  <label for="date">Choose a date
    <input type="date" required>
      <p class="error date-err">Please pick a date for your tour</p>
  <label for="number">Choose passengers
    <input type="number" required>
      <p class="error passengers-err">Please pick a number of passengers</p>
  </label>

  <!-- PERSONAL DATA -->
  <form class="personalData step2">
  </form>

  <!-- ORDER OVERVIEW -->
  <div class="orderOverview step3">
  </div>

  <!-- PAYMENT -->
  <form class="payment step4">
  </form>

  <!-- buttons -->
  <button class="previous hide">Previous</button>
  <button class="next">Next</button>

【问题讨论】:

  • 我没有看到任何调用 formValidation() 的东西。也许有些代码被遗漏了?
  • 您希望如何进行验证?例如:提交表单后,您的验证流程是什么?
  • @HereticMonkey 我刚刚更新了 JS sn-p
  • @ShahnawazHossan 提交表单后,它应该通过“.next”按钮进入下一个表单,并在第二个表单中执行相同操作,依此类推。我相信我混淆了按钮的实际点击(只有在表单经过验证时才会发生)和带有错误消息的表单验证,这应该是两个独立的功能,对吗?
  • 好吧....这就引出了setUpBooking()在哪里调用的问题?我们正在寻找的是minimal reproducible example,这样当我们单击“运行代码 sn-p”时,您正在显示的代码就会运行,我们可以看到它的运行情况。

标签: javascript html forms validation input


【解决方案1】:

首先,对不起。我对您的表单做了一些修改。

思路如下:

  1. 在每个表单中附加了一个span 字段。
  2. 在转到下一个表单之前,只需将表单编号传递给 validateForm 函数,检查当前表单中的每个字段是否都已填写,并检查其所有输入字段是否已填写。
  3. 如果是,则返回 true,否则返回 false。

看看下面的sn-p:

function validateForm(step) {

    // console.log(document.forms[step - 1].elements);

    var i, l = document.forms[step - 1].elements.length;

    for (i = 0; i < l; i++) {
        // console.log(document.forms[step - 1].elements[i].value);
        if (!document.forms[step - 1].elements[i].value) {
            // console.log("All fields should be filled");
            document.getElementById("error" + step).textContent = "Fill all the fields please";
            document.getElementById("error" + step).style.color = "red";
            return false;
        }
    }
    document.getElementById("error" + step).textContent = "Form is completed";
    document.getElementById("error" + step).style.color = "green";
    return true;
}

var counter = 1,
    step = "step";

document.querySelector(".next").addEventListener('click', function() {

    step = ".step" + counter;

    if (validateForm(counter)) {

        if (counter <= 5) {
            document.querySelector(step).classList.add("show");
        }

        counter++;

        if (counter > 5) {
            counter = 5;
        }

        step = ".step" + counter; // step is the class and we are appending counter with step so that it looks like the same class in the given class(like counter 1 means step1)
        //console.log(step);

        document.querySelector(step).classList.remove("show");

    }
});

document.querySelector(".previous").addEventListener('click', function() {

    if (counter > 1) { // we don't want to remove the first step, it will always be shown
        step = ".step" + counter;
        //console.log(step);

        document.querySelector(step).classList.add("show");
    }

    counter--;

    if (counter < 1) {
        counter = 1;
    }


    step = ".step" + counter;

    document.querySelector(step).classList.remove("show");

});
.show {
    display: none;
}
<!-- AVAILABILITY -->
<form name="availability" class="availability step1">
    <h1>Step1</h1>
    <label for="date">Choose a date</label>
    <input type="date" name="DATE" required>
    <label for="firstname">Enter a firstname</label>
    <input type="text" name="FIRSTNAME" required>
    <br/>
    <span id="error1"> </span>
</form>

<!-- PERSONAL DATA -->
<form class="personalData step2 show">
    <h1>Step2</h1>
    <label for="date">Choose a date</label>
    <input type="date" name="DATE" required>
    <label for="firstname">Enter a firstname</label>
    <input type="text" name="FIRSTNAME" required>
    <br/>
    <span id="error2"></span>
</form>

<!-- ORDER OVERVIEW -->
<div class="orderOverview step3 show">
    <h1>Step3</h1>
    <label for="date">Choose a date</label>
    <input type="date" name="DATE" required>
    <label for="firstname">Enter a firstname</label>
    <input type="text" name="FIRSTNAME" required>
    <br/>
    <span id="error3"></span>
</div>

<!-- PAYMENT -->
<form class="payment step4 show">
    <h1>Step4</h1>
    <label for="date">Choose a date</label>
    <input type="date" name="DATE" required>
    <label for="firstname">Enter a firstname</label>
    <input type="text" name="FIRSTNAME" required>
    <br/>
    <span id="error4"></span>
</form>

<!-- buttons -->
<button class="previous hide">Previous</button>
<button class="next">Next</button>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-04
    • 2019-06-11
    • 2019-04-06
    • 2012-06-04
    • 2015-08-28
    • 2022-11-09
    • 1970-01-01
    相关资源
    最近更新 更多