我正在使用 javascript 檢查表單中的必填欄位,以便對欄位進行樣式設定,如果在focusout. (這是對僅在提交時進行驗證的 Kirby CMS 表單插件的補充。)
我試圖創造的行為是......
- 當必填欄位留空時,樣式和訊息會出現在 上
focusout。 - 樣式和訊息保持可見,直到 (a) 欄位再次處于焦點狀態或 (b) 欄位被填充。
- 如果必填欄位“重新聚焦”,留空并再次聚焦,則訊息和樣式會重新出現。
我的問題是輸入樣式(紅色邊框底部)按預期作業,但基于appendChild函式的錯誤訊息卻沒有。錯誤訊息一次只出現一條,其中最后一個重點是必填欄位,我無法弄清楚如何讓訊息以與樣式相同的方式保持不變。
因為在實踐中,表單將由內容管理員使用 CMS 創建,所以我希望腳本是 vanilla JS 并且盡可能通用,避免針對特定 ID。相反,我試圖根據required屬性和querySelectorAll功能來做到這一點。我有一些變數來指定錯誤訊息文本和一個for回圈來僅針對不符合if陳述句標準的“違規”欄位。
function reqdCheck() {
const reqdFields = document.querySelectorAll("main input[required], main textarea[required]");
const reqdPara = document.createElement("p");
const reqdText = document.createTextNode("This field is required.");
reqdPara.appendChild(reqdText);
for (const reqdField of reqdFields) {
reqdField.addEventListener ("focusout", function() {
if (reqdField.value == "" || reqdField.value == null) {
reqdField.style.borderBottom = "1px solid red";
reqdField.style.boxShadow = "0 1px 0 0 red";
reqdField.parentNode.appendChild(reqdPara);
}
else {
reqdField.style.borderBottom = "1px solid black";
reqdField.style.boxShadow = "none";
}
})
reqdField.addEventListener ("focusin", function() {
if (reqdField.value == "" || reqdField.value == null) {
reqdField.style.borderBottom = "1px solid orange";
reqdField.style.boxShadow = "0 1px 0 0 orange";
reqdField.parentNode.removeChild(reqdPara);
}
})
}
}
reqdCheck()
input:not([type="submit"]),
textarea {
border: none;
border-bottom: 1px solid black;
display: block;
width: calc(100% - 40px);
}
input:not([type="submit"]):focus,
textarea:focus {
outline: none;
border-bottom: 1px solid orange;
box-shadow: 0 1px 0 0 orange;
}
.field-group {
margin-bottom: 20px;
}
.field-group p {
color: red;
line-height: 1;
margin: 5px 0 0;
}
<main>
<form id="a2a64e93-2b60-4ad9-9445-ce61f5852594" action="#">
<div class="field-group">
<label for="fname">First name:*</label><br>
<input type="text" id="fname" name="fname" placeholder="John" required>
</div>
<div class="field-group">
<label for="lname">Last name:</label><br>
<input type="text" id="lname" name="lname" placeholder="Doe">
</div>
<div class="field-group">
<label for="company">Company:</label><br>
<input type="text" id="fname" name="company" placeholder="Acme Ltd">
</div>
<div class="field-group">
<label for="email">Email:*</label><br>
<input type="email" id="email" name="email" placeholder="[email protected]" required>
</div>
<div class="field-group">
<label for="email">Message:*</label><br>
<textarea id="message" name="message" placeholder="Message" required></textarea>
</div>
<input type="submit" value="Submit">
</form>
</main>
為了讓 appendChild 錯誤訊息按預期保持可見,我缺少什么?有沒有更有效的方法來實作我所追求的?謝謝。
uj5u.com熱心網友回復:
發生這種情況的原因是您只創建了一個p元素(錯誤文本)并且您想多次附加它。為了解決這個問題,您應該reqdPara在 for 回圈中添加所有邏輯。看看這里:
function reqdCheck() {
const reqdFields = document.querySelectorAll(
'main input[required], main textarea[required]'
);
for (const reqdField of reqdFields) {
const reqdPara = document.createElement('p');
const reqdText = document.createTextNode('This field is required.');
reqdPara.appendChild(reqdText);
reqdField.addEventListener('focusout', function () {
if (reqdField.value === '' || reqdField.value === null) {
reqdField.style.borderBottom = '1px solid red';
reqdField.style.boxShadow = '0 1px 0 0 red';
reqdField.parentNode.appendChild(reqdPara);
} else {
reqdField.style.borderBottom = '1px solid black';
reqdField.style.boxShadow = 'none';
}
});
reqdField.addEventListener('focusin', function () {
if (reqdField.value == '' || reqdField.value == null) {
reqdField.style.borderBottom = '1px solid orange';
reqdField.style.boxShadow = '0 1px 0 0 orange';
reqdField.parentNode.removeChild(reqdPara);
}
});
}
}
reqdCheck();
uj5u.com熱心網友回復:
細節在例子中注釋
顯示代碼片段
/**
* Reference <form>
* Bind <form> to the "focusout" event
* Bind <form> to the "focusin" event
*/
const profile = document.forms.profile;
profile.addEventListener('focusout', requiredData);
profile.addEventListener('focusin', clearData);
// htmlString for error message
const req = `<output name="error">This field is required</output>`;
/**
* Event handler passes (e)vent object by default
* Reference the element being unfocused by user
* If said element is NOT <form> AND said element has the
* attribute "required"...
* ...and if said element is blank...
* Insert error message after said element and add ".error"
* class to it
*/
function requiredData(e) {
const leaving = e.target;
if (leaving != this && leaving.hasAttribute("required")) {
if (leaving.value === "") {
/* Uncomment the next line and comment the line after the next line if you prefer the error message inside the <label> */ //leaving.previousElementSibling.insertAdjacentHTML("beforeend", req);
leaving.insertAdjacentHTML("afterend", req)
leaving.classList.add("error");
return;
}
}
}
/**
* Pretty much the same as requiredData(e) except...
* The third criteria looks for the ".error" class on the
* element the user focused on.
* The ".error" class and error message is removed
*/
function clearData(e) {
const entering = e.target;
if (entering !== this && entering.hasAttribute("required")) {
if (entering.matches(".error")) {
entering.classList.remove("error");
/* Uncomment the next line and comment the line after the next line if you prefer the error message inside the <label> */
//entering.previousElementSibling.querySelector("[name='error']").remove();
entering.nextElementSibling.remove();
return;
}
}
}
:root {
font: 300 2ch/1.1 "Segoe UI"
}
.profile {
padding-top: 0.75rem;
}
fieldset fieldset {
margin-top: 0.75rem;
}
legend {
font-size: 1.15rem;
}
label sup,
legend sup {
color: red;
}
.fc {
border: none;
border-bottom: 1px solid black;
}
.fc:focus {
outline: none;
border-color: orange;
box-shadow: 0 1px 0 0 orange;
}
label,
button,
input,
textarea {
display: block;
font: inherit;
}
input,
textarea {
margin-bottom: 0.5rem
}
label {
width: max-content;
margin-top: 0.75rem;
white-space: pre;
}
legend label {
margin-top: 0.25rem;
}
label,
input,
textarea {
width: 99%;
}
#phone {
width: 12ch;
}
button {
float: right;
width: max-content;
margin-top: 0.5rem;
padding: 2px 4px;
cursor: pointer;
}
output {
border: 0;
color: red;
font-weight: 500;
font-size: 1rem;
}
.error {
border-width: 3px;
border-color: red;
background: rgba(200, 0, 0, 0.3)
}
<main>
<form id="a2a64e93-2b60-4ad9-9445-ce61f5852594" name="profile" action="#">
<fieldset class="profile">
<legend>Profile</legend>
<fieldset>
<legend>Full Name</legend>
<label for="fname">First:<sup>?</sup></label>
<input id="fname" name="fullname" class="fc" type="text" placeholder="John" required>
<label for="lname">Last:<sup>?</sup></label>
<input id="lname" name="fullname" class="fc" type="text" placeholder="Doe" required>
</fieldset>
<fieldset>
<legend>Location</legend>
<label for="company">Company:</label>
<input id="company" name="location" class="fc" type="text" placeholder="Acme Ltd">
<label for="address">Address:</label>
<textarea id="address" name="location" class="fc" placeholder="123 Main St.
Springfield, IL 62702" rows="3" cols="22"></textarea>
</fieldset>
<fieldset>
<legend>Contact</legend>
<label for="email">Email:<sup>?</sup></label>
<input id="email" name="contact" class="fc" type="email" placeholder="[email protected]" required>
<label for="phone">Phone:</label>
<input id="phone" name="contact" class="fc" type="tel" placeholder="123-456-7890" pattern="\(?\d{3}[)\- ]\d{3}[\- ]\d{4}">
</fieldset>
<fieldset>
<legend>Message:<sup>?</sup></legend>
<textarea id="message" name="message" class="fc" placeholder="Enter message here" required></textarea>
</fieldset>
<Button>Submit</Button>
</fieldset>
</form>
</main>
小提琴
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/525746.html
標籤:javascriptif 语句附子
