Angular Text Highlight (テキスト強調表示) ディレクティブの概要

    Ignite UI for Angular の IgxTextHighlight ディレクティブは、テキストのハイライト、大文字と小文字の区別のオプション、完全一致のみのハイライトをサポートします。既にハイライトしている部分を含む、テキストのハイライトをアクティブに保持できます。

    Angular Text Highlight ディレクティブの例

    Ignite UI for Angular Text Highlight ディレクティブを使用した作業の開始

    Ignite UI for Angular Text Highlight ディレクティブを使用した作業を開始するには、Ignite UI for Angular をインストールする必要があります。既存の Angular アプリケーションで、以下のコマンドを入力します。

    ng add igniteui-angular
    

    Ignite UI for Angular については、「はじめに」トピックをご覧ください。

    次に、app.module.ts ファイルに IgxTextHighlightModule をインポートします。

    // app.module.ts
    ...
    import { IgxTextHighlightModule } from 'igniteui-angular';
    // import { IgxTextHighlightModule } from '@infragistics/igniteui-angular'; for licensed package
    
    @NgModule({
        ...
        imports: [IgxTextHighlightModule],
        ...
    })
    export class AppModule {}
    

    あるいは、16.0.0 以降、IgxTextHighlightDirective をスタンドアロンの依存関係としてインポートできます。

    // home.component.ts
    
    import { IgxTextHighlightDirective } from 'igniteui-angular';
    // import { IgxTextHighlightDirective } from '@infragistics/igniteui-angular'; for licensed package
    
    @Component({
        selector: 'app-home',
        template: `
        <div igxTextHighlight
            [value]="html"
            [groupName]="'group1'"
            [containerClass]="'search-text'"
            class="search-text">
            {{html}}
        </div>
        `,
        styleUrls: ['home.component.scss'],
        standalone: true,
        imports: [IgxTextHighlightDirective]
    })
    export class HomeComponent {}
    

    Ignite UI for Angular Text Highlight モジュールまたはディレクティブをインポートしたので、igxTextHighlight ディレクティブの使用を開始できます。

    Angular Text Highlight ディレクティブの使用

    次にテキストの様々な部分を強調表示するためにハイライトできる検索ボックスを作成します。Ignite UI for Angular の InputGroup コンポーネントは、一致のクリア、次の一致、前の一致へ移動するためのボタン、検索で大文字と小文字を区別を指定するボタンを追加します。また一致がいくつ見つかったかを示すラベルがあります。

    <div class="search-container">
        <igx-input-group type="search" class="input-group">
            <igx-prefix>
                <igx-icon *ngIf="searchText.length == 0">search</igx-icon>
                <igx-icon *ngIf="searchText.length > 0" (click)="clearSearch()">clear</igx-icon>
            </igx-prefix>
    
            <input #search1 id="search1" igxInput placeholder="Search" autocomplete="off" [(ngModel)]="searchText" (ngModelChange)="onTextboxChange()"
                    (keydown)="searchKeyDown($event)" />
            <igx-suffix>
                <div class="caseSensitiveButton">
                    <button igxIconButton="flat" igxRipple igxRippleCentered="true" (click)="updateSearch()"
                            [igxButtonBackground]="caseSensitive? 'rgb(73, 180, 254)' : 'transparent'">
                        <igx-icon class="caseSensitiveIcon" fontSet="material">text_fields</igx-icon>
                    </button>
                </div>
                <ng-container *ngIf="searchText.length > 0">
                    <span>
                        <ng-container *ngIf="matchCount > 0">
                            {{ index + 1 }} of {{ matchCount }} results
                        </ng-container>
                        <ng-container *ngIf="matchCount == 0">
                            No results
                        </ng-container>
                    </span>
                </ng-container>
               
                <div class="searchButtons">
                    <button igxIconButton="flat" igxRipple igxRippleCentered="true" (click)="findPrev()" [disabled]="!canMoveHighlight">
                        <igx-icon fontSet="material">navigate_before</igx-icon>
                    </button>
                    <button igxIconButton="flat" igxRipple igxRippleCentered="true" (click)="findNext()" [disabled]="!canMoveHighlight">
                        <igx-icon fontSet="material">navigate_next</igx-icon>
                    </button>
                </div>
            </igx-suffix>
        </igx-input-group>
    </div>
    

    div テキストと IgxTextHighlight ディレクティブを追加します。値入力を div のテキストにバインドする必要があることに注意してください。div テキストに補間も使用します。

    <div igxTextHighlight
         [value]="html"
         [groupName]="'group1'"
         [containerClass]="'search-text'"
         class="search-text">
        {{html}}
    </div>
    

    コンポーネント テンプレートのバインディングに使用する以下のフィールドをコンポーネントの .ts ファイルに追加します。

    public html = '...';
    
    @ViewChild(IgxTextHighlightDirective, {read: IgxTextHighlightDirective})
    public highlight: IgxTextHighlightDirective;
    
    public searchText: string = '';
    public matchCount: number = 0;
    public caseSensitive: boolean = false;
    public index: number = 0;
    
    
    public get canMoveHighlight() {
        return this.matchCount > 1;
    }
    

    次に以下のメソッドを追加すると、ユーザーが検索ボックスに入力したテキストにハイライトを適用でき、アクティブ ハイライト間を移動できます。

    public searchKeyDown(ev) {
        if (this.searchText) {
            if (ev.key === 'Enter' || ev.key === 'ArrowDown' || ev.key === 'ArrowRight') {
                ev.preventDefault();
                this.findNext();
            } else if (ev.key === 'ArrowUp' || ev.key === 'ArrowLeft') {
                ev.preventDefault();
                this.findPrev();
            }
        }
    }
    
    public onTextboxChange() {
        this.index = 0;
        this.find(0);
    }
    
    public updateSearch() {
        this.caseSensitive = !this.caseSensitive;
        this.find(0);
    }
    
    public clearSearch() {
        this.searchText = '';
        this.find(0);
    }
    
    private findNext() {
        this.find(1);
    }
    
    private findPrev() {
        this.find(-1);
    }
    
    private find(increment: number) {
        if (this.searchText) {
            this.matchCount = this.highlight.highlight(this.searchText, this.caseSensitive);
            this.index += increment;
    
            this.index = this.index < 0 ? this.matchCount - 1 : this.index;
            this.index = this.index > this.matchCount - 1 ? 0 : this.index;
    
            if (this.matchCount) {
                IgxTextHighlightDirective.setActiveHighlight('group1', {
                    columnIndex: 0,
                    index: this.index,
                    page: 0,
                    rowIndex: 0
                });
            }
        } else {
            this.highlight.clearHighlight();
        }
    }
    

    サンプルが正しく構成された場合、以下のような結果になります。

    複数要素で検索

    igxTextHighlight は、1 つのアクティブ ハイライトを共有する複数の要素内を検索できます。複数の TextHighlight ディレクティブで同じ groupName 値を持つことにより可能になります。サンプルの設定は、前のサンプルの検索ボックスを再利用しますが、今回は div 要素を 2 つ追加します。columnrow 入力は複数要素がある場合に便利で、この場合は 2 つ目の div に異なる行値があります。

    <div igxTextHighlight
         [groupName]="'group1'"
         [row]="0"
         [containerClass]="'search-text'"
         [value]="firstParagraph"
         class="search-text">
        {{firstParagraph}}
    </div>
    <div igxTextHighlight
         [groupName]="'group1'"
         [row]="1"
         [containerClass]="'search-text'"
         [value]="secondParagraph"
         class="search-text">
        {{secondParagraph}}
    </div>
    

    .ts ファイルに firstParagraphsecondParagraph フィールドがあり、テキスト ハイライト ディレクティブの各値入力にバインドします。ViewChild の代わりに ViewChildren を使用してテンプレートのすべてのハイライトを取得します。

    public firstParagraph = "...";
    
    public secondParagraph = "...";
    
    @ViewChildren(IgxTextHighlightDirective)
    public highlights;
    

    .ts ファイルのコードの残りすべてが単一要素の例 (find メソッドの例外) と同一となります。複数の要素があるため、このメソッドの変更が必要になりますが、TextHighlight ディレクティブの数値に関係なくコードを使用できます。

    private find(increment: number) {
        if (this.searchText) {
            let count = 0;
            const matchesArray = [];
    
            this.highlights.forEach((h) => {
                count += h.highlight(this.searchText, this.caseSensitive);
                matchesArray.push(count);
            });
    
            this.matchCount = count;
    
            this.index += increment;
            this.index = this.index < 0 ? this.matchCount - 1 : this.index;
            this.index = this.index > this.matchCount - 1 ? 0 : this.index;
    
            if (this.matchCount) {
                let row;
    
                for (let i = 0; i < matchesArray.length; i++) {
                    if (this.index < matchesArray[i]) {
                        row = i;
                        break;
                    }
                }
    
                const actualIndex = row === 0 ? this.index : this.index - matchesArray[row - 1];
    
                IgxTextHighlightDirective.setActiveHighlight('group1', {
                    index: actualIndex,
                    rowIndex: row
                });
            }
        } else {
            this.highlights.forEach((h) => {
                h.clearHighlight();
            });
            this.matchCount = 0;
        }
    }
    

    スタイル設定

    IgxTextHighlight ディレクティブは、指定された文字列のすべての発生の色と背景を変更してスタイル設定できます。まず、すべてのテーマ関数とコンポーネント ミックスインが存在する index ファイルをインポートする必要があります。

    @use "igniteui-angular/theming" as *;
    
    // 重要: Ignite UI for Angular 13 より前のバージョンは、次を使用してください。
    // @import '~igniteui-angular/lib/core/styles/themes/index';
    

    最も簡単な方法は、highlight-theme を拡張する新しいテーマを作成し、$resting-background$resting-color$active-background$active-color パラメーターを受け取る方法です。

    $dark-highlight: highlight-theme(
        $resting-background: #FFCD0F,
        $resting-color: #292826,
        $active-background: #292826,
        $active-color: #FFCD0F
    );
    

    $resting-background$resting-color パラメーターは、$active-background$active-colorパラメーターに基づいてスタイル設定されるアクティブな強調表示の文字列以外、すべての強調表示に適用されます。

    最後にコンポーネントのテーマを含めます

    $legacy-supporttrue に設定されている場合、コンポーネントのテーマを以下のように含めます。

    @include highlight($dark-highlight);
    
    Note

    コンポーネントが Emulated ViewEncapsulation を使用している場合、::ng-deep を使用してこのカプセル化を解除する必要があります。

    :host {
        ::ng-deep {
            @include highlight($dark-highlight);
        }
    }
    

    $legacy-supportfalse (デフォルト) に設定されている場合、css 変数 を以下のように含めます。

    @include css-vars($dark-highlight);
    
    Note

    デフォルトでは、$legacy-supportfalse に設定されます。

    カスタム スタイル

    IgxTextHighlight ディレクティブの cssClassactiveCssClass 入力を利用できます。これらのクラスを highlight-theme のスタイルと組み合わせて、優れたユーザー エクスペリエンスを提供できます。

    プロパティを持ついくつかの CSS クラスを作成し、上記の入力を使用してそれらを添付します。

    <div igxTextHighlight
         [cssClass]="'custom-highlight'"
         [activeCssClass]="'custom-active-highlight'">
        {{html}}
    </div>
    
    // cssClass
    .custom-highlight {
        border: 1px solid #FFCD0F;
    }
    // activeCssClass
    .custom-active-highlight {
        box-shadow: 0 0 3px 0 rgba(0,0,0,0.75);
    }
    

    上記のように、テーマと組み合わせることもできます。

    :host {
        ::ng-deep {
           @include highlight($dark-highlight);
            
           // cssClass
           .custom-highlight {
                border: 1px solid #FFCD0F;
           }
            
            // activeCssClass
           .custom-active-highlight {
                box-shadow: 0 0 3px 0 rgba(0,0,0,0.75);
            }
       }
    }
    

    デモ

    API リファレンス

    TextHighlight ディレクティブの API に関する詳細な情報は、以下のリンクのトピックを参照してください。

    使用したその他のコンポーネント:

    その他のリソース

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