Components: feat(input): add (limited) support for text masking

Created on 9 Oct 2017  路  10Comments  路  Source: angular/components

Bug, feature request, or proposal:

How can I set a text mask in date picker component so, if user doesn't want to select a date in calendar, he can type and fill correctly the field?

What is the expected behavior?

When click on input date picker, show the mask so user can type date instead of selecting a date from calendar

What is the current behavior?

empty input

What are the steps to reproduce?

Providing a StackBlitz/Plunker (or similar) is the best way to get the team to see your issue.

Plunker starter (using on @master): https://goo.gl/DlHd6U

StackBlitz starter (using latest npm release): https://goo.gl/wwnhMV

Just add a datepicker component

What is the use-case or motivation for changing an existing behavior?

Maybe user wants to type date instead of selecting form calendar.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

@angular/cli: 1.3.0
node: 6.10.3
os: darwin x64
@angular/animations: 4.3.5
@angular/cdk: 2.0.0-beta.8
@angular/common: 4.3.5
@angular/compiler: 4.3.5
@angular/core: 4.3.5
@angular/flex-layout: 2.0.0-beta.8
@angular/forms: 4.3.5
@angular/http: 4.3.5
@angular/material: 2.0.0-beta.8
@angular/platform-browser: 4.3.5
@angular/platform-browser-dynamic: 4.3.5
@angular/router: 4.3.5
@angular/cli: 1.3.0
@angular/compiler-cli: 4.3.5
@angular/language-service: 4.3.5

Is there anything else we should know?

P3 materiainput feature

Most helpful comment

Hi @WandersonAlves
I can see 2 ways to do that, the first one would be to use the date pipe in the text-mask-addons lib, but you'll likely have to create a custom pipe for some mask formats.
The second way would be to do it on the angular side, catching when the input value changes and then doing a check. Not really clean I think because then the input validation is half vanilla, half angular... but as a workaround that would work.
Good luck and please let me know what you go for :)

All 10 comments

a) material doesn't provide mask behavior
b) it's currently impossible to open datepicker with focus, while keeping focus on the input (because of how Overlay works)

Hey @fxck ! Thanks for the answer!
Well... there's no need to keep focus on text input wile calendar is open! If user click on input, just show the mask. If user clicks on button, hide mask and show calendar! Is that possible?

Yes, but as I said, material doesn't provide that functionality, you can use something like https://github.com/text-mask/text-mask

As mentioned above, text-mask won't work with material2. This is because angular doesn't allow input fields to have more than 1 ValueAcessor.

A work around is to use the vanilla version of text-mask:
1 - Import the library in your component
import * as textMask from "vanilla-text-mask/dist/vanillaTextMask.js";

2 - Add your mask in the component and init your input (don't forget to import AfterViewInit and implement it to your component)
```
mask = [ /[1-9]/, /\d/, /\d/];
maskedInputController;

@ViewChild("input", { read: ViewContainerRef }) public input;

ngAfterViewInit(): void {
setTimeout(() => {
this.maskedInputController = textMask.maskInput({
inputElement: this.input.element.nativeElement,
mask: this.mask
});
});
}

ngOnDestroy() {
this.maskedInputController.destroy();
}

3 - in your template, make sure the input element has an #input attribute





```

I @remborg ! I was trying to set a mask like 'dd/mm/yyyy' and validate things like day 32 or month 13. I can't figure out how to do that using vanilla-text-mask, do you know if is possible?

Thanks!

Hi @WandersonAlves
I can see 2 ways to do that, the first one would be to use the date pipe in the text-mask-addons lib, but you'll likely have to create a custom pipe for some mask formats.
The second way would be to do it on the angular side, catching when the input value changes and then doing a check. Not really clean I think because then the input validation is half vanilla, half angular... but as a workaround that would work.
Good luck and please let me know what you go for :)

+1 would like a way to add masking that inserts slashes

Upping the priority of this as we'll need to add at least limited masking support to allow for prefix and suffix text now that we're only recommending matPrefix and matSuffix for icons (or other centered content) .

See related discussion on #9488

We were able to get a mask directive working with Material inputs using the text-mask library mentioned above. You can see the code here if it's helpful (at least until an official solution is offered).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dzrust picture dzrust  路  3Comments

crutchcorn picture crutchcorn  路  3Comments

theunreal picture theunreal  路  3Comments

michaelb-01 picture michaelb-01  路  3Comments

LoganDupont picture LoganDupont  路  3Comments