Masked InputField on Unity UI

I am making a player registration menu in a game using data such as: Name, Email, Password, Gender, Date of Birth and Phone Number.

The problem is when I add the UI InputField for the Date of Birth and Phone Number, I would need to apply a formatting mask such as “##/ ##/####” for the Date and “(##) #####-####” for the Phone.

I can limit the InputField to typing just numbers, however I did not find any way to add formatted masks or to create a component akin to C#'s MaskedTextBox. Is it possible to do something similar to this in Unity?

Example of MaskedTextBox:
85377-maskedtextbox.jpg

Hi @IntrudeN313, i had a similar problem with Dates. Maybe this code can help you

private char OnValidateInput(string text, int charIndex, char addedChar)
{
    if (addedChar == '/')
        return addedChar;
    if (!char.IsNumber(addedChar))
        return '\0';

    //I Want date format like (dd/mm/yyyy)
    switch(text.Length)
    {
        case 2: //User typed 'dd'
            DataInicial.text = text + "/";
            DataInicial.caretPosition = DataInicial.text.Length;
            break;

        case 5: //User typed 'dd/mm'
            DataInicial.text = text + "/";
            DataInicial.caretPosition = DataInicial.text.Length;
            break;
    }
    return addedChar;
}

public class PhoneInputMask : MonoBehaviour
{
public InputField inputField;

    private void OnValidate()
    {
        inputField = GetComponent<InputField>();
    }

    public void Start()
    {
        inputField.onValueChanged.AddListener(delegate { OnValueChangeEvent(); });
    }

    // Invoked when the value of the text field changes.
    public void OnValueChangeEvent()
    {
        if (string.IsNullOrEmpty(inputField.text))
        {
            inputField.text = string.Empty;
        }
        else
        {
            string input = inputField.text;
            string MatchPattern = @"^((\d{2}\.){0,4}(\d{1,2})?)$";
            string ReplacementPattern = "$1.$3";
            string ToReplacePattern = @"((\.?\d{2})+)(\d)";

            input = Regex.Replace(input, ToReplacePattern, ReplacementPattern);
            Match result = Regex.Match(input, MatchPattern);
            if (result.Success)
            {
                inputField.text = input;
                inputField.caretPosition++;
            }
        }
    }
}

###UPDATED ANSWER

public void OnValueChanged(string input) // Supposing input = "953"
{
    int index = 0 ;
    string format = "##/##/####" ;
    string output = format;
    
    for( int i = 0 ; i < input.Length ; ++i )
    {
        index = output.IndexOf("#");
        if( index < 0 )
            break ;
        if( index == 0 )
            output = input *+ output.Substring ( 1 );*

else if( index == output.Length - 1 )
output = output.Substring ( 0, index ) + input ;
else
output = output.Substring ( 0, index ) + input + output.Substring ( index + 1 );
}
if( index >= 0 )
output = output.Substring( 0, index + 1 );

Debug.Log( output ); // Will output 95/3
}
-----
###2nd UPDATE
public UnityEngine.UI.InputField inputField;
// The Text component showing your formatted string
public UnityEngine.UI.Text text;
private string lastValidInput = string.Empty;
private void Awake()
{
inputField.onValueChanged.AddListener( OnValueChanged );
}
private void OnValueChanged( string input ) // Supposing input = “9534”
{
string format = “{0}{1}/{2}{3}/{4}{5}{6}{7}” ;
string[] array = new string[input.Length];
int index = format.IndexOf(“{” + (input.Length - 1) + “}”);
if ( input.Length == 0 )
{
text.text = string.Empty;
return;
}
if ( index >= 0 )
{
format = format.Substring( 0, index + 3 );
}
else
{
inputField.text = lastValidInput;
return;
}
for ( index = 0 ; index < input.Length ; ++index )
array[index] = string.Empty + input[index];
lastValidInput = input;
text.text = string.Format( format, array ); // Will output 95/34
}
###2nd Update’ (different output)
private void OnValueChanged( string input ) // Supposing input = “9534”
{
string format = “{0}{1}/{2}{3}/{4}{5}{6}{7}” ;
string[] array = new string[input.Length];
int index = format.IndexOf(“{” + (input.Length) + “}”);
if ( input.Length == 0 )
{
text.text = string.Empty;
return;
}
if ( index >= 0 )
{
format = format.Substring( 0, index );
}
else
{
inputField.text = lastValidInput;
return;
}
for ( index = 0 ; index < input.Length ; ++index )
array[index] = string.Empty + input[index];
lastValidInput = input;
text.text = string.Format( format, array ); // Will output 95/34/
}
#IMPORTANT NOTE :
The functions I gave you will only accept a string containing numbers only. Thus, you will need an input field with invisible characters to accept the input and a Text component to show the formatted result (See 2nd Update)
-----
##INITIAL ANSWER
I think [regular expressions][1] is the way to go. I prepared you an example for your first case :
System.Text.RegularExpressions.Match match = System.Text.RegularExpressions.Regex.Match(“9545551212”, @“(\d{3})(\d{3})(\d{4})”);
if ( match.Success )
{
// match.Groups[0] will return the whole input
string output = string.Format(“({0}) {1}-{2}”, match.Groups[1], match.Groups[2], match.Groups[3]);
Debug.Log( output ); // Will log “(954) 555-1212”
}
_*[1]: Microsoft Learn: Build skills that open doors in your career

Take a look at .NET’s formatting System.String,Format
It should cover basically everything you are looking to do.