3

I'm trying to create a directive to create custom mask for my input. I know there are other libraries I could use, but sometimes I need a custom input based on the company needs, (e.g. "OS.012-08765"), so I'd rather create my own directive.

So far I was able to format the number on the pattern I need, but not on the input, only on the model. For this example I'll be using a money input, because it's simpler to work with (I think). This is the code I'm using:

function myMoney() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attr, ngModelCtrl) {
            ngModelCtrl.$formatters.push( formatInput );
            ngModelCtrl.$render = renderViewValue;
            ngModelCtrl.$parsers.push( parseOutput );


            function formatInput( value ) {
                value = formatNumber(value);
                return value;
            }
            function parseOutput( value ) {
                value = formatNumber(value);
                return value;
            }
            function renderViewValue() {
                element.html( ngModelCtrl.$viewValue );
            }

            function formatNumber(value) {
                if(!value) {
                    value = '000';
                }

                var checkValue = value.replace(/[^0-9\.]/g, '');
                if(checkValue != value) {
                    value = checkValue;
                }

                value = value.toString();

                if(value.length < 3) {
                    value = ('000'+value).slice(-3);
                }

                var 
                    firstChar = value.slice(0, value.length-2),
                    lastChar  = value.slice(-2),
                    firstChar = Number(firstChar).toLocaleString(),
                    finalChar = '$'+firstChar+','+lastChar;

                return finalChar;
            }
        }
    }
}

And this is a plunkr with the code: http://plnkr.co/edit/UjZkPFL0V4FRrDUL9jAJ?p=preview


The main problem is where the output is, if you start typing on the input, the value doesn't have the mask, is just numbers. But the model has the proper mask.

So, based on this, I have 2 main issues:

  • First: I want to invert these results. I want to type in the textbox and have the mask on the textbox while the model is just plain number (without the mask).
  • Second: If I create a button to update the value on the model, it doesn't get formatted within the mask, it stays plain text.

How can I solve these problems?

2
  • Can't you use <input placeholder="__.___-_____ "> ? So you won't have to worry about replacing "_" with your actual character. Commented Oct 8, 2016 at 22:50
  • But the problem with the placeholder, is that it's not going to fill acording to what user types, which is what I want. Commented Oct 8, 2016 at 22:54

1 Answer 1

5

try to use ui mask, https://htmlpreview.github.io/?https://github.com/angular-ui/ui-mask/master/demo/index.html, enter AA.999-99999 under Mask Definition field to match your pattern.

<input type="text" 
       ng-model="serviceOrderNumber" 
       ui-mask="AA.999-99999"  
       ui-mask-placeholder 
       ui-mask-placeholder-char="_"/>
Sign up to request clarification or add additional context in comments.

8 Comments

Like I said, I know there is libraries I could use, but I want to develop ir myself. Any ideas on how to do it?
I see... If you really want to keep track of your placeholder characters, you will have to compute every cursor position and replace it with your actual character. I will take a lot of time to create an input mask from scratch, though. Good luck!
see github.com/angular-ui/ui-mask/blob/master/dist/mask.js for implementation. you should create directive, require 'ngModel', via link function get access to ngModel controller, rewrite some of its logic ($isEmpty() function, validity logic ...), use ngModelController's $formatters and $parsers to change view and model values of your ngModel
@EdmarMiyake I don't actually need to check where the cursor is, etc.. But for example, as soon as user starts typing, it will start to fill the mask. Just like most of the currency mask work. You start typing and when you have just one number, the output would be "0.01" and after you type more, it would be "149.65"
@Andriy I'm already trying to do a reverse analyses on the code, but if you could elaborate an answer expanding your comment explanation, that would be great. Also, It doesn't need to be a complex mask. As soon as I get to the basics I think I'll be able to proceed.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.