我的应用程序所有者希望选择的文本字段为大写,就像大写锁定已打开一样。我正在使用具有这些字段的observable的KnockoutJS视图模型。有没有办法可以将任何用户输入的文本转换为大写?
我在我想要更改的控件上放了一个input
事件,但发现尽管它有效,但是observables没有更新。
<input type="text" maxlength="80" data-bind="value: colorName, disable: $parent.isReadOnly, event: { 'input': toUpper }" />
toUpper: function (d, e) {
if (e.target) {
if (e.target.value) {
e.target.value = e.target.value.toUpperCase();
}
}
}
我一直在考虑将ucase
CSS类放在我希望成为大写的控件上,然后在客户端或服务器上,将这些字段保存为大写。
.ucase {
text-transform: uppercase;
}
答案 0 :(得分:9)
你可以扩展你的观察力 -
<input data-bind="value: colorName, valueUpdate:'afterkeydown'" />
ko.extenders.uppercase = function(target, option) {
target.subscribe(function(newValue) {
target(newValue.toUpperCase());
});
return target;
};
var colorName = ko.observable().extend({ uppercase: true });
小提琴示例 - http://jsfiddle.net/kbFwK/
基本上每当值发生变化时,它都会将observable的值转换为大写。
这里的缺点是它实际上会更改值并以这种方式存储它。您可以始终将计算属性添加到observable上,仅用于显示目的。您可以使用ko.computed,自定义绑定处理程序(因为它仅用于演示)或类似的东西来实现。如果这更符合您的要求,请通过评论告诉我。
修改强>
更新了afterkeydown - http://jsfiddle.net/kbFwK/2/
答案 1 :(得分:1)
这是我编写的自定义绑定,可确保输入字段和可观察字段均为大写。它应该像textInput绑定一样工作。
ko.bindingHandlers.textInputUpperCase = {
init: (element, valueAccessor) => {
const observable = valueAccessor();
let preventDoubleUpdate = false;
function update(newValue) {
if (preventDoubleUpdate) {
preventDoubleUpdate = false;
} else {
switch(typeof newValue) {
//Undefined value will be displayed as empty in the input field.
case 'undefined':
element.value = '';
break;
//String value will be converted to upper case.
case 'string':
const upperCase = newValue.toLocaleUpperCase();
//Check if input field matches the observable. If not the change was made directly to the observable.
const match = element.value.toLocaleUpperCase() === upperCase;
//Remember the cursor position.
const selectionStart = element.selectionStart;
const selectionEnd = element.selectionEnd;
//Update the input text (will move the cursor to the end of the text).
element.value = upperCase;
//Move the cursor to it's original position if the change came from the input field.
if (match) {
element.selectionStart = selectionStart;
element.selectionEnd = selectionEnd;
}
//Update the observable if necessary and make sure it won't do a double update.
if (newValue !== upperCase) {
preventDoubleUpdate = true;
observable(upperCase);
}
break;
default:
element.value = newValue;
}
}
}
//Run the update function each time the observable has been changed
observable.subscribe(update);
//Initiate the observable and input
update(observable());
//Update the observable on changes of the text in the input field
element.addEventListener('input', event => {
observable(event.target.value);
});
}
};
一个小警告。如果您写给观察者,它将两次通知其他订户。首先,当您写入它时,然后当它变成大写时。