- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 Bootstrap 4 进行非常基本的表单验证。出于某种原因,在我的示例中将类“is-valid”添加到我的第二个输入时,因为第一个输入具有“is-invalid”类,第二个输入将有绿色边框(因为它应该是有效的!),但是它也会显示无效反馈 div(“此字段是必需的”消息!)。
参见:
我不确定我在这里做错了什么......这是代码:
/**
* AJAX Post script
*/
const ERROR_TYPE_FATALERROR = 1;
const ERROR_TYPE_INPUTERROR = 2;
const ERROR_TYPE_GLOBALMESSAGE = 3;
// Run through the validate() function ONLY once the form as been submitted once!
// Otherwise, user will get validation right away as he types! Just a visual thing ...
var formSubmittedOnce = false;
/**
* submitFormData()
* Serialize and post form data with an AJAX call
*
* Example: onClick="submitFormData('frm1',['username','email'])"
*
* @param string formid essentially the 'id' of the container holding all form elements (i.e. <tr id="rowfrm_1">, <form id='frm1'>, etc.)
* @param array fields list of field names that may produce input errors (i.e. ['username','email'] )
*/
function submitFormData(formid, fields) {
// flag form was submitted once!
formSubmittedOnce = true;
// ----------------------------------
// first rehide all error containers
// ----------------------------------
$('#fatalError').removeClass('d-block');
$('#fatalErrorID').removeClass('d-block');
$('#fatalErrorTrace').removeClass('d-block');
$('#fatalErrorGoBack').removeClass('d-block');
$('#globalMessage').removeClass('d-block');
$('#globalMessageID').removeClass('d-block');
$('#globalMessageTrace').removeClass('d-block');
$('#globalMessageFooter').removeClass('d-block');
$('#globalMessageMailLink').removeClass('d-block');
$('#globalMessageGoBackLink').removeClass('d-block');
// rehide error containers of all inputs that might produce errors
if (fields != null){
for (const f of fields) {
$('#' + f + '_inputError').removeClass('d-block');
}
}
// ----------------------------------
// loop form elements and validate required fields
// ----------------------------------
var formNode = $("#"+formid);
var formInputs = formNode.find("select, textarea, input");
var submit = true;
for(var i = 0; i < formInputs.length; ++i) {
var input = formInputs[i];
// validate fields
if( validate(input) === false ){
submit = false;
}
}
if(submit === true) {
// ----------------------------------
// get form data and serialize it!
// ----------------------------------
// formid comes from a <form>. just serialize it
if( formNode.prop("tagName") === "FORM" ){
var formData = formNode.serialize();
}
// formid doesn't come from a <form>
else {
// get all form control
var myInputs = formNode.clone();
// bug with clone() and SELECT controls: it'll only get the value of the option having the 'selected' attribute (the default value)
// this hack will change the value clone() got to the actual user selected value, and not the default set value!
formNode.find('select').each(function(i) {
myInputs.find('select').eq(i).val($(this).val());
})
// create a dummy form, append all inputs to it and serialize it.
var formData = $('<form>').append(myInputs).serialize();
}
// ----------------------------------
// POST !
// ----------------------------------
$.ajax({
type: 'POST',
url: $(location).attr('href'),
data: formData,
dataType : "json",
}).done(function(response) {
// get response
if(response) {
// if we got success, redirect if we got a redirect url!
if ( response.success != null ) {
if (typeof response.success === "string") {
window.location.replace(response.success);
}
}
// if anything else, PHP returned some errors or a message to display (i.e. 'data saved!')
else {
showMessages(response);
}
}
// Successful post, but no response came back !?
// assume success, since no 'success' response came back, thus keeping same page as is
else {
console.warn("Post sent, but no response came back!? Assuming successful post...");
}
}).fail(function(xhr, status, error) { // we get here if we don't have a proper response/json sent!
console.error("Ajax failed: " + xhr.statusText);
console.error(status);
console.error(error);
var ajaxError = {
'type' : ERROR_TYPE_FATALERROR,
'message' : '<strong>Ajax failure!</strong><br/><br/>' + status + '<br/><br/>' + error,
'trace' : null,
'id' : null,
'goback' : null,
'adminMailtoLnk' : 'mailto:' + 'ravenlost2@gmail.com'
};
showMessages(ajaxError);
});
}
}
/**
* showMessages()
* show error messages in page based on JSON response
* @param response JSON object holding response with (error) messages to display
*/
function showMessages(response){
// error type
switch (response.type) {
// ----------------------------
// GLOBAL MESSAGE
// ----------------------------
case ERROR_TYPE_GLOBALMESSAGE:
$('#globalMessage').addClass('d-block');
// set global message header message type
$('#globalMessage').removeClass("error warning info");
$('#globalMessage').addClass(response.gmType);
$('#globalMessageIcon').removeClass("fa-exclamation-triangle fa-info-circle");
$('#globalMessageIcon').addClass(response.gmIcon);
$('#globalMessageTitle').empty();
$('#globalMessageTitle').append(response.gmTitle);
// set message
$('#globalMessagePH').empty();
$('#globalMessagePH').append(response.message);
// set uniq error id
if (response.id != null) {
$('#globalMessageID').addClass('d-block');
$('#globalMessageIDPH').empty();
$('#globalMessageIDPH').append(response.id);
}
// set stacktrace
if(response.trace != null) {
$('#globalMessageTrace').addClass('d-block');
$('#globalMessageTracePH').empty();
$('#globalMessageTracePH').append(response.trace);
}
// set footer
if( (response.showContactAdmin == true) || (response.goback != null) ) {
$('#globalMessageFooter').addClass('d-block');
// contact admin
if(response.showContactAdmin == true) {
$('#globalMessageMailLink').addClass('d-block');
$('#globalMessageMailLinkPH').attr('href', response.adminMailtoLnk);
}
// go back
if(response.goback != null){
$('#globalMessageGoBackLink').addClass('d-block');
$('#globalMessageGoBackLinkPH').attr('href', response.goback);
}
}
break;
// ----------------------------
// FATAL ERROR
// ----------------------------
case ERROR_TYPE_FATALERROR:
// hide content if we got a fatal as to prevent user from fiddling around and not reading the message!
$('#content').addClass('d-none');
$('#fatalError').addClass('d-block');
// set message
$('#fatalErrorMessagePH').empty();
$('#fatalErrorMessagePH').append(response.message);
// reset mailto link
$('#fatalErrorMailLink').attr('href', response.adminMailtoLnk);
// set stacktrace
if (response.trace != null) {
$('#fatalErrorTrace').addClass('d-block');
$('#fatalErrorTracePH').empty();
$('#fatalErrorTracePH').append(response.trace);
}
// set uniq error id
if (response.id != null) {
$('#fatalErrorID').addClass('d-block');
$('#fatalErrorIDPH').empty();
$('#fatalErrorIDPH').append(response.id);
}
// set 'go back' url
if(response.goback != null) {
$('#fatalErrorGoBack').addClass('d-block');
$('#fatalErrorGoBackLink').attr('href', response.goback);
}
break;
// ----------------------------
// INPUT ERROR
// ----------------------------
case ERROR_TYPE_INPUTERROR:
for (var field in response.fields) {
var msg = eval('response.fields.' + field);
$('#' + field + '_inputError').addClass('d-block')
$('#' + field + '_inputError_message').empty();
$('#' + field + '_inputError_message').append(msg);
}
break;
default:
console.error('Got an invalid error type from the response!');
}
}
/**
* validate()
* Validate if field is empty or not
* @param input form element
* @return boolean
*/
function validate(input) {
if(formSubmittedOnce === true) {
if( input.hasAttribute('required') ) {
if(input.value.trim() === '') {
input.classList.remove('is-valid');
input.classList.add('is-invalid');
return false;
}
else {
input.classList.remove('is-invalid');
input.classList.add('is-valid');
return true;
}
}
else {
// if we get here, then any other inputs not marked as 'required' are valid
input.classList.add('is-valid');
}
}
}
<html>
<head>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" type="text/css">
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
</script>
</head>
<body>
<form id="testfrm" class="form-group">
Username: <input type="text" name="username" aria-describedby="username_required username_inputError" class="form-control is-invalid" oninput="validate(this)" required/><br>
<div id="username_required" class="pl-1 invalid-feedback">
This field is required!
</div>
<!-- if bad username format or already taken, print form input error -->
<div id="username_inputError" class="col alert alert-danger alert-dismissible fade show mt-2 py-2 pl-3 pr-5 text-left d-none">
<small>
<strong>Error!</strong> <span id="username_inputError_message"></span>
<button type="button" aria-label="Close" class="close pt-1 pr-2" onclick="$('#username_inputError').removeClass('d-block').addClass('d-none');">×</button>
</small>
</div>
Email: <input type="text" name="email" aria-describedby="email_required email_inputError" class="form-control is-valid" oninput="validate(this)" required/><br>
<div id="email_required" class="pl-1 invalid-feedback">
This field is required!
</div>
<!-- if bad email format or already taken, print form input error -->
<div id="email_inputError" class="col alert alert-danger alert-dismissible fade show mt-2 py-2 pl-3 pr-5 text-left d-none">
<small>
<strong>Error!</strong> <span id="email_inputError_message"></span>
<button type="button" aria-label="Close" class="close pt-1 pr-2" onclick="$('#email_inputError').removeClass('d-block').addClass('d-none');">×</button>
</small>
</div>
Comment: <input type="text" name="comment" class="form-control is-valid"><br>
<input type="button" value="Submit" onclick="submitFormData('testfrm',['username','email'])" class="is-valid">
</form>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.bundle.min.js" integrity="sha384-6khuMg9gaYr5AxOqhkVIODVIvm9ynTT5J4V1cfthmT+emCG6yVmEZsRHdxlotUnm" crossorigin="anonymous"></script>
</body>
</html>
如果有人能阐明这一点……干杯!帕特
最佳答案
它不起作用的原因是您没有包装您的标签并在 form-group
中输入格
验证已经改变了它过去用于 Bootstrap 的方式 - 这意味着 is-valid
我和我 s invalid
不知道在哪里看,所以当它不在包裹的表单组 div 中时,它应用 is-invalid
给所有匹配的消息 divs
.
我已经添加了 label
让它变得更好而不是仅仅使用电子邮件:<input>
如果您现在提交没有任何值的表单,它将显示错误 _ 一旦您输入输入,错误就会消失。
运行下面的代码片段以查看它的运行情况。
/**
* AJAX Post script
*/
const ERROR_TYPE_FATALERROR = 1;
const ERROR_TYPE_INPUTERROR = 2;
const ERROR_TYPE_GLOBALMESSAGE = 3;
// Run through the validate() function ONLY once the form as been submitted once!
// Otherwise, user will get validation right away as he types! Just a visual thing ...
var formSubmittedOnce = false;
/**
* submitFormData()
* Serialize and post form data with an AJAX call
*
* Example: onClick="submitFormData('frm1',['username','email'])"
*
* @param string formid essentially the 'id' of the container holding all form elements (i.e. <tr id="rowfrm_1">, <form id='frm1'>, etc.)
* @param array fields list of field names that may produce input errors (i.e. ['username','email'] )
*/
function submitFormData(formid, fields) {
// flag form was submitted once!
formSubmittedOnce = true;
// ----------------------------------
// first rehide all error containers
// ----------------------------------
$('#fatalError').removeClass('d-block');
$('#fatalErrorID').removeClass('d-block');
$('#fatalErrorTrace').removeClass('d-block');
$('#fatalErrorGoBack').removeClass('d-block');
$('#globalMessage').removeClass('d-block');
$('#globalMessageID').removeClass('d-block');
$('#globalMessageTrace').removeClass('d-block');
$('#globalMessageFooter').removeClass('d-block');
$('#globalMessageMailLink').removeClass('d-block');
$('#globalMessageGoBackLink').removeClass('d-block');
// rehide error containers of all inputs that might produce errors
if (fields != null) {
for (const f of fields) {
$('#' + f + '_inputError').removeClass('d-block');
}
}
// ----------------------------------
// loop form elements and validate required fields
// ----------------------------------
var formNode = $("#" + formid);
var formInputs = formNode.find("select, textarea, input");
var submit = true;
for (var i = 0; i < formInputs.length; ++i) {
var input = formInputs[i];
// validate fields
if (validate(input) === false) {
submit = false;
}
}
if (submit === true) {
// ----------------------------------
// get form data and serialize it!
// ----------------------------------
// formid comes from a <form>. just serialize it
if (formNode.prop("tagName") === "FORM") {
var formData = formNode.serialize();
}
// formid doesn't come from a <form>
else {
// get all form control
var myInputs = formNode.clone();
// bug with clone() and SELECT controls: it'll only get the value of the option having the 'selected' attribute (the default value)
// this hack will change the value clone() got to the actual user selected value, and not the default set value!
formNode.find('select').each(function(i) {
myInputs.find('select').eq(i).val($(this).val());
})
// create a dummy form, append all inputs to it and serialize it.
var formData = $('<form>').append(myInputs).serialize();
}
// ----------------------------------
// POST !
// ----------------------------------
$.ajax({
type: 'POST',
url: $(location).attr('href'),
data: formData,
dataType: "json",
}).done(function(response) {
// get response
if (response) {
// if we got success, redirect if we got a redirect url!
if (response.success != null) {
if (typeof response.success === "string") {
window.location.replace(response.success);
}
}
// if anything else, PHP returned some errors or a message to display (i.e. 'data saved!')
else {
showMessages(response);
}
}
// Successful post, but no response came back !?
// assume success, since no 'success' response came back, thus keeping same page as is
else {
console.warn("Post sent, but no response came back!? Assuming successful post...");
}
}).fail(function(xhr, status, error) { // we get here if we don't have a proper response/json sent!
console.error("Ajax failed: " + xhr.statusText);
console.error(status);
console.error(error);
var ajaxError = {
'type': ERROR_TYPE_FATALERROR,
'message': '<strong>Ajax failure!</strong><br/><br/>' + status + '<br/><br/>' + error,
'trace': null,
'id': null,
'goback': null,
'adminMailtoLnk': 'mailto:' + 'ravenlost2@gmail.com'
};
showMessages(ajaxError);
});
}
}
/**
* showMessages()
* show error messages in page based on JSON response
* @param response JSON object holding response with (error) messages to display
*/
function showMessages(response) {
// error type
switch (response.type) {
// ----------------------------
// GLOBAL MESSAGE
// ----------------------------
case ERROR_TYPE_GLOBALMESSAGE:
$('#globalMessage').addClass('d-block');
// set global message header message type
$('#globalMessage').removeClass("error warning info");
$('#globalMessage').addClass(response.gmType);
$('#globalMessageIcon').removeClass("fa-exclamation-triangle fa-info-circle");
$('#globalMessageIcon').addClass(response.gmIcon);
$('#globalMessageTitle').empty();
$('#globalMessageTitle').append(response.gmTitle);
// set message
$('#globalMessagePH').empty();
$('#globalMessagePH').append(response.message);
// set uniq error id
if (response.id != null) {
$('#globalMessageID').addClass('d-block');
$('#globalMessageIDPH').empty();
$('#globalMessageIDPH').append(response.id);
}
// set stacktrace
if (response.trace != null) {
$('#globalMessageTrace').addClass('d-block');
$('#globalMessageTracePH').empty();
$('#globalMessageTracePH').append(response.trace);
}
// set footer
if ((response.showContactAdmin == true) || (response.goback != null)) {
$('#globalMessageFooter').addClass('d-block');
// contact admin
if (response.showContactAdmin == true) {
$('#globalMessageMailLink').addClass('d-block');
$('#globalMessageMailLinkPH').attr('href', response.adminMailtoLnk);
}
// go back
if (response.goback != null) {
$('#globalMessageGoBackLink').addClass('d-block');
$('#globalMessageGoBackLinkPH').attr('href', response.goback);
}
}
break;
// ----------------------------
// FATAL ERROR
// ----------------------------
case ERROR_TYPE_FATALERROR:
// hide content if we got a fatal as to prevent user from fiddling around and not reading the message!
$('#content').addClass('d-none');
$('#fatalError').addClass('d-block');
// set message
$('#fatalErrorMessagePH').empty();
$('#fatalErrorMessagePH').append(response.message);
// reset mailto link
$('#fatalErrorMailLink').attr('href', response.adminMailtoLnk);
// set stacktrace
if (response.trace != null) {
$('#fatalErrorTrace').addClass('d-block');
$('#fatalErrorTracePH').empty();
$('#fatalErrorTracePH').append(response.trace);
}
// set uniq error id
if (response.id != null) {
$('#fatalErrorID').addClass('d-block');
$('#fatalErrorIDPH').empty();
$('#fatalErrorIDPH').append(response.id);
}
// set 'go back' url
if (response.goback != null) {
$('#fatalErrorGoBack').addClass('d-block');
$('#fatalErrorGoBackLink').attr('href', response.goback);
}
break;
// ----------------------------
// INPUT ERROR
// ----------------------------
case ERROR_TYPE_INPUTERROR:
for (var field in response.fields) {
var msg = eval('response.fields.' + field);
$('#' + field + '_inputError').addClass('d-block')
$('#' + field + '_inputError_message').empty();
$('#' + field + '_inputError_message').append(msg);
}
break;
default:
console.error('Got an invalid error type from the response!');
}
}
/**
* validate()
* Validate if field is empty or not
* @param input form element
* @return boolean
*/
function validate(input) {
if (formSubmittedOnce === true) {
if (input.hasAttribute('required')) {
if (input.value.trim() == '') {
input.classList.remove('is-valid');
input.classList.add('is-invalid');
return false;
} else {
input.classList.remove('is-invalid');
input.classList.add('is-valid');
return true;
}
} else {
// if we get here, then any other inputs not marked as 'required' are valid
input.classList.add('is-valid');
}
}
}
<html>
<head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
</head>
<body>
<form id="testfrm" class="form-group">
<div class="form-group">
<label class="form-control-label" for="username_required">Username</label>
<input type="text" name="username" aria-describedby="username_required username_inputError" class="form-control is-invalid" oninput="validate(this)" required/><br>
<div id="username_required" class="pl-1 invalid-feedback">
This field is required!
</div>
<!-- if bad username format or already taken, print form input error -->
<div id="username_inputError" class="col alert alert-danger alert-dismissible fade show mt-2 py-2 pl-3 pr-5 text-left d-none">
<small>
<strong>Error!</strong> <span id="username_inputError_message"></span>
<button type="button" aria-label="Close" class="close pt-1 pr-2" onclick="$('#username_inputError').removeClass('d-block').addClass('d-none');">×</button>
</small>
</div>
<div class="form-group">
<label class="form-control-label" for="email_required">Email</label>
<input type="text" name="email" aria-describedby="email_required email_inputError" class="form-control is-valid" oninput="validate(this)" required/><br>
<div id="email_required" class="pl-1 invalid-feedback">
This field is required!
</div>
</div>
<!-- if bad email format or already taken, print form input error -->
<div id="email_inputError" class="col alert alert-danger alert-dismissible fade show mt-2 py-2 pl-3 pr-5 text-left d-none">
<small>
<strong>Error!</strong> <span id="email_inputError_message"></span>
<button type="button" aria-label="Close" class="close pt-1 pr-2" onclick="$('#email_inputError').removeClass('d-block').addClass('d-none');">×</button>
</small>
</div>
Comment: <input type="text" name="comment" class="form-control is-valid"><br>
<input type="button" value="Submit" onclick="submitFormData('testfrm',['username','email'])" class="is-valid">
</form>
</body>
</html>
关于jquery - 即使在输入 'is-valid' 时使用无效反馈时 Bootstrap 4 表单验证也不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62832151/
SQLite、Content provider 和 Shared Preference 之间的所有已知区别。 但我想知道什么时候需要根据情况使用 SQLite 或 Content Provider 或
警告:我正在使用一个我无法完全控制的后端,所以我正在努力解决 Backbone 中的一些注意事项,这些注意事项可能在其他地方更好地解决......不幸的是,我别无选择,只能在这里处理它们! 所以,我的
我一整天都在挣扎。我的预输入搜索表达式与远程 json 数据完美配合。但是当我尝试使用相同的 json 数据作为预取数据时,建议为空。点击第一个标志后,我收到预定义消息“无法找到任何内容...”,结果
我正在制作一个模拟 NHL 选秀彩票的程序,其中屏幕右侧应该有一个 JTextField,并且在左侧绘制弹跳的选秀球。我创建了一个名为 Ball 的类,它实现了 Runnable,并在我的主 Draf
这个问题已经有答案了: How can I calculate a time span in Java and format the output? (18 个回答) 已关闭 9 年前。 这是我的代码
我有一个 ASP.NET Web API 应用程序在我的本地 IIS 实例上运行。 Web 应用程序配置有 CORS。我调用的 Web API 方法类似于: [POST("/API/{foo}/{ba
我将用户输入的时间和日期作为: DatePicker dp = (DatePicker) findViewById(R.id.datePicker); TimePicker tp = (TimePic
放宽“邻居”的标准是否足够,或者是否有其他标准行动可以采取? 最佳答案 如果所有相邻解决方案都是 Tabu,则听起来您的 Tabu 列表的大小太长或您的释放策略太严格。一个好的 Tabu 列表长度是
我正在阅读来自 cppreference 的代码示例: #include #include #include #include template void print_queue(T& q)
我快疯了,我试图理解工具提示的行为,但没有成功。 1. 第一个问题是当我尝试通过插件(按钮 1)在点击事件中使用它时 -> 如果您转到 Fiddle,您会在“内容”内看到该函数' 每次点击都会调用该属
我在功能组件中有以下代码: const [ folder, setFolder ] = useState([]); const folderData = useContext(FolderContex
我在使用预签名网址和 AFNetworking 3.0 从 S3 获取图像时遇到问题。我可以使用 NSMutableURLRequest 和 NSURLSession 获取图像,但是当我使用 AFHT
我正在使用 Oracle ojdbc 12 和 Java 8 处理 Oracle UCP 管理器的问题。当 UCP 池启动失败时,我希望关闭它创建的连接。 当池初始化期间遇到 ORA-02391:超过
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve
引用这个plunker: https://plnkr.co/edit/GWsbdDWVvBYNMqyxzlLY?p=preview 我在 styles.css 文件和 src/app.ts 文件中指定
为什么我的条形这么细?我尝试将宽度设置为 1,它们变得非常厚。我不知道还能尝试什么。默认厚度为 0.8,这是应该的样子吗? import matplotlib.pyplot as plt import
当我编写时,查询按预期执行: SELECT id, day2.count - day1.count AS diff FROM day1 NATURAL JOIN day2; 但我真正想要的是右连接。当
我有以下时间数据: 0 08/01/16 13:07:46,335437 1 18/02/16 08:40:40,565575 2 14/01/16 22:2
一些背景知识 -我的 NodeJS 服务器在端口 3001 上运行,我的 React 应用程序在端口 3000 上运行。我在 React 应用程序 package.json 中设置了一个代理来代理对端
我面临着一个愚蠢的问题。我试图在我的 Angular 应用程序中延迟加载我的图像,我已经尝试过这个2: 但是他们都设置了 src attr 而不是 data-src,我在这里遗漏了什么吗?保留 d
我是一名优秀的程序员,十分优秀!