通过javascript更改值时元素不更新错误状态

时间:2017-05-30 15:14:03

标签: javascript jquery asp.net-mvc knockout.js

我有一个页面有一些淘汰,我正在尝试实现验证。我有一个输入,我允许用户改变这样的下拉:

<div class="col-md-6 form-group has-feedback" data-bind="css: { 'has-error': Term.hasError }">
    <label for="ddlTerm" class="col-form-label" style="padding: 0;">Term</label>
    <div class="input-group input-group-sm">
        <input type="text" data-bind="textInput: Term" class="form-control input-sm" id="tbTerm" />
        <div class="input-group-btn">
            <button type="button" class="btn btn-warning dropdown-toggle" data-toggle="dropdown">Select <span class="caret"></span></button>
            <ul class="dropdown-menu pull-right">
                <li><a href="javascript:set_Term(12)">12 Months</a></li>
                <li><a href="javascript:set_Term(24)">24 Months</a></li>
                <li><a href="javascript:set_Term(36)">36 Months</a></li>
                <li><a href="javascript:set_Term(48)">48 Months</a></li>
                <li><a href="javascript:set_Term(60)">60 Months</a></li>
                <li><a href="javascript:set_Term(72)">72 Months</a></li>
                <li><a href="javascript:set_Term(84)">84 Months</a></li>
            </ul>
        </div>
    </div>
    <span data-bind='visible: Term.hasError, text: Term.validationMessage' class="help-block"></span>
</div>

JavaScript函数:

function set_Term(months) {
    var termInput = document.getElementById("tbTerm");
    termInput.value = months;           
};

该值与:

相关联
self.Term = ko.observable('').extend({ required: 'Term is required' });

当值更改时,observable会更新,但错误状态保持不变,输入保持红色,反馈仍然可见。有没有办法强制输入意识到它的值已被更改,它应该清除错误?

我试图给出元素focus(),但这不起作用。

我发现的唯一一件事就是给出包含div和验证消息id,然后在JS函数中执行此操作:

  $('#tbTermDiv').removeClass('has-error');
  $('#tbTermNote').addClass('hidden');

在视觉上可以做到这一点 - 错误消息消失了,文本框失去了红色,但如果用户再次清空该框,则红色会回来,但消息仍然隐藏...所以不是最好的解决方案。

我会对任何解决方案感到满意:淘汰赛,jQuery,纯JS。

编辑:我注意到这不会更新observable,所以当我通过value属性更改输入时,它不会更新observable。

1 个答案:

答案 0 :(得分:1)

扩展器的工作原理与普通作品相同。它只知道对视图模型上的可观察对象所做的更改。使用jquery在UI上更新控件的值不会更新基础视图模型,因此任何相关的淘汰代码都不知道要更新。

您可以将set_term函数更改为视图模型上的函数,并让它更新基础observable而不是控件。然后使用数据绑定来调用函数而不是原始js。

  self.set_Term = function(months) {
      self.Term(months);
  };

...

  <li><a data-bind="click: function(){set_Term(84)}">84 Months</a></li>

以下是更新的示例:https://jsfiddle.net/jlspake/8ob0gj6q/3/