DEV Community

Amina Tariq
Amina Tariq

Posted on

Enhance MAUI Entry: Auto-Format Credit Card Numbers!

πŸš€ Seamless UX with Auto-Formatting πŸš€

Have you ever struggled with users entering messy credit card numbers? Say no more! Implement a custom MAUI Behavior that formats credit card numbers dynamically as users type. πŸ¦πŸ’³

How It Works

βœ… Automatically insert spaces every 4 digits (e.g., 1234 5678 9012 3456).
βœ… Maintains correct cursor position while typing or deleting.
βœ… Removes non-numeric characters automatically.
βœ… Enhances user experience with clean and readable input.

Code Implementation

`public class CardNumberFormatterBehavior : Behavior
{
private bool _isUpdating = false;

protected override void OnAttachedTo(Entry entry)
{
    entry.TextChanged += OnEntryTextChanged;
    base.OnAttachedTo(entry);
}

protected override void OnDetachingFrom(Entry entry)
{
    entry.TextChanged -= OnEntryTextChanged;
    base.OnDetachingFrom(entry);
}

private void OnEntryTextChanged(object sender, TextChangedEventArgs args)
{
    if (_isUpdating || !(sender is Entry entry))
        return;

    _isUpdating = true;

    try
    {
        int cursorPosition = entry.CursorPosition;

        if (string.IsNullOrEmpty(args.NewTextValue))
        {
            entry.Text = string.Empty;
            entry.CursorPosition = 0;
            return;
        }

        int oldSpacesBeforeCursor = 0;
        if (!string.IsNullOrEmpty(args.OldTextValue) && cursorPosition <= args.OldTextValue.Length)
        {
            oldSpacesBeforeCursor = args.OldTextValue.Substring(0, cursorPosition).Count(c => c == ' ');
        }

        int oldDigitsBeforeCursor = cursorPosition - oldSpacesBeforeCursor;

        string cleanText = new string(args.NewTextValue.Where(char.IsDigit).ToArray());

        string formattedText = FormatCardNumber(cleanText);

        entry.Text = formattedText;

        int newCursorPosition;

        if (args.NewTextValue.Length > args.OldTextValue?.Length)
        {
            int spacesInFormattedTextUpToDigits = 0;
            int digitCount = 0;

            for (int i = 0; i < formattedText.Length && digitCount < oldDigitsBeforeCursor + 1; i++)
            {
                if (formattedText[i] == ' ')
                {
                    spacesInFormattedTextUpToDigits++;
                }
                else
                {
                    digitCount++;
                }
            }

            newCursorPosition = oldDigitsBeforeCursor + spacesInFormattedTextUpToDigits + 1;
        }
        else
        {
            int spacesInFormattedTextUpToDigits = 0;
            int digitCount = 0;

            for (int i = 0; i < formattedText.Length && digitCount < oldDigitsBeforeCursor; i++)
            {
                if (formattedText[i] == ' ')
                {
                    spacesInFormattedTextUpToDigits++;
                }
                else
                {
                    digitCount++;
                }
            }

            newCursorPosition = oldDigitsBeforeCursor + spacesInFormattedTextUpToDigits;
        }

        newCursorPosition = Math.Max(0, Math.Min(formattedText.Length, newCursorPosition));
        entry.CursorPosition = newCursorPosition;
    }
    finally
    {
        _isUpdating = false;
    }
}

private string FormatCardNumber(string cardNumber)
{
    if (string.IsNullOrEmpty(cardNumber))
        return string.Empty;

    StringBuilder result = new StringBuilder();

    for (int i = 0; i < cardNumber.Length; i++)
    {
        if (i > 0 && i % 4 == 0)
            result.Append(" ");

        result.Append(cardNumber[i]);
    }

    return result.ToString();
}
Enter fullscreen mode Exit fullscreen mode

}`

How to Use It in Your MAUI App

Simply attach the behavior to an Entry in XAML:
<Entry Placeholder="Enter card number">
<Entry.Behaviors>
<local:CardNumberFormatterBehavior />
</Entry.Behaviors>
</Entry>

output

Why Use This?

πŸš€ Improves data consistency.
🎯 Reduces user input errors.
πŸ”§ Works seamlessly in .NET MAUI apps.

Would you add any improvements to this behavior? Drop your thoughts below! β¬‡οΈπŸ’¬

Top comments (0)