Filter Blazor Input field

Viewed 2993

I have a basic input with Blazor

<div class="file-explorer-input">
    <div class="search"><i class='fas fa-search search-icon' /><input type="text" name="subPath" placeholder="Select or search for your directory..." @bind="Search" @oninput="OnType" /></div>
</div>

When I type in characters which I deem invalid (such as "/" or "<") I want to filter those immediately from the search.

I tried to do it like so

using System.Text.RegularExpressions;

private string Search;

private void OnType(ChangeEventArgs args)
{
    var pattern = @"[<>:/\\""|?* ]";
    Search = Regex.Replace(args.Value.ToString(), pattern, "");
}

Now my filtering works great. The Search immediately filters out what I want and is set to that value. The issue is with the state management.

If I where to type in an invalid character after a valid one (i.e. "s/"), it would not recognize it as a change to Search.

The reason being, is because before the typing, Search = "s" and then the args = "s/" but since the result is filtered, Search still equals "s"and therefore doesn't recognize a change. However, the input still says s/.

I have even tried

private void OnType(ChangeEventArgs args)
    {
        var pattern = @"[<>:/\\""|?* ]";
        Search = Regex.Replace(args.Value.ToString(), pattern, "");

        base.StateHasChanged();
    }

Summary
When I add invalid characters, they are not removed from the input because the Search doesn't recognize a change. Only when I add another valid character, are all the inbetween invalid ones removed.

2 Answers

Rather than using @bind="Search", you probably want to use:

<input @bind-value="Search" @bind-value:event="oninput" />

This way the binding works oninput instead of onchange.

Then change your string Search to match something similar to this pattern:

private string _search;
string Search
{
  get { return _search; }
  set 
  {
     _search = Regex.Replace(value, pattern, "");
  }
}

Years late but maybe this will help someone else. The advantage of this one is that if a non-allowed char is used it will not jump to the end.

<input @bind-value=search @onkeydown=OnType @onkeydown:preventDefault="preventDefaultForSearch " >

@code 
{
    private string search;
    bool preventDefaultForSearch = false;
    
    private void OnType(KeyboardEventArgs e)
    {
        var pattern = @"[<>:/\\""|?* ]";
        preventDefaultForSearch = Regex.IsMatch(e.Key, pattern);
    }
}
Related