当存在单个输入字段时,Bootbox 错误地提交表单
Bootbox incorrectly submits a form when a single input field is present
我有一个奇怪的问题开始困扰我。提前为一大堆代码和有点令人困惑的问题道歉。
我需要为用户显示模态表单,并让他们填写一些详细信息。
- 用户可以点击保存来保存他们的更改。
- 用户可以点击取消来取消他们的更改。
- 我使用
save
处理程序序列化表单并将其数据发送到 JSON 服务。
如果我有一个包含多个 input
字段的表单,一切都很好,没有意外发生。
但是,如果我有一个只有一个 input
字段的表单,我会得到意想不到的副作用。在该输入字段中点击 Enter/Return 会导致提交模态表单,而不是调用我的 JSON 处理程序,页面会以表单的参数作为参数重新加载 - 就像正在提交表单一样。事实上,向表单元素添加 action=
参数已经证明,当您导航到您指定的页面时。
这是我使用的表格:
<form id="surveyQuestionForm" class="form-horizontal" style="display:none;">
<div class="row">
<input name="surveyQuestionId" id="surveyQuestionId" type="hidden">
<input name="surveyId" type="hidden" value="${survey.surveyId}">
<div class="control-group">
<label class="control-label" for="questionType"><b><spring:message code="survey.question.type"/></b></label>
<div class="controls">
<select class="input-large" name="questionType" id="questionType">
<option value="">(Select one)</option>
<c:forEach items="${surveyQuestionTypes}" var="surveyQuestionType">
<option value="${surveyQuestionType.code}">${surveyQuestionType.name}</option>
</c:forEach>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="questionText"><b><spring:message code="survey.question.text"/></b></label>
<div class="controls">
<input type="text" class="input-xlarge" name="questionText" id="questionText" maxLength="64"/>
</div>
</div>
</div>
</form>
这是我用来模态显示表单的代码:
function addQuestion() {
// find the form, and initialise its validation.
var form = $('#surveyQuestionForm');
var validator = form.validate(
{
rules: {
questionType: {
required: true
},
questionText: {
required: true
}
},
messages: {
questionType: {
required: '<spring:message javaScriptEscape="true" code="survey.question.type.required"/>'
},
questionText: {
required: '<spring:message javaScriptEscape="true" code="survey.question.text.required"/>'
}
},
onkeyup: false
});
// reset form validation, and hide any error message
validator.resetForm();
$("#errorMessage").hide();
// show the dialog
bootbox.dialog({
title: '<i class="icon-plus green"/> <spring:message javaScriptEscape="true" code="survey.add.question"/>',
message: form,
closeButton: false,
buttons: {
cancel: {
label: '<i class="icon-remove bigger-130"></i> <spring:message javaScriptEscape="true" code="button.cancel"/>',
className: "btn btn-danger"
},
save: {
label: '<i class="icon-ok bigger-130"></i> <spring:message javaScriptEscape="true" code="button.save"/>',
className: 'btn btn-success',
callback: function () {
var result = false;
if (!form.valid())
return false;
$.ajax({
type: "POST",
url: '/addSurveyQuestion.json',
async: false,
data: form.serialize(),
success: function (outcome) {
if (outcome.success) {
$('#question-list').dataTable().fnReloadAjax();
result = true;
}
else {
$("#errorMessage").html(htmlEncode(outcome.message)).show();
}
}
}
).fail(function () {
$.gritter.add({
title: '<spring:message javaScriptEscape="true" code="general.error"/>',
text: '<spring:message javaScriptEscape="true" code="server.error"/>',
class_name: 'gritter-error'
}
);
}
);
return result;
}
}
},
show: false,
animate: false,
onEscape: false
}
).on('shown.bs.modal', function () {
var form = $('#surveyQuestionForm');
form.find('#surveyQuestionId').val(null);
form.find('#questionType').val('');
form.find('#questionText').val('');
form.show().find('#questionType').focus();
form.show();
}
).on('hide.bs.modal', function (e) {
if (e.target === this)
$('#surveyQuestionForm').hide().appendTo('body');
}
).modal('show').addClass("bootboxDialog40");
}
如果我按原样使用此代码,在 Bootbox 4.4 中,当用户在 questionText
字段中时点击 Enter/Return 提交表单,我的页面重新显示,但表单字段为参数,例如:
page.html?surveyQuestionId=&surveyId=3&questionType=Y&questionText=blah
如果我有一个 second input
字段,在字段中点击 Enter/Return 没有任何作用,用户必须点击 Save
或 Cancel
.
我相信这与 bootbox 插件无关。真正的原因在这里:
https://www.w3.org/MarkUp/html-spec/html-spec_8.html#SEC8.2
When there is only one single-line text input field in a form, the user agent should accept Enter in that field as a request to submit the form.
来到解决方案,您可以在表单中添加另一个隐藏字段,这将阻止在输入时提交表单。
单个输入字段的“输入时提交”是您需要覆盖的浏览器行为。您可以通过几种方式做到这一点。
<form onSubmit="return false;">
我认为您根本没有使用本机 submit
函数,因此添加这一点内联脚本会阻止表单提交。但是将脚本放入您的标记中并不是很好。一点 jQuery 可以为您做同样的事情:
$('form').on('submit', function(){ return false; });
我有一个奇怪的问题开始困扰我。提前为一大堆代码和有点令人困惑的问题道歉。
我需要为用户显示模态表单,并让他们填写一些详细信息。
- 用户可以点击保存来保存他们的更改。
- 用户可以点击取消来取消他们的更改。
- 我使用
save
处理程序序列化表单并将其数据发送到 JSON 服务。
如果我有一个包含多个 input
字段的表单,一切都很好,没有意外发生。
但是,如果我有一个只有一个 input
字段的表单,我会得到意想不到的副作用。在该输入字段中点击 Enter/Return 会导致提交模态表单,而不是调用我的 JSON 处理程序,页面会以表单的参数作为参数重新加载 - 就像正在提交表单一样。事实上,向表单元素添加 action=
参数已经证明,当您导航到您指定的页面时。
这是我使用的表格:
<form id="surveyQuestionForm" class="form-horizontal" style="display:none;">
<div class="row">
<input name="surveyQuestionId" id="surveyQuestionId" type="hidden">
<input name="surveyId" type="hidden" value="${survey.surveyId}">
<div class="control-group">
<label class="control-label" for="questionType"><b><spring:message code="survey.question.type"/></b></label>
<div class="controls">
<select class="input-large" name="questionType" id="questionType">
<option value="">(Select one)</option>
<c:forEach items="${surveyQuestionTypes}" var="surveyQuestionType">
<option value="${surveyQuestionType.code}">${surveyQuestionType.name}</option>
</c:forEach>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="questionText"><b><spring:message code="survey.question.text"/></b></label>
<div class="controls">
<input type="text" class="input-xlarge" name="questionText" id="questionText" maxLength="64"/>
</div>
</div>
</div>
</form>
这是我用来模态显示表单的代码:
function addQuestion() {
// find the form, and initialise its validation.
var form = $('#surveyQuestionForm');
var validator = form.validate(
{
rules: {
questionType: {
required: true
},
questionText: {
required: true
}
},
messages: {
questionType: {
required: '<spring:message javaScriptEscape="true" code="survey.question.type.required"/>'
},
questionText: {
required: '<spring:message javaScriptEscape="true" code="survey.question.text.required"/>'
}
},
onkeyup: false
});
// reset form validation, and hide any error message
validator.resetForm();
$("#errorMessage").hide();
// show the dialog
bootbox.dialog({
title: '<i class="icon-plus green"/> <spring:message javaScriptEscape="true" code="survey.add.question"/>',
message: form,
closeButton: false,
buttons: {
cancel: {
label: '<i class="icon-remove bigger-130"></i> <spring:message javaScriptEscape="true" code="button.cancel"/>',
className: "btn btn-danger"
},
save: {
label: '<i class="icon-ok bigger-130"></i> <spring:message javaScriptEscape="true" code="button.save"/>',
className: 'btn btn-success',
callback: function () {
var result = false;
if (!form.valid())
return false;
$.ajax({
type: "POST",
url: '/addSurveyQuestion.json',
async: false,
data: form.serialize(),
success: function (outcome) {
if (outcome.success) {
$('#question-list').dataTable().fnReloadAjax();
result = true;
}
else {
$("#errorMessage").html(htmlEncode(outcome.message)).show();
}
}
}
).fail(function () {
$.gritter.add({
title: '<spring:message javaScriptEscape="true" code="general.error"/>',
text: '<spring:message javaScriptEscape="true" code="server.error"/>',
class_name: 'gritter-error'
}
);
}
);
return result;
}
}
},
show: false,
animate: false,
onEscape: false
}
).on('shown.bs.modal', function () {
var form = $('#surveyQuestionForm');
form.find('#surveyQuestionId').val(null);
form.find('#questionType').val('');
form.find('#questionText').val('');
form.show().find('#questionType').focus();
form.show();
}
).on('hide.bs.modal', function (e) {
if (e.target === this)
$('#surveyQuestionForm').hide().appendTo('body');
}
).modal('show').addClass("bootboxDialog40");
}
如果我按原样使用此代码,在 Bootbox 4.4 中,当用户在 questionText
字段中时点击 Enter/Return 提交表单,我的页面重新显示,但表单字段为参数,例如:
page.html?surveyQuestionId=&surveyId=3&questionType=Y&questionText=blah
如果我有一个 second input
字段,在字段中点击 Enter/Return 没有任何作用,用户必须点击 Save
或 Cancel
.
我相信这与 bootbox 插件无关。真正的原因在这里: https://www.w3.org/MarkUp/html-spec/html-spec_8.html#SEC8.2
When there is only one single-line text input field in a form, the user agent should accept Enter in that field as a request to submit the form.
来到解决方案,您可以在表单中添加另一个隐藏字段,这将阻止在输入时提交表单。
单个输入字段的“输入时提交”是您需要覆盖的浏览器行为。您可以通过几种方式做到这一点。
<form onSubmit="return false;">
我认为您根本没有使用本机 submit
函数,因此添加这一点内联脚本会阻止表单提交。但是将脚本放入您的标记中并不是很好。一点 jQuery 可以为您做同样的事情:
$('form').on('submit', function(){ return false; });