是否有使用扩展器的knockout.js的蒙面输入插件?

时间:2022-12-03 07:53:51

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?

任何人都知道那里有类似的项目吗?

5 个解决方案

#1


33  

If you wanted to use the excellent Masked Input Plugin in 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.

各种面具等等。这样,您只需将面罩放在数据绑定中,就可以获得很大的灵活性。

#2


6  

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的“placeholder”属性,我拿了你的代码并扩展了一点:

    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绑定以任何一种方式工作。

#3


2  

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

编辑:您可能希望提供掩码作为选项,而不是将其硬编码到USD等

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);
}

http://jsfiddle.net/rTK6G/

http://jsfiddle.net/rTK6G/

#4


2  

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插件。如果没有输入值,我也会擦除我的viewmodel上的属性。

    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" >

#5


0  

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/

我的Binding淘汰赛电话受到网络的启发,我添加了一些托管语言并从不同的事件更新。我也使用这个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

birthDate只是一个可观察的

this.birthDate = ko.observable();

#1


33  

If you wanted to use the excellent Masked Input Plugin in 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.

各种面具等等。这样,您只需将面罩放在数据绑定中,就可以获得很大的灵活性。

#2


6  

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的“placeholder”属性,我拿了你的代码并扩展了一点:

    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绑定以任何一种方式工作。

#3


2  

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

编辑:您可能希望提供掩码作为选项,而不是将其硬编码到USD等

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);
}

http://jsfiddle.net/rTK6G/

http://jsfiddle.net/rTK6G/

#4


2  

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插件。如果没有输入值,我也会擦除我的viewmodel上的属性。

    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" >

#5


0  

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/

我的Binding淘汰赛电话受到网络的启发,我添加了一些托管语言并从不同的事件更新。我也使用这个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

birthDate只是一个可观察的

this.birthDate = ko.observable();