PatternMask
<MudTextField>
can be configured to apply rules to the user input by setting
its Mask
property.
The easiest to use Mask is the PatternMask
which allows you to specify the input structure with
a simple pattern consisting of pre-defined mask characters.
In this example the mask string is "0000 0000 0000 0000"
prompting for blocks of digits and
refusing invalid input. Note how the cursor automatically
jumps over delimiters so you don't have to type them. You can also try pasting the test credit card number 4543474002249996.
Expiration Date:
CVC:
<MudGrid Class="justify-space-between" Style="max-width: 400px;"> <MudItem xs="12"> <MudTextField Mask="@(new PatternMask("0000 0000 0000 0000"))" Label="Credit Card Number" @bind-Value="creditCard" Variant="@Variant.Text" Clearable /> </MudItem> <MudItem xs="4"> <MudTextField Mask="@(new DateMask("MM/YY", 'Y', 'M'))" Label="Expires" @bind-Value="expiration" Variant="@Variant.Text" /> </MudItem> <MudItem xs="4"/> <MudItem xs="4"> <MudTextField Mask="@(new PatternMask("000"))" Label="CVC" @bind-Value="cvc" Variant="@Variant.Text" /> </MudItem> <MudItem xs="12"> Credit Card Number: <b>@creditCard</b><br/> Expiration Date: <b>@expiration</b><br/> CVC: <b>@cvc</b> </MudItem> </MudGrid>
@code { private string creditCard; private string expiration; private string cvc; }
Defining Mask Characters
When you use PatternMask
without setting its MaskChars
property,
you can use the default masking characters a
, 0
and *
.
See their definitions below. But you are not limited to these. You can re-define them or define your own.
Placeholder | Description | Regex |
---|---|---|
a |
Letters, lower- and upper-case, both ASCII and Unicode | \p{L} |
0 |
Digits 0-9 | \d |
* |
Letters (Unicode) or digits | \p{L}|\d |
MaskChars
. It also shows the features Placeholder
which makes the user aware of the input format and CleanDelimiters
which removes delimiters from the resulting Value
. Last but not least the second
mask also transforms all lower-case input into upper-case. You can also try pasting dc12aa309c23 into the field.
<MudGrid Class="justify-space-between" Style="max-width: 800px;"> <MudItem xs="12" sm="6"> <MudTextField Mask="" Label="MAC Address" HelperText="@mask1.Mask" @bind-Value="mac1" Variant="@Variant.Text" Clearable /> </MudItem> <MudItem xs="12" sm="6"> <MudTextField Mask="" Label="MAC with Placeholder" HelperText="@mask2.Mask" @bind-Value="mac2" Variant="@Variant.Text" Clearable /> </MudItem> <MudItem xs="12" sm="6"> MAC Address: <b>@mac1</b> </MudItem> <MudItem xs="12" sm="6"> Cleaned MAC Address: <b>@mac2</b> </MudItem> </MudGrid>
@code { public string mac1, mac2; public PatternMask mask1 = new PatternMask("##:##:##:##:##:##") { MaskChars = new[] { new MaskChar('#', @"[0-9a-fA-F]") } }; public PatternMask mask2 = new PatternMask("XX-XX-XX-XX-XX-XX") { MaskChars = new[] { new MaskChar('X', @"[0-9a-fA-F]") }, Placeholder = '_', CleanDelimiters = true, Transformation = AllUpperCase }; // transform lower-case chars into upper-case chars private static char AllUpperCase(char c) => c.ToString().ToUpperInvariant()[0]; }
MultiMask
MultiMask
is a powerful masking algorithm which can change its pattern depending on partial input.
It uses the same MaskChars
as PatternMask. Check out the example code to see how easy it is to set up.
Example inspired by Cleave.js
@using MudBlazor.Interfaces <MudGrid Class="justify-space-between mb-3 mx-n3" Style="max-width: 800px;"> <MudItem xs="12"> <MudTextField Mask="" Label="Credit Card Number" Style="max-width: 400px;" @bind-Value="cardNumber" Variant="@Variant.Text" Clearable/> </MudItem> <MudItem xs="12"> Credit Card: <b>@cardNumber</b> </MudItem> </MudGrid>
@code { string cardNumber, cardType; MultiMask mask = new MultiMask("0000 0000 0000 0000", new MaskOption("American Express", "0000 000000 00000", @"^(34|37)"), new MaskOption("Diners Club", "0000 000000 0000", @"^(30[0-59])"), new MaskOption("JCB", "0000 0000 0000 0000", @"^(35|2131|1800)"), new MaskOption("VISA", "0000 0000 0000 0000", @"^4"), new MaskOption("MasterCard", "0000 0000 0000 0000", @"^(5[1-5]|2[2-7])"), new MaskOption("Discover", "0000 0000 0000 0000", @"^(6011|65|64[4-9])") ); MaskOption? option = null; Dictionary<string, Variant> variants = new(); MudElement element; protected override void OnInitialized() { base.OnInitialized(); mask.OptionDetected += (o, input) => { option = o; cardType = o == null ? "Unknown" : o.Value.Id; UpdateClasses(); // re-render only MudElement's children (element as IMudStateHasChanged)?.StateHasChanged(); }; UpdateClasses(); } void UpdateClasses() { foreach (var type in new[] { "American Express", "Diners Club", "JCB", "VISA", "MasterCard", "Discover" }) variants[type] = type == cardType ? Variant.Filled : Variant.Outlined; } } @* Note: MudElement is used here to limit the render-update to this html tree *@ <MudElement HtmlTag="div" @ref="element" Style="max-width: 800px;" Class="mud-width-full"> <MudGrid Class="justify-space-between"> <MudItem xs="12" sm="6"> <MudAlert Variant="@variants["American Express"]" NoIcon Dense Class="mb-2"> American Express: starts with 34/37<br/> <pre>34·· ······ ·····</pre> </MudAlert> <MudAlert Variant="@variants["Diners Club"]" NoIcon Dense Class="mb-2"> Diners Club: starts with 300-305/309<br/> <pre>300· ······ ···</pre> </MudAlert> <MudAlert Variant="@variants["JCB"]" NoIcon Dense Class="mb-2"> JCB: starts with 35/2131/1800<br/> <pre>35·· ···· ···· ····</pre> </MudAlert> </MudItem> <MudItem xs="12" sm="6"> <MudAlert Variant="@variants["VISA"]" NoIcon Dense Class="mb-2"> VISA: starts with 4<br/> <pre>4··· ···· ···· ····</pre> </MudAlert> <MudAlert Variant="@variants["MasterCard"]" NoIcon Dense Class="mb-2"> MasterCard: starts with 51-55/22-27<br/> <pre>51·· ···· ···· ····</pre> </MudAlert> <MudAlert Variant="@variants["Discover"]" NoIcon Dense Class="mb-2"> Discover: starts with 6011/65/644-649<br/> <pre>6011 ···· ···· ····</pre> </MudAlert> </MudItem> </MudGrid> <MudText Class="mud-text-secondary" Typo="Typo.body2">Example inspired by Cleave.js</MudText> </MudElement>
DateMask
DateMask
is an auto-correcting calendar-aware date input mask with customizable format. There are some restrictions though.
Day and month must be dual digit blocks like dd
and MM
. The year can either be denoted by
yy
or by yyyy
. The characters for the day, month and year blocks are customizable. You can align
the three blocks in any order and add any delimiters you want or none at all. The day block can be left out. Year and month blocks must be used or yields undefined
results as will multiple usage of a block.
@using System.Globalization <MudGrid Class="justify-space-between" Style="max-width: 800px;"> <MudItem xs="12" sm="6"> <MudTextField Mask="" Label="ISO Date" HelperText="@mask1.Mask" @bind-Value="isoDate" Variant="@Variant.Text" Clearable /> ISO: <b>@isoDate</b> </MudItem> <MudItem xs="12" sm="6"> <MudTextField Mask="" Label="US" HelperText="@mask2.Mask" @bind-Value="usDate" Variant="@Variant.Text" Clearable /> US: <b>@usDate</b> </MudItem> <MudItem xs="12" sm="6"> <MudTextField Mask="" Label="AT" HelperText="@mask3.Mask" @bind-Value="atDate" Variant="@Variant.Text" Clearable /> AT: <b>@atDate</b> </MudItem> <MudItem xs="12" sm="6"> <MudTextField Mask="" Label="Month" HelperText="@mask4.Mask" @bind-Value="monthAndYear" Variant="@Variant.Text" Clearable /> MM/YY: <b>@monthAndYear</b> </MudItem> </MudGrid>
@code { string isoDate, usDate, atDate; string monthAndYear; IMask mask1 = new DateMask("yyyy-MM-dd"); IMask mask2 = new DateMask("MM/dd/yyyy"); IMask mask3 = new DateMask("TT.MM.JJJJ", 'J', 'M', 'T'); IMask mask4 = new DateMask("MM/YY", 'Y', 'M'); }
RegexMask
RegexMask
is very different from the other algorithms, because it does not use mask characters.
Instead it lets you define the allowed input with a single C# regular expression. The advantage of RegexMask is that it
can allow input of variable length. The disadvantage is that it can be applied only in very specific use-cases. The problem
is that the Regex needs to match all incomplete versions of the input value which can be very challenging for non-trivial
use-cases.
The following example restricts user input to digits only on the left and restricts input to Russian postal codes
(first digit between 1 and 6, total of 6 digits) on the right.
<MudGrid Class="justify-space-between" Style="max-width: 800px;"> <MudItem xs="12" sm="6"> <MudTextField Mask="" Label="Only digits (unlimited length)" HelperText="@mask1.Mask" @bind-Value="numbers" Variant="@Variant.Text" Clearable /> </MudItem> <MudItem xs="12" sm="6"> <MudTextField Mask="" Label="Russian postal code" HelperText="@mask2.Mask" @bind-Value="russianZip" Variant="@Variant.Text" Clearable /> </MudItem> <MudItem xs="12" sm="6"> Number: <b>@numbers</b> </MudItem> <MudItem xs="12" sm="6"> Russian ZIP: <b>@russianZip</b> </MudItem> </MudGrid>
@code { public string numbers, russianZip; public IMask mask1 = new RegexMask(@"^\d+$"); public IMask mask2 = new RegexMask(@"^[1-6]\d{0,5}$"); }
RegexMask.IPv4
RegexMask.IPv4()
is a predefined RegexMask
for an IPv4 Address with or without port masking.
<MudGrid Class="justify-space-between" Style="max-width: 800px;"> <MudItem xs="12" sm="6"> <MudTextField Mask="" Label="IPv4 Address" HelperText="@ipv4Mask.Mask" @bind-Value="ip" Variant="@Variant.Text" Clearable /> </MudItem> <MudItem xs="12" sm="6"> <MudTextField Mask="" Label="IPv4 Address with Port" HelperText="@ipv4PortMask.Mask" @bind-Value="ipPort" Variant="@Variant.Text" Clearable /> </MudItem> <MudItem xs="12" sm="6"> IPv4: <b>@ip</b> </MudItem> <MudItem xs="12" sm="6"> IPv4 w/Port: <b>@ipPort</b> </MudItem> </MudGrid>
@code { public string ip; public string ipPort; public IMask ipv4Mask = RegexMask.IPv4(); public IMask ipv4PortMask = RegexMask.IPv4(true); }
RegexMask.IPv6
RegexMask.IPv6()
is a predefined RegexMask
for an IPv6 Address with or without port masking.
<MudGrid Class="justify-space-between" Style="max-width: 800px;"> <MudItem xs="12" sm="6"> <MudTextField Mask="" Label="IPv6 Address" HelperText="@ipv6Mask.Mask" @bind-Value="ip" Variant="@Variant.Text" Clearable /> </MudItem> <MudItem xs="12" sm="6"> <MudTextField Mask="" Label="IPv6 Address with Port" HelperText="@ipv6PortMask.Mask" @bind-Value="ipPort" Variant="@Variant.Text" Clearable /> </MudItem> <MudItem xs="12" sm="6"> IPv4: <b>@ip</b> </MudItem> <MudItem xs="12" sm="6"> IPv4 w/Port: <b>@ipPort</b> </MudItem> </MudGrid>
@code { public string ip; public string ipPort; public IMask ipv6Mask = RegexMask.IPv6(); public IMask ipv6PortMask = RegexMask.IPv6(true); }
RegexMask.Email
RegexMask.Email()
is a predefined RegexMask
for an Email Address.
<MudGrid Class="justify-space-between" Style="max-width: 800px;"> <MudItem xs="12" sm="6"> <MudTextField Mask="" Label="Email Address" HelperText="@emailMask.Mask" @bind-Value="email" Variant="@Variant.Text" Clearable /> </MudItem> <MudItem xs="12" sm="6"> <MudTextField Mask="" Label="Email Address with Custom Mask" HelperText="@emailCustomMask.Mask" @bind-Value="email2" Variant="@Variant.Text" Clearable /> </MudItem> <MudItem xs="12" sm="6"> Email 1: <b>@email</b> </MudItem> <MudItem xs="12" sm="6"> Email 2: <b>@email2</b> </MudItem> </MudGrid>
@code { public string email; public string email2; public IMask emailMask = RegexMask.Email(); public IMask emailCustomMask = RegexMask.Email("<user>@<domain.com>"); }
BlockMask
BlockMask
can match blocks of uniform patterns with a variable length (min, max) with delimiters in between.
In this example we show a BlockMask that matches all of the following flight numbers LH4234, RUS1727, OS1 and H028.
<MudGrid Class="justify-space-between" Style="max-width: 400px;"> <MudItem xs="12"> <MudTextField Mask="" Label="Flight number" @bind-Value="text" Variant="@Variant.Outlined" Clearable /> </MudItem> <MudItem xs="12"> Flight number: <b>@text</b> </MudItem> </MudGrid>
@code { public string text { get; set; } IMask mask = new BlockMask(delimiters:" ", new Block('a', 1,3), new Block('0', 1,4)); }
Implement your own Mask
To write your own custom mask either derive your own from one of our masking algorithms or implement the
interface IMask
.