使用 knockout.js 在 HTML 中使用禁用元素保持 Tab 键顺序

Keeping tab order in HTML with disabled elements using knockout.js

请看一下这个简单的例子:http://jsfiddle.net/wassimmansour/9v8nbqww/。在输入 "Optional Data" 中输入内容,然后按 Tab 键。

var ViewModel = function (opt, dep, oth) {
    this.optionalData = ko.observable(opt);
    this.dependantData = ko.observable(dep);
    this.otherData = ko.observable(oth);

    this.optionalDataPresent = ko.pureComputed(function () {
        return this.optionalData().trim() !== '';
    }, this);
};

ko.applyBindings(new ViewModel("", "", "123")); 

我需要能够在 "Optional Data" 为空时跳转并跳过 "Dependent Data" 输入字段。但是,如果 "Optional Data" 不为空,则 Tab 键顺序必须先跳转到 "Dependent Data",然后才能继续输入其余内容。

现在发生的情况是 "Dependent Data" 获取仅在选项卡跳过它后才启用,这不是预期的或直观的流程。

这个问题有什么解决办法吗?


编辑

"optional data" 字段实际上必须格式化为“1,234.56”或“1,234.00”。我为此使用的代码是:

<input data-bind="masked: optionalData, mask: 'N2'" />

ko.bindingHandlers.masked = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var mask = allBindingsAccessor().mask || 'N2';
        var val = $(element).val();
        if (val || val == 0) {
            val = parseFloat((val + '').replace(/,/g, ''));
            if (!isNaN(val)) $(element).val(val.format(mask));
            else $(element).val('');
        }

        ko.utils.registerEventHandler(element, 'focusout', function () {
            var observable = valueAccessor();
            observable($(element).val());
        });
    },
    update: function (element, valueAccessor, allBindingsAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        var mask = allBindingsAccessor().mask || 'N2';
        var val = value;
        if (val || val == 0) {
            val = parseFloat((val + '').replace(/,/g, ''));
            if (!isNaN(val)) {
                $(element).val(val.format(mask));
                return;
            }
        }
        $(element).val(value);
    }
};

我更新了 http://jsfiddle.net/wassimmansour/9v8nbqww/7/ 上的代码,但它似乎 运行 不正确。

我测试了'valueUpdate'解决方案,但它似乎与用于格式化的'update'函数冲突。一旦按下一个键,输入的值就会更新并应用格式化功能,这意味着每次按键后都会应用格式化。这使得无法输入数据(如果您键入“1”,输入会立即更新为“1.00”,然后您必须手动将光标移回 1 之后,然后按 2,然后输入也会被格式化并显示“ 12.00').

谢谢。

这是更新代码:jsfiddle。我建议在第一个字段上使用 valueUpdate: "keyup"

<div class='liveExample'>Optional Data
    <br/>
    <input data-bind='value: optionalData, valueUpdate: "keyup"' />
    <br/>Dependent Data
    <br/>
    <input data-bind='value: dependantData, attr {disabled: !optionalDataPresent()}' />
    <br />Other Data
    <br/>
    <input data-bind='value: otherData' />
</div>