【问题标题】:Adding validation to knockout为淘汰赛添加验证
【发布时间】:2015-06-05 08:46:33
【问题描述】:

我正在尝试使用 jquery 验证。我正在通过 ajax 加载项目列表,加载我的淘汰赛模型。我想将验证绑定到这些项目。问题是验证消息仅显示在第一个输入框中。我做错了什么?

$(document).ready(function () {
        var viewModel = new ViewModel();
        viewModel.load();
        ko.applyBindings(viewModel);

        $('#list').validate();
});

然后在我的 viewModel 中:

    self.load = function (selected) {
        $.ajax({
            type: "POST",
            url: myUrl,
            data: ko.toJSON({ type: self.url(), customerNumbers: selected }),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            beforeSend: function () {
                $(".demo-tbl").block({ message: "Loading..." });
            },
            complete: function () {
                $(".demo-tbl").unblock();
                // COMMENTED OUT $("input.percent-text").valid(); // validator
            },
            success: function (data) {
                ko.mapping.fromJS(data, {}, self);
            },
            error: function (err) {
                alert(err.status + " - " + err.statusText);
            }
        });
    };

呈现的 HTML:

                           <form id="list">
                            <table class="demo-tbl" data-bind='visible: List().length > 0'>
                                <thead>
                                </thead>


<tbody data-bind="foreach: List">
    <tr class="tbl-item" data-bind="css: HasDiscount">
        <td>
            <dl>
                <dt class="like" data-bind="text: CustomerName"></dt>
                <dd>Customer Number: <span data-bind="text: CustomerNumber"></span></dd>
            </dl>
        </td>
        <td>
            <span class="label label-sm label-warning" data-bind="css: HasDiscount, text: $root.DiscountListType"></span>
        </td>
        <td>
            <dl>
                <dt class="like">Activation Date:</dt>
                <dd data-bind="text: moment(ActivationDate()).format('LLL')"></dd>
            </dl>
        </td>
        <!-- ko if: $parent.DiscountListType() == "DiscountOverwrite" -->
        <td class="action">
            <input class="required number percent-text" name="percent" data-bind="numeric: Percent, value: Percent, event: { keypress: $root.update, blur: $root.update }" type="number" min="1" max="100" oninput="maxlength(this)" maxlength="3" />
        </td>
        <!-- /ko -->
        <td class="checkbox-cell">
            <button class="btn action" type="button" data-bind="click: $root.action, css: HasDiscount"></button>
        </td>
    </tr>
</tbody>

                            </table>
                        </form>

编辑 1:

...
              complete: function () {
                    $(".demo-tbl").unblock();
                    $('#list').validate();
                },
...
$(document).ready(function () {
    if ($(".demo-tbl").length > 0) {
        var viewModel = new ViewModel();
        viewModel.load();
        ko.applyBindings(viewModel);
    }
});

【问题讨论】:

  • 我在您的 HTML 中没有看到 &lt;form&gt;&lt;/form&gt; 容器。也请只显示在浏览器中看到的 rendered HTML。
  • 添加了呈现的 html。就像我说我正在加载页面,通过 ajax 获取列表。验证有效,但 validate 插件生成的 仅针对列表中的第一项生成。因此,如果第二行有问题,错误消息会显示在第一行而不是第二行旁边。

标签: knockout.js jquery-validate knockout-mapping-plugin


【解决方案1】:

“问题是验证消息只显示在第一个输入框中。我做错了什么?”

根据您显示的代码,jQuery Validate 根本不应该工作。

您只能将.validate() 方法附加到form,而不能附加到输入元素。

$(document).ready(function() {

    $('#list').validate(); // initialize plugin on your form

});

注意:name 属性是插件跟踪字段的方式,因此重复名称将导致类似于您描述的某些元素被跳过的位置。我以为我在您的 HTML 的第一个版本中看到了重复的 name


您不能将.validate() 方法附加到尚不存在的form 元素。如果您的ajax() 正在为form 加载HTML,则在成功加载表单的HTML 后立即调用.validate()

您注释掉对.validate() 的调用的同一个地方,只是这次它附加到form,而不是输入元素。

self.load = function (selected) {
    $.ajax({
        ....
        complete: function () {
            $(".demo-tbl").unblock();
            $('#list').validate(); // initialize validate plugin
        },
        ....
    });
};

编辑 2:

在上面强调我原来的“注释”。您必须重复name 属性,否则插件将失败。没有解决方法。您必须确保每个输入都包含一个唯一 name

name="percent[1]"
name="percent[2]"
name="percent[3]"
....

【讨论】:

  • 我已将此添加到 jquery 文档中,但错误仍然只显示在第一个输入旁边。请参阅上面的更新代码
  • @ShaneKm,看看我的编辑。加载 HTML 后立即调用 .validate()form 必须存在才能初始化插件。
  • 我做到了。请参阅 EDIT1。现在验证消息仅显示在第二行
  • @ShaneKm,这是一个不同的问题。请参阅我原始答案中的“注释”:name 属性是插件跟踪字段的方式,因此重复名称将导致您描述某些元素被跳过的位置。我想我看到了name 在您的 HTML 的第一个版本中重复。"
猜你喜欢
  • 2018-03-12
  • 2012-02-18
  • 2011-08-09
  • 2012-11-04
  • 1970-01-01
  • 2017-01-27
  • 1970-01-01
  • 2012-12-05
  • 2012-03-08
相关资源
最近更新 更多