当存在单个输入字段时,Bootbox 错误地提交表单

Bootbox incorrectly submits a form when a single input field is present

我有一个奇怪的问题开始困扰我。提前为一大堆代码和有点令人困惑的问题道歉。

我需要为用户显示模态表单,并让他们填写一些详细信息。

如果我有一个包含多个 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"/>&emsp;<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 没有任何作用,用户必须点击 SaveCancel.

我相信这与 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; });