JQuery + TinyMCE = TypeError: validator is undefined

JQuery + TinyMCE = TypeError: validator is undefined

计算器溢出!这是我在这里的第一个问题,所以要温柔! ;)

我从上到下搜索了 SO,但在下面的代码中找不到 "TypeError: validator is undefined" 的解决方案。

我唯一找到的是这个问答:jQuery validation plugin error: TypeError: validator is undefined

似乎每个人都遇到过表单 ID 无效的类似问题。我检查了我所有的 ID,它们都是正确的。

关于我的网站的一些细节:

我的代码存储在 .js 文件中,并在每个页面上加载。我将它加载到一个 "include" 文件中的每个页面上,我的所有自定义 JavaScript 代码都位于该文件中(这当然不包括 JQuery.js、bootstrap.js 等)。我这样做是为了不必 copy/paste 在数百个其他页面上使用相同的代码,我只需添加一个 "include" 文件。

NOT 使用 TinyMCE 表单字段的页面上,我总是收到 TypeError: validator is undefined" 并且我的所有其他 JavaScript 似乎都冻结了。在使用 TinyMCE 表单字段的页面,它工作正常。

请注意,下面显示的我的代码是在这里回答其他人的问题的结果。例如,"tinyMCE.triggerSave();" 代码在尝试验证 TinyMCE 字段时起到了救命稻草的作用。

那么,有人看到下面的问题了吗?我会被迫只在使用 TinyMCE 的页面上加载代码吗?

    $(function() {
    var validator = $("#alert_notification_form").submit(function() {
                // Force MCE to update textarea before proceeding
                tinyMCE.triggerSave();
        }).validate({
            errorElement: 'span',
            errorClass: 'help-block help-block-error',
            focusInvalid: true,
            ignore: '',             
            rules: {
                impact: {
                    required: true
                },
                further_info: {
                    required: true
                }   
            },
            messages:{

                impact: {
                    required: 'Please state how we will be affected.'
                },
                further_info: {
                    required: 'Further Information is required.'
                }
            },
            errorPlacement: function (error, element) {
                if (element.parent(".input-group").size() > 0) {
                    error.insertAfter(element.parent(".input-group"));
                } else if (element.attr("data-error-container")) {
                    error.appendTo(element.attr("data-error-container"));
                } else if (element.parents('.radio-list').size() > 0) {
                    error.appendTo(element.parents('.radio-list').attr("data-error-container"));
                } else if (element.parents('.radio-inline').size() > 0) {
                    error.appendTo(element.parents('.radio-inline').attr("data-error-container"));
                } else if (element.parents('.checkbox-list').size() > 0) {
                    error.appendTo(element.parents('.checkbox-list').attr("data-error-container"));
                } else if (element.parents('.checkbox-inline').size() > 0) {
                    error.appendTo(element.parents('.checkbox-inline').attr("data-error-container"));
                } else {
                    error.insertAfter(element);
                }
            },
            highlight: function (element) {
                $(element)
                    .closest('.form-group').addClass('has-error');
            },
            unhighlight: function (element) {
                $(element)
                    .closest('.form-group').removeClass('has-error');
            },
            success: function (label) {
                label
                    .closest('.form-group').removeClass('has-error');
            }
    });
    validator.focusInvalid = function() {
            // put focus on tinymce on submit validation
            if (this.settings.focusInvalid) {
                try {
                    var toFocus = $(this.findLastActive() || this.errorList.length && this.errorList[0].element || []);
                    if (toFocus.is("textarea")) {
                        tinyMCE.get(toFocus.attr("id")).focus();
                    } else {
                        toFocus.filter(":visible").focus();
                    }
                } catch (e) {
                    // ignore IE throwing errors when focusing hidden elements
                }
            }
        }
    $(".reset").click(function() {
        validator.resetForm();
    });
});

更新 - 2015 年 3 月 1 日

我尝试了下面的两个建议,但我可能还遗漏了一些其他的东西。我发现下面代码中的 "validator.focusinvalid" 函数来自此处的 GIT 存储库:https://github.com/jzaefferer/jquery-validation/blob/master/demo/tinymce4/index.html

该验证程序功能可能有问题吗?我尝试完全删除 "tinyMCE.triggerSave();",但仍然得到 TypeError: validator is undefined.

