Blazor Grid 検索フィルター

    Blazor Grid の Ignite UI for Blazor 検索フィルター機能を使用すると、データのコレクション内の値を検索するプロセスが可能になります。この機能のセットアップが簡単になり、検索入力ボックス、ボタン、キーボード ナビゲーション、その他の便利な機能を使用して実装できるため、ユーザー エクスペリエンスがさらに向上します。ブラウザーにはネイティブなコンテンツ検索機能がありますが、ほとんどの場合で IgbGrid は表示範囲外の行列を仮想化します。そのため、ネイティブ ブラウザー検索は DOM の一部でないため仮想化セルでデータを検索できません。IgbGrid では、Blazor Material テーブル ベースのグリッドの拡張により、検索 API を使用した仮想コンテンツの検索が可能です。

    Blazor 検索の例

    次の例は、すべての列と行を検索できる検索入力ボックスと、各列の特定のフィルタリング オプションを備えた IgbGrid を表しています。

    Blazor 検索の使用

    Grid のセットアップ

    グリッドを作成してからデータをバインドします。コンポーネントにカスタム スタイルも追加しました。

    .gridSize {
        --ig-size: var(--ig-size-small);
    }
    
    <IgbGrid @ref=grid Class="gridSize" Width="100%" Height="480px" AllowFiltering=true AutoGenerate=false Data=marketData>
        <IgbColumn Field="IndustrySector" DataType="GridColumnDataType.String" Sortable=true></IgbColumn>
        <IgbColumn Field="IndustryGroup" DataType="GridColumnDataType.String" Sortable=true></IgbColumn>
        <IgbColumn Field="SectorType" DataType="GridColumnDataType.String" Sortable=true></IgbColumn>
        <IgbColumn Field="KRD" DataType="GridColumnDataType.Number" Sortable=true></IgbColumn>
        <IgbColumn Field="MarketNotion" DataType="GridColumnDataType.Number" Sortable=true></IgbColumn>
    </IgbGrid>
    
    @code {
        protected override void OnInitialized()
        {
            base.OnInitialized();
            this.marketData = MarketData.GetData();
        }
    }
    

    では、IgbGrid の検索 API の準備をしましょう。検索したテキストの保存、また大文字小文字の区別や完全一致 (またはそのいずれか) に使用するプロパティを作成できます。

    public string searchText = "";
    public bool caseSensitive = false;
    public bool exactMatch = false;
    

    Blazor 検索ボックス入力

    検索入力を作成します。新しく作成した入力の Value プロパティに SearchText をバインドし、ValueChanging イベントをサブスクライブすることで、ユーザーによるすべての SearchText の変更を検出できます。これによって IgbGridFindNextFindPrev メソッドを使用して SearchText のすべての出現を強調し、次へまたは前 (呼び出すメソッドに基づいて) へスクロールできます。

    FindNextFindPrev メソッドの両方に 3 つの引数があります。

    • Text: string (検索テキスト)
    • (オプション) CaseSensitive: boolean (検索で完全一致するかどうか、デフォルト値は false)。
    • (オプション) ExactMatch: boolean (検索で完全一致するかどうか、デフォルト値は false)。

    完全一致で検索した場合、検索 API は SearchText と完全一致 (大文字小文字の区別を含む) するセル値のみ結果としてハイライト表示します。たとえば、文字列 'software' と 'Software' は大文字小文字を区別しない場合は完全一致となります。

    上記のメソッドは number 値を返します (IgbGrid で指定した文字列が含まれる回数)。

    <IgbInput ValueChanging="valueChanging" Value="@searchText" />
    

    検索ボタンの追加

    ボタンの各クリック イベント ハンドラー内で FindNextFindPrev メソッドを呼び出して検索や検索結果をナビゲーションするためのボタンを作成します。

    <IgbIconButton Variant="IconButtonVariant.Flat" @onclick="PrevSearch">
        <IgbIcon IconName="prev" Collection="material"/>
    </IgbIconButton>
    <IgbIconButton Variant="IconButtonVariant.Flat" @onclick="NextSearch">
        <IgbIcon IconName="next" Collection="material" />
    </IgbIconButton>
    
    @code {
        private IgbGrid grid;
        public void PrevSearch()
        {
            this.grid.FindPrevAsync(this.searchText, this.caseSensitive, this.exactMatch);
        }
    
        public void NextSearch()
        {
            this.grid.FindNextAsync(this.searchText, this.caseSensitive, this.exactMatch);
        }
    }
    

    キーボード検索の追加

    ユーザーは矢印キーと Enter キーで結果を移動できます。PreventDefault メソッドのデフォルト キャレットの移動を防止する検索入力の keydown イベントを処理し、ユーザーが押したキーに基づいて FindNext/FindPrev メソッドを呼び出します。

    ユーザーは Enter キーで結果を移動できます。これを実現するために、検索の keydown イベントを処理し、ユーザーが Shift キーを押したかどうかに応じて FindNext/FindPrev メソッドを呼び出すことができます。

    <IgbInput ValueChanging="valueChanging" Value="@searchText" @onkeydown="OnSearchKeyDown"/>
    
    @code {
        private void OnSearchKeyDown(KeyboardEventArgs evt)
        {
            if (evt.Key == "Enter" && !evt.ShiftKey) {
                this.grid.FindNextAsync(this.searchText, this.caseSensitive, this.exactMatch);
            } else if (evt.Key == "Enter") {
                this.grid.FindPrevAsync(this.searchText, this.caseSensitive, this.exactMatch);
            }
        }
    }
    

    大文字と小文字の区別と完全一致

    次に完全一致の検索で大文字と小文字を区別するかどうかをユーザーが選択できるようにします。この目的のために、単純な選択可能な Chips を使用し、SelectedChanged イベントにバインドして、ユーザーがいつチップを操作したかを判断できます。

    <IgbChip Selectable=true SelectedChanged="UpdateCase">
        Case Sensitive
    </IgbChip>
    <IgbChip  Selectable=true SelectedChanged="UpdateExactSearch">
        Exact Match
    </IgbChip>
    
    @code {
        public void UpdateCase(bool selected) {
            this.caseSensitive = selected;
            this.grid.FindNextAsync(this.searchText, this.caseSensitive, this.exactMatch);
        }
    
        public void UpdateExactSearch(bool selected) {
            this.exactMatch = selected;
            this.grid.FindNextAsync(this.searchText, this.caseSensitive, this.exactMatch);
        }
    }
    

    保持

    IgbGrid のフィルターやソート、レコードの追加や削除をする場合を想定します。そのような処理の後、現在の検索が自動的に更新されて SearchText に一致するテキストが保持されます。更に検索がページングで動作し、IgbGridPerPage プロパティの変更時もハイライト表示が保持されます。

    アイコンの追加

    その他のコンポーネントを使用するためにユーザー インターフェイスを作成し、検索バー全体のデザインを向上します。検索入力の左側に検索または削除アイコン、検索オプションのチップ、右側にはマテリアル デザイン アイコンと Ripple スタイルのボタンを組み合わせたナビゲーションを表示できます。入力グループ内のコンポーネントをラップしてより洗練されたデザインにすることができます。

    IgbInputIgbIconIgbIconButtonIgbChip のモジュールを使用します。

    // eg. Program.cs register the following:
    builder.Services.AddIgniteUIBlazor(
        typeof(IgbGridModule),
        typeof(IgbInputModule),
        typeof(IgbIconButtonModule),
        typeof(IgbIconModule)
    );
    
    @code {
        private IgbIcon searchIconRef { get; set; }
        const string searchIcon = "<svg width='24' height='24' viewBox='0 0 24 24'><path d='M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z' /></svg>";
        const string prevIcon = "<svg width='24' height='24' viewBox='0 0 24 24'><path d='M15.41 7.41 14 6l-6 6 6 6 1.41-1.41L10.83 12z'></path></svg>";
        const string nextIcon = "<svg width='24' height='24' viewBox='0 0 24 24'><path d='M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z'></path></svg>";
        const string clearIcon = "<svg width='24' height='24' viewBox='0 0 24 24' title='Clear'><path d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'></path></svg>";
        
        protected override void OnAfterRender(bool firstRender)
        {
            if (this.searchIconRef != null && firstRender)
            {
                this.searchIconRef.EnsureReady().ContinueWith(new Action<Task>((e) =>
                {
                    this.searchIconRef.RegisterIconFromTextAsync("search", searchIcon, "material");
                    this.searchIconRef.RegisterIconFromTextAsync("prev", prevIcon, "material");
                    this.searchIconRef.RegisterIconFromTextAsync("next", nextIcon, "material");
                    this.searchIconRef.RegisterIconFromTextAsync("clear", clearIcon, "material");
                }));
            }
        }
    }
    

    テンプレートを新しいコンポーネントで更新します。

    IgbInput 内のすべてのコンポーネントをラップします。左側で検索と 削除/クリア アイコンを切り替えます (検索入力が空かどうかに基づきます)。中央に入力を配置します。更に削除アイコンがクリックされたときに SearchText を更新し、IgbGridClearSearch メソッドを呼び出してハイライト表示をクリアします。

    <IgbInput ValueChanging="OnValueChanging" Value="@searchText" @onkeydown="OnSearchKeyDown">
        @if (searchText.Length == 0)
        {
            <IgbIcon @ref="searchIconRef" slot="prefix" IconName="search" Collection="material"/>
        }
        @if (searchText.Length > 0)
        {
            <IgbIcon slot="prefix" IconName="clear" Collection="material" @onclick="ClearSearch"/>
        }
    
        <div class="chips" slot="suffix">
            <IgbChip Selectable=true SelectedChanged="UpdateCase">
                Case Sensitive
            </IgbChip>
            <IgbChip  Selectable=true SelectedChanged="UpdateExactSearch">
                Exact Match
            </IgbChip>
        </div>
        <div class="searchButtons" slot="suffix">
            <IgbIconButton Variant="IconButtonVariant.Flat" @onclick="PrevSearch">
                <IgbIcon IconName="prev" Collection="material"/>
            </IgbIconButton>
            <IgbIconButton Variant="IconButtonVariant.Flat" @onclick="NextSearch">
                <IgbIcon IconName="next" Collection="material" />
            </IgbIconButton>
        </div>
    </IgbInput>
    
    @code {
    
        public void clearSearch()
        {
            this.searchText = "";
            this.grid.ClearSearchAsync();
        }
    }
    

    右側の入力グループに以下の目的で別のコンテナーを作成します。

    • 以下は CaseSensitiveExactMatch を切り替えるチップを表示する方法です。プロパティに基づいて色が変わる 2 つのチップでチェックボックスを 置き換えます。チップをクリックすると、どちらのチップがクリックされたかによって各ハンドラーを呼び出します。
        <div class="chips" slot="suffix">
            <IgbChip Selectable=true SelectedChanged="UpdateCase">
                Case Sensitive
            </IgbChip>
            <IgbChip  Selectable=true SelectedChanged="UpdateExactSearch">
                Exact Match
            </IgbChip>
        </div>
    
    @code {
        public void UpdateCase(bool selected) {
            this.caseSensitive = selected;
            this.grid.FindNextAsync(this.searchText, this.caseSensitive, this.exactMatch);
        }
    
        public void UpdateExactSearch(bool selected) {
            this.exactMatch = selected;
            this.grid.FindNextAsync(this.searchText, this.caseSensitive, this.exactMatch);
        }
    }
    
    • 検索ナビゲーション ボタンは、マテリアルアイコンを使用して入力を Ripple スタイルボタンにします。click イベントのハンドラーはそのままで FindNext/FindPrev メソッドを呼び出します。
    <div class="searchButtons" slot="suffix">
        <IgbIconButton Variant="IconButtonVariant.Flat" @onclick="PrevSearch">
            <IgbIcon IconName="prev" Collection="material"/>
        </IgbIconButton>
        <IgbIconButton Variant="IconButtonVariant.Flat" @onclick="NextSearch">
            <IgbIcon IconName="next" Collection="material" />
        </IgbIconButton>
    </div>
    @code {
        public void PrevSearch()
        {
            this.grid.FindPrevAsync(this.searchText, this.caseSensitive, this.exactMatch);
        }
    
        public void NextSearch()
        {
            this.grid.FindNextAsync(this.searchText, this.caseSensitive, this.exactMatch);
        }
    }
    

    既知の問題と制限

    制限 説明
    テンプレートを使用したセル内の検索 検索機能のハイライト表示が、デフォルトのセルテンプレートに対してのみ機能する問題。カスタム セル テンプレートを含む列がある場合、ハイライト表示が機能しないため、列フォーマッタなどの代替アプローチを使用するか、Searchable (検索可能な) プロパティを false に設定します。
    リモート仮想化 リモート仮想化の使用時に検索が正しく動作しません。
    セル テキストが切れる問題 セル内のテキストが長すぎるために検索テキストが省略記号によって切れている場合も、セルまでスクロールして一致カウントに含まれますが、ハイライト表示はされません。

    API リファレンス

    このトピックでは、IgbGrid にカスタム検索バーを実装し、更に検索結果を移動する際の機能を追加しました。アイコン、チップ、入力などその他の Ignite UI for Blazor も使用しています。以下は検索 API です。

    IgbGrid メソッド:

    IgbColumn プロパティ:

    その他のコンポーネント (またはそのいずれか) で使用した API:

    その他のリソース

    コミュニティに参加して新しいアイデアをご提案ください。