Search code examples
knockout.jsknockout-validationknockout-kendo

Formatting a number in a TextBox onBlur and onLoad ? using Knockout


I have a view with text-box of type Number and i am successfully validating whether i'm entering numeric's or not like that using knockout validation plugin

But here comes a situation where i need to format my entered numbers with a comma for every four digits onBlur (millions formats) .

I have no clue how to proceed with this implementation but i just had couple of thoughts but no idea how to make it into picture (better ideas are appreciated)

Here is my FIDDLE

Requirement : I will explain my scenario based on this number 1234567890

  1. onLoad i need to show the number in my textbox as 12,3456,7890

  2. If user wants to modify the number means when he clicks inside the text-box the number should become 1234567890 so he can modify it (onblur sort of).

  3. After modifying if user clicks outside the text-box means the number should become comma separated to view .

  4. Finally i have validation to check whether is it number or not . #so it should accept numbers with comma .

I thought something like this :

1)i use computed to format and return it

2)no clue on this but gave a thought to subscribe

3)same subscribe

4) custom validation separating commas in a number and validating i.e may be regex expression .

Is it even possible in knockout or not i have my doubts but fingers crossed i hope everything has some way .

Interestingly i found knockout-kendo which does the work what i'm looking for but i prefer to implement the same functionality in knockout rather using some other plugin which cause issue in some point of time .

Any ideas are crazy enough for me to run .


Solution

  • You can create two inputs:

    • Input 1 is readonly & visible by default and contains the formatted value.
    • When Input 1 is clicked, hide it, show and focus Input 2 with the real value that can be edited.
    • When Input 2 is 'blurred', hide it and show input 1 with the formatted value.

    Html:

    <div>
        <input type="text" readonly data-bind="value: valFormatted, 
                                               visible: !editMode(),
                                               click: toggleEdit" />
        <input type="text" data-bind="value: val, 
                                      visible: editMode, 
                                      hasFocus: editMode,
                                      event: { blur: toggleEdit}" />
    </div>
    

    JS:

    window.onload = function() {
        var vm = {
            val: ko.observable(),
            valFormatted: ko.computed({
                read: function() {
                    // number format
                    return (vm.val() || '') + '[formatted]';
                },
                deferEvaluation: true
            }),
            editMode: ko.observable(false),
            toggleEdit: function() {
                vm.editMode(!vm.editMode());
            }
        };
    
        ko.applyBindings(vm);
    };
    

    window.onload = function() {
    	var vm = {
    		val: ko.observable(),
    		valFormatted: ko.computed({
    			read: function() {
    				// number format
    				return (vm.val() || '') + '[formatted]';
    			},
    			deferEvaluation: true
    		}),
    		editMode: ko.observable(false),
    		toggleEdit: function() {
    			vm.editMode(!vm.editMode());
    		}
    	};
    
    	ko.applyBindings(vm);
    };
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    <div>
    <input type="text" data-bind="value: valFormatted, visible: !editMode(), click: toggleEdit" readonly />
    <input type="text" data-bind="value: val, visible: editMode, hasFocus: editMode, event: { blur: toggleEdit}" />
    </div>