Blazor Using Input Control for Date or DateTime
10:11 22 Nov 2025

The InputDate control works ok for capturing date or datetime user input except for one thing, it's not possible to paste a value into the control.

I have tried creating a control that inherits from input. It uses a string a the value which allows me to control the formatting, cursor position, etc. The problem with this approach is that I'm not able to figure out how to bind the control to a date and keep the same functionality. Here is the code for the control. It is not yet complete, but it's complete enough to display the problem. Can anyone help me to bind this to a date or datetime and still keep the ability to paste in a value?

@using System.Text.RegularExpressions
@inject IJSRuntime JsRuntime
@inherits InputText





@code {
    private ElementReference myInputText;

    protected void OnBlurEventHandler(FocusEventArgs e)
    {
        if (string.IsNullOrWhiteSpace(CurrentValueAsString))
        {
            return;
        }

        if (!Regex.IsMatch(CurrentValueAsString, @"^(0[1-9]|1[012])[- /. ](0[1-9]|[12][0-9]|3[01])[- /. ](19|20)\\d\\d$"))
        {
            var number = Regex.Replace(CurrentValueAsString, @"[\s()-]", "");
            //CurrentValueAsString = Regex.Replace(number, @"(\d{3})(\d{3})(\d{4})", "($1) $2-$3");
        }

        if (CurrentValueAsString.Length > 10)
        {
            CurrentValueAsString = CurrentValueAsString.Substring(0, 10);
        }
    }

    protected async void OnKeyPressEventHandler(KeyboardEventArgs e)
    {
        if (string.IsNullOrWhiteSpace(CurrentValueAsString))
        {
            CurrentValueAsString = string.Empty;
        }

        var key = (string)e.Key;
        if (Regex.IsMatch(key, "[0-9]"))
        {
            var selectedText = await JsRuntime.InvokeAsync("getSelectionFromInput", myInputText);
            //var cursorPosition = await JSRuntime.InvokeAsync("getCursorPosition", myInputText);
            var cursorPosition = await JsRuntime.InvokeAsync("getCursorPosition", myInputText);

            if (selectedText.Length > 0)
            {
                if (cursorPosition < 2)
                {
                    CurrentValueAsString = CurrentValueAsString.Replace(selectedText + "/", key + "/");
                }
                else if (cursorPosition > 2 && cursorPosition < 5)
                {
                    CurrentValueAsString = CurrentValueAsString.Replace("/" + selectedText, "/" + key);
                }
                else if (cursorPosition > 5)
                {
                    CurrentValueAsString = CurrentValueAsString.Substring(0, cursorPosition) + key;
                }
            }
            else
            {
                if (cursorPosition < CurrentValueAsString.Length)
                {
                    if (cursorPosition == 0)
                    {
                        if (CurrentValueAsString.Substring(1, 1) == "/")
                        {
                            CurrentValueAsString = key + CurrentValueAsString;
                        }
                    }
                    else if (cursorPosition == 1)
                    {
                        CurrentValueAsString = CurrentValueAsString.Substring(0, 1) + key + CurrentValueAsString.Substring(2);
                        CurrentValueAsString = CurrentValueAsString.Replace("//", "/");
                        // Check the month
                    }
                    else if (cursorPosition == 3)
                    {
                        CurrentValueAsString = CurrentValueAsString.Substring(0, 3) + key + CurrentValueAsString.Substring(4);
                    }
                    //CurrentValueAsString = CurrentValueAsString.Substring(0, cursorPosition) + key;
                }
                else if (CurrentValueAsString?.Length < 10 && Regex.IsMatch(key, "[0-9]"))
                {
                    CurrentValueAsString += CurrentValueAsString.Length switch
                    {
                        0 => $"{key}",
                        1 => $"{key}/",
                        2 => $"{key}",
                        3 => $"{key}",
                        4 => $"{key}/",
                        5 => $"{key}",
                        6 => $"{key}",
                        7 => $"{key}",
                        8 => $"{key}",
                        9 => $"{key}",
                        _ => $"{key}"
                    };
                }
            }
            ValidateMonth();
            ValidateDay();
        }
    }

    private void ValidateMonth()
    {
        if (CurrentValueAsString is not null)
        {
            if (CurrentValueAsString.Contains("/"))
            {
                int monthSlash = CurrentValueAsString.IndexOf("/");
                int monthSection = Convert.ToInt32(CurrentValueAsString.Substring(0, monthSlash));
                if (monthSection > 12)
                {
                    CurrentValueAsString = string.Empty;
                }
            }
        }
    }

    private void ValidateDay()
    {
        if (CurrentValueAsString is not null)
        {
            if (CurrentValueAsString.Contains("/"))
            {
                int monthSlash = CurrentValueAsString.IndexOf("/");
                if (monthSlash > 0)
                {
                    int monthSection = Convert.ToInt32(CurrentValueAsString.Substring(0, monthSlash));
                    int yearSlash = CurrentValueAsString.IndexOf("/", monthSlash + 1);
                    if (yearSlash > 0)
                    {
                        int daySection = Convert.ToInt32(CurrentValueAsString.Substring(monthSlash + 1, yearSlash - monthSlash - 1));

                        int maxDay = 29;
                        if (monthSection == 1 || monthSection == 3 || monthSection == 5 || monthSection == 7 || monthSection == 8 || monthSection == 10 || monthSection == 12)
                        {
                            maxDay = 31;
                        }
                        else if (monthSection != 2)
                        {
                            maxDay = 30;
                        }

                        if (daySection < 1 || daySection > maxDay)
                        {
                            CurrentValueAsString = string.Empty;
                        }
                    }
                }
            }
        }
    }
}
c# blazor