【问题标题】:Accessing client_side_validations validation function manually手动访问 client_side_validations 验证函数
【发布时间】:2011-11-02 17:18:52
【问题描述】:

我正在开发 Rails 3 应用程序,我在 JQuery UI 对话框中显示的表单中使用 client_side_validations(从 ActiveRecord 模型验证自动生成的 JavaScript 验证),我想知道是否有一些 JavaScript 函数在用户按下对话框提交(确定)按钮后,我可以调用 client_side_validations 来验证表单中的所有验证是否通过,然后再通过 javascript 提交表单。 client_side_validations 中有类似的东西吗?我注意到 wiki 中有一个名为 Client Side Validations callbacks 的部分看起来很有趣,但我没有在 gem 中看到相应的 javascript 文件。也许是正在进行的工作或已弃用的东西?

基本上我有这个创建包含表单的对话框的 javascript sn-p

$(function() {
    $("#subscription_dialog").dialog({
        autoOpen: false,
        show: "blind",
        hide: "blind",
        width: 'auto',
        height: 'auto',
        modal: true,
        title: "Become an Empower United member",
        buttons: {
            "OK": function () {
                if ($('form[data-validate]').validate()) {
                    $('#new_subscription').submit();
                    $(this).dialog("close");
                }
            },
            "Cancel": function() {
                $(this).dialog("close");
            }
        }
    });

    $("#subscribe").click(function() {
        $("#subscription_dialog").dialog("open");
        return false;
    });
});

我需要在表单提交位之前进行一些验证检查,否则即使其中包含无效数据,对话框也会关闭。我可以使用 jquery 的验证插件编写一个表单,但我不想像这样从模型层复制验证 - 我更希望它们始终保持同步。

提前感谢您可能决定渲染的任何帮助!

【问题讨论】:

    标签: jquery ruby-on-rails ruby validation


    【解决方案1】:

    完成 client_side_validations 安装过程后(在github README 上的 Install 下,如果在 Rails 3.1+ 上,请确保执行 rails g client_side_validations:copy_assets)rails.validations.js 文件应该被删除进入您的app/assets/javascripts 目录。

    这包含客户端验证的 javascript 源代码。如果您在那里四处寻找,您会看到它将javascript ajax:beforeSendsubmit 事件处理程序绑定到您的表单。

    所以它们应该在您的表单自动提交之前被调用。

    但是,要回答一个关于手动触发验证的更通用的问题......

    您可以在表单上调用trigger 并提供ajax:beforeSend 事件来手动触发验证。您还需要传入一个具有包含表单 DOM 元素的 target 属性的对象(因为 rails.validation.js 源代码检查以确保它只响应该表单元素的事件)。

    需要注意的是,client_side_validations 会监听更改事件并跟踪自上次验证尝试以来您的输入是否发生了更改。因此,如果自上次验证以来您的任何字段都没有更改,则不会运行验证。在这种情况下,您也可以手动触发更改。

    所以...开始代码:

       handleAjaxError = function(event, data, status) {
          $("form input").trigger("change");
          $("form").trigger("ajax:beforeSend", { target: this.$("form")[0] });
       };
    

    诚然,这感觉有点 hacky,触发了“ajax:beforeSend”。您也可以直接在表单上调用 isValid 函数,但这需要您传入验证器,而您只能从窗口 DOM 元素中获取:

       formValidationSettings = window[$('form').attr('id')];
       $('form').isValid(formValidationSettings.validators);
    

    选择你的毒药

    如果 handleAjaxError 函数看起来很奇怪,我需要这样做来处理电子邮件唯一性 ajax 验证的竞争条件,其中两个用户尝试同时注册相同的电子邮件。客户端 ajax 验证唯一性通过了两个用户,第一个提交获得成功,第二个获得服务器端验证失败。我希望 ajax 错误处理程序通过重新运行验证来处理失败。

    【讨论】:

    • 我想澄清一件事。似乎结合这两种方法会产生最好的结果。当我尝试仅使用第二种方法来查看是否需要将信息发送到服务器时,它总是返回误报。正如您在 Jimbo 之前所说,我认为这是因为客户端验证会跟踪已更改的元素。因此,在紧随其后使用 isValid 时,触发事件以强制验证似乎也能给出正确的结果。
    【解决方案2】:

    以上答案无效。我已经尝试查看他们的代码并最终找到了答案。

    form_validators = ClientSideValidations.forms[form.attr('id')].validators
    form.isValid(form_validators)
    

    这肯定行得通。

    为时已晚。但对于像我这样的人。这会有所帮助。

    【讨论】:

    • 感谢您的发帖!救了我。
    【解决方案3】:

    对于版本 3.2.7,我添加了一个关于触发所选输入 https://github.com/DavyJonesLocker/client_side_validations/wiki/Manually-trigger-input-validation 验证的 wiki 页面。

    代码如下:

    $input = $('#validated_input')
    $form = $input.closest('form')
    $input.data('changed', true).isValid($form[0].ClientSideValidations.settings.validators)
    

    使用 Rails 4.2.0 应用测试

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-04
      • 1970-01-01
      • 2014-10-22
      相关资源
      最近更新 更多