我错过了什么? :(

作为参考,我添加了初始化 TinyMCE 的代码。

tinymce.init({
selector: "textarea",
menubar: false,
plugins: "link, paste, lists, wordcount",
toolbar: "undo redo | bold italic | alignleft aligncenter alignright | bullist numlist outdent indent | link | paste",
setup: function(editor) {
    editor.on('change', function(e) {
        tinymce.triggerSave();
        $("#" + editor.id).valid();
    });
} });

您可以在所有页面上加载此脚本,但您需要一种方法来检测 TinyMCE 是否处于活动状态。您可以通过调用以下函数来完成,如果为真,则执行 tinyMCE.triggerSave();

function isTinyMCEActive()
{
    is_tinyMCE_active = false;
    if (typeof(tinyMCE) != "undefined")
    {
        if (tinyMCE.activeEditor == null || tinyMCE.activeEditor.isHidden() != false)
        {
            is_tinyMCE_active = true;
        }
    }

    return is_tinyMCE_active;
}

这个if是为了检测TinyMCE是否激活。

现在,至于 "TypeError: validator is undefined" 错误,问题可能是由您将调用链接到 submit() 和 validate() 的方式引起的。这是您的代码的更新版本,调用 beforeSubmit() 方法将编辑器的值保存到他们的文本区域。这样,您就可以定位表单,然后在提交时调用 validate() 方法(在更新文本区域之后)。

$(function() {
var validator = $("#alert_notification_form").validate({
       beforeSubmit:function() {
            // Force MCE to update textarea before proceeding
            tinyMCE.triggerSave();
            return true;
       },
        errorElement: 'span',
        errorClass: 'help-block help-block-error',
        focusInvalid: true,
        ignore: '',             
        rules: {
            impact: {
                required: true
            },
            further_info: {
                required: true
            }   
        },
        messages:{

            impact: {
                required: 'Please state how we will be affected.'
            },
            further_info: {
                required: 'Further Information is required.'
            }
        },
        errorPlacement: function (error, element) {
            if (element.parent(".input-group").size() > 0) {
                error.insertAfter(element.parent(".input-group"));
            } else if (element.attr("data-error-container")) {
                error.appendTo(element.attr("data-error-container"));
            } else if (element.parents('.radio-list').size() > 0) {
                error.appendTo(element.parents('.radio-list').attr("data-error-container"));
            } else if (element.parents('.radio-inline').size() > 0) {
                error.appendTo(element.parents('.radio-inline').attr("data-error-container"));
            } else if (element.parents('.checkbox-list').size() > 0) {
                error.appendTo(element.parents('.checkbox-list').attr("data-error-container"));
            } else if (element.parents('.checkbox-inline').size() > 0) {
                error.appendTo(element.parents('.checkbox-inline').attr("data-error-container"));
            } else {
                error.insertAfter(element);
            }
        },
        highlight: function (element) {
            $(element)
                .closest('.form-group').addClass('has-error');
        },
        unhighlight: function (element) {
            $(element)
                .closest('.form-group').removeClass('has-error');
        },
        success: function (label) {
            label
                .closest('.form-group').removeClass('has-error');
        }
});
validator.focusInvalid = function() {
        // put focus on tinymce on submit validation
        if (this.settings.focusInvalid) {
            try {
                var toFocus = $(this.findLastActive() || this.errorList.length && this.errorList[0].element || []);
                if (toFocus.is("textarea")) {
                    tinyMCE.get(toFocus.attr("id")).focus();
                } else {
                    toFocus.filter(":visible").focus();
                }
            } catch (e) {
                // ignore IE throwing errors when focusing hidden elements
            }
        }
    }
$(".reset").click(function() {
    validator.resetForm();
});
});

一种简单的方法是在初始化仅适用于该类型元素的代码之前检查一个元素或 class 个元素是否存在,但如果代码为 运行,则可能会导致问题。

$(function(){
    if($('.someSpecialClass').length){
       /* code that applies only when selector exists */    
    }
});

或者,如果您有多种插件选项,具体取决于 class 是否存在

var pluginOpts={
   foo:'some value'
}

if($('.someSpecialClass').length){
      $.extend(pluginOpts , {bar: 'another value'});   
}

$(selector).somePlugin(pluginOpts);