Bind to ui-mask?
I have no problem using ui-mask="999999", but when I try to bind that value the mask does not appear: ui-mask="vm.myMask"
Should this work?
Binding a variable to the ui-mask attribute requires it to be surrounded by {{ }}.
i.e. ui-mask={{vm.myMask}}
Thanks. While that works, it doesn't seem that it will pick up a placeholder bound the same way:
<input ng-mask="{{ vm.myMask }}" placeholder="{{ vm.myPlaceholder }}" ui-mask-placeholder />
When trying that, I just get the mask underscores, not the placeholder I expect.
Not sure what's wrong with the placeholder as that is exactly how the tests are operating and those are passing. Do you have the latest version and/or can you create a plunk that shows the issue?
Yes, I recreated the issue here: http://plnkr.co/edit/kL6tOBeBmRD52k1uiw5z?p=preview
I'm getting both the mask and placeholder from an API call and while the mask is updated, the placeholder is not.
I'm guessing there is something wrong with the observer as 'initing' the value of the placeholder works.
Part of the problem is that you have a ui-mask-placeholder attribute and a placeholder attribute and those do not function properly together.
However, there appears to be another issue even after you remove the ui-mask-placeholder attribute which I'm not sure why the unit tests aren't catching that problem. I will have to look into that sometime soon.
Are you sure I don't want both ui-mask-placeholder and placeholder? That's exactly what the demo page uses and I don't think it worked without ui-mask-placeholder:
https://github.com/angular-ui/ui-mask/blob/master/demo/index.html#L35
Also, I discovered that if I have a dummy placeholder before the API call the placeholder will properly update: http://plnkr.co/edit/4T5iciN6ggRLDxmQp2Yc?p=info
The demo page might have it wrong and could possibly need to be updated. All I know is that from looking at the code if you have both ui-mask-placeholder and placeholder only one of them will be observed using iAttrs.$observe and the ui-mask-placeholder attribute wins that contest. Lines of code I'm referencing.
if (angular.isDefined(iAttrs.uiMaskPlaceholder)) {
iAttrs.$observe('uiMaskPlaceholder', initPlaceholder);
}
else {
iAttrs.$observe('placeholder', initPlaceholder);
}
https://github.com/angular-ui/ui-mask/blob/master/src/mask.js#L182
In either case, there seems to be an issue with the placeholder attribute that needs to be dug into. Yay...
That's also what i thought, but why would it work when a dummy placeholder is put before loading the API call?
My best guess is that the initPlaceholder function doesn't handle null or undefined properly and so it ends up in a mixed state of thinking there is a placeholder and not a placeholder at the same time; but that is just a guess
So, I've discovered the problem (still working on a potential solution). The problem stems from having the mask and the placeholder "resolve" simultaneously like in your original plunk. When they both change in the same $digest loop the initPlaceholder function runs before the processMask function which is causing the funky placeholder issue because processMask overwrites the maskPlaceholder set in the initPlaceholder function.
The reason the placeholder ends up so funky is that the processMask function gets the placeholder characters to use in the mask based off the corresponding character position in the placeholder attribute.
The solution for now would be to make sure the mask and placeholder variables aren't updated at the same time so they won't trigger their watch functions in the same digest loop.
There appears to be a lot more to this issue then I first thought after looking through some of the old issues. #4 talks about this being a long standing issue where the placeholder probably doesn't do what it should. This led to the ui-mask-placeholder attribute being added which further complicates things. Maybe I will get some time soon to dig into the original problem and come up with a good solution.