Highlight Pipe не выделяет все экземпляры значения - PullRequest
0 голосов
/ 08 мая 2019

У меня есть поисковый ввод, который выделяет символы внутри абзаца, если поисковый ввод соответствует какой-либо части значения:

Поиск:

<h4>Keyword Search</h4>
<mat-form-field appearance="outline" class="mat-form-field">
  <mat-label>Search</mat-label>
  <input matInput placeholder="Search Text" [(ngModel)]="searchTerm">
</mat-form-field>

//Area to search: 
 <p [innerHTML]="paragraphText | highlight: searchTerm"></p>

Файл компонента:

searchTerm: string;
paragraphText = "1. Local currency (Kwanza-AOA): up to AOA 50,000.- for residents and non-residents.<br xmlns="http://www.opentravel.org/OTA/2003/05/beta" />2. Foreign currencies:<br xmlns="http://www.opentravel.org/OTA/2003/05/beta" />a. Residents (older than 17 years): up to USD 15,000.- or equivalent;<br xmlns="http://www.opentravel.org/OTA/2003/05/beta" />b. Residents (younger than 18 years): up to USD 5,000.- or equivalent;<br xmlns="http://www.opentravel.org/OTA/2003/05/beta" />c. Non Residents (older than 17 years): up to USD 10,000.- or equivalent;<br xmlns="http://www.opentravel.org/OTA/2003/05/beta" />d. Non Residents (younger than 18 years): up to USD 3,000.- or equivalent. <br xmlns="http://www.opentravel.org/OTA/2003/05/beta" />Exempt: <br xmlns="http://www.opentravel.org/OTA/2003/05/beta" />- If holding a letter (certified by B.N.A./D.O.I.) from a company or entity which took care of payment of all expenses during stay in Angola: foreign currencies up to the amount imported.<br xmlns="http://www.opentravel.org/OTA/2003/05/beta" />- Amounts left with receipts of bills paid or money exchange vouchers. "

Подсветка:

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

@Pipe({
  name: 'highlight'
})
export class HighlightPipe implements PipeTransform {

  transform(value: string, searchTerm: string, index= -1 ): any {
    if (searchTerm && value) {
      value = String(value);
      console.log(value);
      const startIndex = value.toLowerCase().indexOf(searchTerm.toLowerCase(),index);
      if (startIndex != -1) {
          const endLength = searchTerm.length;
          const matchingString = value.substr(startIndex, endLength);
          return value.substring(0,startIndex)+"<mark>" + matchingString + "</mark>"+value.substring(startIndex+endLength);
        }

    }
    return value;
  }

}

Текущее поведение При вводе буквы (например, «c») в поле поиска выделяются не все буквы «c».Я заметил закономерность, что что-либо после встроенных html-тегов (в свойстве абзаца-текст) не поднимается.

enter image description here

Ожидаемое поведение Должны быть выделены все символы в абзаце, соответствующие строке в поле поиска.

Что я делаю не так в канале выделения, чтобы гарантировать выделение всех значений ??

Ответы [ 2 ]

1 голос
/ 08 мая 2019

Я создал следующий stackblitz пример, который показывает, как работать с подсветкой Pipes

Pipe:

@Pipe({
  name: 'highlight'
})
export class HighlightSearch implements PipeTransform {
  constructor(private sanitizer: DomSanitizer) { }

  transform(value: any, args: string): any {
    if (!args) {
      return value;
    }
    const specials = [
      // order matters for these
      "-"
      , "["
      , "]"
      // order doesn't matter for any of these
      , "/"
      , "{"
      , "}"
      , "("
      , ")"
      , "*"
      , "+"
      , "?"
      , "."
      , "\\"
      , "^"
      , "$"
      , "|"
    ];

    const rgxEscaper = RegExp('[' + specials.join('\\') + ']', 'g');

    args = args.replace(rgxEscaper, "\\$&");

    // Match in a case insensitive maneer
    const re = new RegExp(`\\\\?${args}` + `(?!([^<]+)?>)`, 'g');
    const match = value.match(re);

    // If there's no match, just return the original value.
    if (!match) {
      return value;
    }

    const replacedValue = value.replace(re, "<mark>" + match[0] + "</mark>")
    return this.sanitizer.bypassSecurityTrustHtml(replacedValue)
  }
}

Компонент:

@Component({ 
  selector: 'my-app',
  styleUrls: ['./app.component.css'],
  template: `
    <label for="search-term">Search</label>
    <input placeholder="Enter term" (input)="updateSearch($event)" id="search-term">
    <div [innerHTML]="results | highlight: searchTerm"></div>
  `,
})
export class AppComponent {
  results: string;
  searchTerm: string;
  constructor() {
    this.results =  '"1. Local currency (Kwanza-AOA): up to AOA 50,000.- for residents and non-residents.<br xmlns="http://www.opentravel.org/OTA/2003/05/beta" />2. Foreign currencies:<br xmlns="http://www.opentravel.org/OTA/2003/05/beta" />a. Residents (older than 17 years): up to USD 15,000.- or equivalent;<br xmlns="http://www.opentravel.org/OTA/2003/05/beta" />b. Residents (younger than 18 years): up to USD 5,000.- or equivalent;<br xmlns="http://www.opentravel.org/OTA/2003/05/beta" />c. Non Residents (older than 17 years): up to USD 10,000.- or equivalent;<br xmlns="http://www.opentravel.org/OTA/2003/05/beta" />d. Non Residents (younger than 18 years): up to USD 3,000.- or equivalent. <br xmlns="http://www.opentravel.org/OTA/2003/05/beta" />Exempt: <br xmlns="http://www.opentravel.org/OTA/2003/05/beta" />- If holding a letter (certified by B.N.A./D.O.I.) from a company or entity which took care of payment of all expenses during stay in Angola: foreign currencies up to the amount imported.<br xmlns="http://www.opentravel.org/OTA/2003/05/beta" />- Amounts left with receipts of bills paid or money exchange vouchers. "'
  }
    updateSearch(e) {
    this.searchTerm = e.target.value
  }
}
0 голосов
/ 08 мая 2019

Я использую регулярное выражение для замены всех вхождений поискового термина

export class HighlightPipe implements PipeTransform {
   transform(text: string, search: string): string {
     if (search && text) {
       let pattern = search.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
       pattern = pattern.split(' ').filter((t) => {
         return t.length > 0;
       }).join('|');
       const regex = new RegExp(pattern, 'gi');
       return text.replace(regex, (match) => `<mark>${match}</mark>`);
     } else {
       return text;
     }
   }
}

Редактировать: хммм, думая о том, что вы ищете в html doc, а не просто в текстовом формате, верно?Перед тем как приступить к реальному поиску в трубе, рекомендуется экранировать HTML-теги в тексте.Как превратить < в &lt; ... Я бы проверил это и опубликовал обновление функции, но сейчас я на мобильном ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...