web-dev-qa-db-fra.com

Mettez en surbrillance le texte de recherche - angulaire 2

Un messager affiche les résultats de la recherche en fonction de l’entrée donnée par l’utilisateur. Besoin de mettre en évidence le mot recherché, tout en affichant le résultat. Ce sont le code HTML et le composant qui ont été utilisés.

Component.html

 <div *ngFor = "let result of resultArray">
<div>Id : result.id </div>
<div>Summary : result.summary </div>
<div> Link : result.link </div>
</div>

Component.ts

resultArray : any = [{"id":"1","summary":"These are the results for the searched text","link":"http://www.example.com"}]

Cette table de résultats est extraite du service principal en envoyant le texte de recherche en tant qu'entrée. En fonction du texte de recherche, le résultat est récupéré. Besoin de mettre en évidence le texte recherché, similaire à la recherche Google. S'il vous plaît trouver la capture d'écran, 

 enter image description here

Si je recherche le mot "membre", l'occurrence du mot "membre" est mise en évidence. Comment obtenir la même chose en utilisant angular 2. Suggérez une idée à ce sujet.

13
regina

Vous pouvez le faire en créant un canal et en appliquant ce canal à la partie summary du tableau dans ngfor. Voici le code pour Pipe:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
    name: 'highlight'
})

export class HighlightSearch implements PipeTransform {

    transform(value: any, args: any): any {
        if (!args) {return value;}
        var re = new RegExp(args, 'gi'); //'gi' for case insensitive and can use 'g' if you want the search to be case sensitive.
        return value.replace(re, "<mark>" + args + "</mark>");
    }
}

puis dans le balisage, appliquez-le sur une chaîne comme celle-ci:

<div innerHTML="{{ str | highlight : 'search'}}"></div>

Remplacez 'recherche' par le mot que vous souhaitez mettre en évidence.

J'espère que cela aidera.

25
Fahad Nisar

La réponse sélectionnée pose les problèmes suivants:

  1. Il retournera undefined s'il n'y a rien de fourni dans la chaîne de recherche
  2. La recherche doit être insensible à la casse, mais cela ne doit pas remplacer le casse de chaîne d'origine.

je suggère plutôt le code suivant

transform(value: string, args: string): any {
    if (args && value) {
        let startIndex = value.toLowerCase().indexOf(args.toLowerCase());
        if (startIndex != -1) {
            let endLength = args.length;
            let matchingString = value.substr(startIndex, endLength);
            return value.replace(matchingString, "<mark>" + matchingString + "</mark>");
        }

    }
    return value;
}
7
Kamal Saad

Une difficulté de la méthode innerHTML réside dans le style de la balise <mark>. Une autre méthode consiste à placer cela dans un composant, ce qui permet beaucoup plus d'options de style.

highlight-text.component.html

<mark *ngIf="matched">{{matched}}</mark>{{unmatched}}

highlight-text.component.ts

import { Component, Input, OnChanges, OnInit } from "@angular/core";

@Component({
    selector: "highlighted-text",
    templateUrl: "./highlighted-text.component.html",
    styleUrls: ["./highlighted-text.component.css"]
})
export class HighlightedTextComponent implements OnChanges {
    @Input() needle: String;
    @Input() haystack: String;
    public matched;
    public unmatched;

    ngOnChanges(changes) {
        this.match();
    }

    match() {
        this.matched = undefined;
        this.unmatched = this.haystack;
        if (this.needle && this.haystack) {
            const needle = String(this.needle);
            const haystack = String(this.haystack);
            const startIndex = haystack.toLowerCase().indexOf(needle.toLowerCase());
            if (startIndex !== -1) {
                const endLength = needle.length;
                this.matched = haystack.substr(startIndex, endLength);
                this.unmatched = haystack.substr(needle.length);
            }
        }
    }
}

highlight-text.component.css

mark {
    display: inline;
    margin: 0;
    padding: 0;       
    font-weight: 600;
}

Utilisation

<highlighted-text [needle]=searchInput [haystack]=value></highlighted-text>
1
Will Shaver

Pour développer la réponse de Kamal,

La valeur entrant dans la méthode de transformation, pourrait être un nombre, peut-être qu'une conversion en chaîne String(value) serait une chose sûre à faire.

transform(value: string, args: string): any {
    if (args && value) {
        value = String(value); // make sure its a string
        let startIndex = value.toLowerCase().indexOf(args.toLowerCase());
        if (startIndex != -1) {
            let endLength = args.length;
            let matchingString = value.substr(startIndex, endLength);
            return value.replace(matchingString, "<mark>" + matchingString + "</mark>");
        }

    }
    return value;
}
0
Mingster