javascript 是否有使用扩展器的 Knockout.js 的屏蔽输入插件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13604103/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there masked input plugin for knockout.js using extenders?
提问by kyrisu
I've seen this post- it shows one possible solution. But I would like to have a more elegant way of doing masked input.
我看过这篇文章- 它显示了一种可能的解决方案。但我想有一种更优雅的方式来进行屏蔽输入。
It should also play nicely with knockout validation plugin (or maybe extending it).
它也应该与淘汰验证插件(或可能扩展它)一起很好地发挥作用。
Anyone know how is there similar project out there?
有人知道那里有类似的项目吗?
回答by Jason Clark
If you wanted to use the excellent Masked Input Pluginin Knockout, it's pretty easy to write a basic custom binding rather than an extender.
如果您想在 Knockout 中使用出色的Masked Input Plugin,编写一个基本的自定义绑定而不是扩展程序非常容易。
ko.bindingHandlers.masked = {
init: function(element, valueAccessor, allBindingsAccessor) {
var mask = allBindingsAccessor().mask || {};
$(element).mask(mask);
ko.utils.registerEventHandler(element, 'focusout', function() {
var observable = valueAccessor();
observable($(element).val());
});
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
$(element).val(value);
}
};
And then in your HTML:
然后在你的 HTML 中:
<input type="text" data-bind="masked: dateValue, mask: '99/99/9999'" />
<input type="text" data-bind="masked: ssnValue, mask: '999-99-9999'" />
And so on with various masks. This way, you can just put the mask right in your databinding, and it allows a ton of flexibility.
等等各种面具。通过这种方式,您可以将掩码放在数据绑定中,并提供很大的灵活性。
回答by hoyt1969
Well done, riceboyler. I took your code and extended it a little in order to use the "placeholder" property of the Masked Input Plugin:
干得好,赖斯博勒。为了使用 Masked Input Plugin 的“占位符”属性,我使用了您的代码并对其进行了一些扩展:
ko.bindingHandlers.masked = {
init: function (element, valueAccessor, allBindingsAccessor) {
var mask = allBindingsAccessor().mask || {};
var placeholder = allBindingsAccessor().placeholder;
if (placeholder) {
$(element).mask(mask, { placeholder: placeholder });
} else {
$(element).mask(mask);
}
ko.utils.registerEventHandler(element, "blur", function () {
var observable = valueAccessor();
observable($(element).val());
});
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
$(element).val(value);
}
};
HTML with placeholder:
带占位符的 HTML:
<input id="DOB" type="text" size="12" maxlength="8" data-bind="masked: BirthDate, mask: '99/99/9999', placeholder: 'mm/dd/yyyy', valueUpdate: 'input'"/>
HTML without placeholder:
没有占位符的 HTML:
<input id="DOB" type="text" size="12" maxlength="8" data-bind="masked: BirthDate, mask: '99/99/9999', valueUpdate: 'input'"/>
The KO binding works either way.
KO 绑定以任何方式工作。
回答by Anders
Just take the code from the answer in that link and put it in a extender (Written on free hand, can have errors)
只需从该链接中的答案中提取代码并将其放入扩展程序中(徒手编写,可能有错误)
ko.extenders.masked = function(observable, options) {
return ko.computed({
read: function() {
return '$' + this.observable().toFixed(2);
},
write: function(value) {
// Strip out unwanted characters, parse as float, then write the raw data back to the underlying observable
value = parseFloat(value.replace( /[^\.\d]/g , ""));
observable(isNaN(value) ? 0 : value); // Write to underlying storage
}
});
};
edit: You probably want to supply the mask as a options instead of having it hardcoded to USD etc
编辑:您可能希望将掩码作为选项提供,而不是将其硬编码为美元等
update:If you want to use the mask plugin from riceboyler's answer but with extenders you can do
更新:如果你想使用 Riceboyler 的回答中的掩码插件,但你可以使用扩展器
ko.extenders.mask = function(observable, mask) {
observable.mask = mask;
return observable;
}
var orgValueInit = ko.bindingHandlers.value.init;
ko.bindingHandlers.value.init = function(element, valueAccessor) {
var mask = valueAccessor().mask;
if(mask) {
$(element).mask(mask);
}
orgValueInit.apply(this, arguments);
}
回答by benk
I tried to use the first answer but it did not work with ko.validation plug in. My validation errors were not being displayed.
我尝试使用第一个答案,但它不适用于 ko.validation 插件。没有显示我的验证错误。
I wanted to have little bit more intuitive ko binder. Here is my solution. I am using jquery.inputmask plug in. I also wipe out the property on my viewmodel if not value entered.
我想要更直观的 ko 活页夹。这是我的解决方案。我正在使用 jquery.inputmask 插件。如果没有输入值,我也会清除视图模型上的属性。
ko.bindingHandlers.mask = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var mask = valueAccessor() || {};
$(element).inputmask({ "mask": mask, 'autoUnmask': false });
ko.utils.registerEventHandler(element, 'focusout', function () {
var value = $(element).inputmask('unmaskedvalue');
if (!value) {
viewModel[$(element).attr("id")]("");
}
});
}
};
Here is the usage:
这是用法:
<input type="text" data-bind="value: FEIN, mask: '99-9999999'" id="FEIN" >
回答by Yvan
You can use this homemade solution, work perfectly for me:
您可以使用这个自制的解决方案,非常适合我:
My Binding knockout call masked inspired from the net, i added some managed language and update from different event. Also I use this js library for using basically : https://plugins.jquery.com/maskedinput/
我的绑定淘汰赛电话受到网络的启发,我添加了一些托管语言并从不同的事件更新。我也使用这个 js 库基本上使用:https: //plugins.jquery.com/maskedinput/
You can see in my binding the term "allBindingsAccessor().mask" this is from the library maskedinput
您可以在我的绑定中看到术语“allBindingsAccessor().mask”,这是来自库 maskedinput
ko.bindingHandlers.masked = {
init: function (element, valueAccessor, allBindingsAccessor) {
var mask = allBindingsAccessor().mask || {},
getCaretPosition,
setCaretPosition;
// Permet d'obtenir la position du curseur
getCaretPosition = function getCaretPosition(element) {
// Initialise la position
var caretPos = 0, sel;
// IE
if (document.selection) {
// Donne le focus à l'élément
element.focus();
// Afin d'obtenir la position du curseur
sel = document.selection.createRange();
// On place le curseur à 0
sel.moveStart('character', -element.value.length);
caretPos = sel.text.length;
}
// Firefox
else if (element.selectionStart || element.selectionStart === '0') {
caretPos = element.selectionStart;
}
return (caretPos);
};
// Permet de définir la position du curseur en fonction d'une position donnée
setCaretPosition = function setCaretPosition(element, pos) {
var range;
if (element.setSelectionRange) {
element.focus();
element.setSelectionRange(pos, pos);
}
else if (element.createTextRange) {
range = element.createTextRange();
range.collapse(true);
range.moveEnd('character', pos);
range.moveStart('character', pos);
range.select();
}
};
// Définition du masque inséré dans le champ
if (configSvc.culture === "fr-FR") {
// Cas francais
$(element).mask("99/99/9999", { placeholder: "JJ/MM/AAAA" });
}
else {
// Cas anglophone
$(element).mask("99/99/9999", { placeholder: "MM/DD/YYYY" });
}
// On capte l'événement d'appuie sur une touche
ko.utils.registerEventHandler(element, 'keypress', function () {
var observable = valueAccessor(),
position;
// Afin de résoudre le pb de déplacement du curseur a la fin du mask lors de la mise à jour de l'observable knockout
if ($(element).val().length === 10) {
// On récupère la dernière position
position = getCaretPosition(this);
// On met à jour la valeur de l'obersable (en cas de sauvegarde)
observable($(element).val());
// On force la position du curseur apres mise à jour de l'observable à la derniere position récupéré
setCaretPosition(this, position);
}
});
// On capte l'événement de perte de focus pour mettre l'obersable à jour
ko.utils.registerEventHandler(element, 'blur', function () {
var observable = valueAccessor();
observable($(element).val());
});
// On capte l'événement change pour mettre l'obersable à jour
ko.utils.registerEventHandler(element, 'change', function () {
var observable = valueAccessor();
observable($(element).val());
});
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
$(element).val(value);
}
};
in my html page, i use this observable "masked" :
在我的 html 页面中,我使用了这个可观察的“屏蔽”:
<input type="text" id="head-birthDate" class="form-control" data-bind="masked: birthDate" />
Finally in my js :
最后在我的 js 中:
birthDate is just an observable
出生日期只是一个可观察的
this.birthDate = ko.observable();