Usuniecie elementu span i przeszukanie stringow.

0

Witam,

Mam stringi:

<span class="image"><img src="/img/photo1.png"</span>Sample 1
<span class="image"><img src="/img/photo2.png"</span>Sample 2
<span class="image"><img src="/img/photo3.png"</span>Sample 3
(...) itd

To sa podpowiedzi w liscie autocomplete.

Uzytkownik wpisuje szukana fraze np 'sp' albo 'an' to tylko przyklad. Co chce zrobic to wyszykac tych fraz tylko w tekscie, musze zignorowac element span.

Mam cos takiego:

    value.replace(new RegExp(pattern, modifier), '<strong>$1<\/strong>');

Moge usuwac i dodawac ten span element po przez jQuery. Ale wole zrobic to przy pomocy wyrazen regularnych.

0

Korzystasz z jakiejś biblioteki? jQuery/Angular/itp itd? Jeśli tak to może lepiej sobie przefiltruj te wyniki bez regexpa. To co masz obecnie - wskazuje mi, że albo gdzieś niepoprawnie ogarnąłeś autocomplete'a albo korzystasz z dziwnego pluginu. Pamiętaj, że do autocomplete'a zazwyczaj masz taki zestaw danych - klucz->wartość. Jeśli możesz to sprawdź czy w wartości nie możesz wsadzić obiektu i tam definiować pola możliwe do przeszukania.

0

@axelbest Korzystam z jQuery. Ale biblioteka jest mega stara. Nie moge jej zaktualizowac. Poniewaz, ktos zaczal ja modyfikowac :D I teraz jak zauktualizuje to bede musial dostosowaywac ja w kilkunastu miejscach w projekcie. Takze moge to ogarnac wylacznie przez wyrazenie regularne, albo zostawic chamskie rozwiazanie z usuwaniem/dodwaniem elementu span za pomoca jQuery. Nie ma innej opcji. Niestety. To jest bardzooo stara biblioteka. Kod jest dosc stary i banalny.

0

Funckcja do przeszukiwania wyglada tak:

  function fnFormatResult(value, data, currentValue) {
    var pattern = '(' + currentValue.replace(reEscape, '\\$1') + ')',
        modifier = '';
    if(currentValue.length == 1) {
        modifier = 'i';
    } else {
        modifier = 'gi'
    }
    return value.replace(new RegExp(pattern, modifier), '<strong>$1<\/strong>');
  }

To jest ta biblioteka: http://www.devbridge.com/projects/autocomplete/jquery/

Ale uzywa w mega starej wersji.

3

A jak działa ten Twój autocomplete? Ogólnie ja bym zrobił tak, że oddzielnie bym trzymał tekst, a oddzielnie miał funkcję renderującą te opcje. Coś takiego http://jsfiddle.net/L81qh9u0/3/

0

@Desu Wszystko fajnie wyglada. Zgadzam sie z podejscie, ale nie usuwasz w zadnym momencie elementu span. Czy czegos nie rozumiem?

0

Nie, bo po co? Oddzielnie trzymam opcje w takim formacie:

 [
    'To Kill a Mockingbird',
    'Pride and Prejudice',
    'The Diary of Anne Frank',
    '1984',
    'Harry Potter and the Sorcerer\'s Stone',
    'The Lord of the Rings',
    'The Great Gatsby'
  ]

A oddzielnie je renderuję. Najpierw filtruję opcje, tworząc nową tablicę zawierającą tylko te, które chce, a później lecę po tych odfiltrowanych i tworzę HTML.

0

Wszystko fajnie, ale ja musialbym przerabiac jQuery biblioteke, zeby dzialala w taki sposob. A tego nie chce robic.

0

A nie wolisz napisać czegoś własnego? To dosyć łatwe i fajne ćwiczenie :D Jak chcesz, żebym Ci pomógł z tą biblioteką, to przygotuj proszę JSFiddle tak, żebym mógł sobie tam coś porzeźbić (dołącz też wersję biblioteki, którą używasz).

Ta funkcja, która jest niby do przeszukiwania na pewno jest do przeszukiwania, a nie do formatowania opcji? Nazywa się fnFormatResult, więc..

0

Pewnie, ze wolabym. Ten kod co przeslales wyglada mega dobrze. Niecale 50 linii kodu i bardzo czytelne. Ale jak pisalem, nie moge zmienic biblioteki. Ona jest uzyta w kilku miejscach w projekcie. Nie chce na jednej podstronie dodwac mojego rozwiazania. Wole trzymac wszytko spojnie w tym wypadku.

0

Okej, dasz rade podesłać JSFiddle?

0

Niebardzoo, bedzie sporo roboty :/ Nie dasz rady czegos podpowiedzic na podstwie funkcji, ktora podalem w wyzej?


  function fnFormatResult(value, data, currentValue) {
    var pattern = '(' + currentValue.replace(reEscape, '\\$1') + ')',
        modifier = '';
    if(currentValue.length == 1) {
        modifier = 'i';
    } else {
        modifier = 'gi'
    }
    return value.replace(new RegExp(pattern, modifier), '<strong>$1<\/strong>');
  }

0

Pokaż jak inicjalizujesz to, czyli coś w stylu: $().autocomplete({}). Chciałbym zobaczyć config.

0

$('#sample').autocomplete({
    serviceUrl: '/autocomplete',
    params: {
        type: 'lista'
    },
    minChars: 2,
    delimiter: /(,|;)\s*!/,
    maxHeight: 200,
    width: 450,
    zIndex: 100,
    deferRequestBy: 0,
    noCache: true
});

0

Czekaj, z tego co widzę, to Twoje opcje pochodzą z backendu, mam rację?
I jeszcze raz, bo nie wiem, czy dobrze zrozumiałem problem. Jak wpisujesz "span" to pokazuje Ci wszystkie opcje, bo każda opcja zawiera tekst (HTML) span?

0

Tak, tak. jQuery lib wysyla request do servera przez Ajaxa. Ten span jest dodwany przeze mnie w backendzie. Dlatego, nie chce sie rozczulac i zrobic to przez reg expressions.

Tak, jak wpisze jakiekolwiek litery ze zbioru span to <strong> jest tez dodwany do <span>.

Szukaj: an:
Powinno byc:

<span class="image"><img src="/img/photo1.png"</span><strong>An</strong>na Latwa

A jest tak:

 <sp<strong>an</strong>class="image"><img src="/img/photo1.png"</sp<strong>an</strong>><strong>An</strong>na Latwa
1

Dobra to wszystko jasne. Nie masz problemu z przeszukiwaniem, tylko formatowaniem wyników. Chcesz pogrubić wyszukiwaną frazę w każdym z wyników. Mam rację?

0

@Desu Tak, masz racje. Przepraszam za zle zlozone pytanie.

1

Luzik, czasami trudno ubrać w słowa to, co chcemy zrobić. W takim razie proponuję coś takiego:

const testString = `<span class="image anna">
  <img src="/img/photo1.png"</span>Anna Latwa
  <i>anna Latwa</i>
</span> Anna Latwa`;

const query = 'An';
const pattern = new RegExp(`(${query})(?!([^<]+)?>)`, 'gim');

const result = testString.replace(pattern, '<strong>$1</strong>');

To nam znajduje query, które
a) jest pomiędzy tagami HTML, czyli

<span>Anna</span>

b) jest poza tagiem HTML, czyli:

<span></span> Anna

Nie zmatchuje natomiast czegoś takiego:

<span class="anna"></span>

Po czym podmienia wystąpienia owijając je tagami <strong></strong>.

0

@Desu wow, to jest to czego szukam :)

Napisz mi co oznaczaja ukosne znaczki ` (ukosnego cudzyslowa)? Czy to jest zaciagniete z reactjs?

Musze je usunac z wyrazenia:

var pattern = new RegExp(`(${query})(?!([^<]+)?>)`, 'gim');

Inaczej nie bedzie dzialac z jQuery. No, ale jak je zastapie ' to wyrazenie przestaje dzialac. Przetestowalem w konsoli dziala dobrze, ale nie w pliku jQuery.

1

Serio? To chyba nie powinno mieć znaczenia.

W każdym razie tu masz napisane, co to jest https://developer.mozilla.org/pl/docs/Web/JavaScript/Referencje/template_strings

A można to zastąpić zwykłym łączeniem znaków:

const pattern = new RegExp('(' + query + ')(?!([^<]+)?>)', 'gim');

To ficzer nowego (w sumie już starego) standardu javascript. Nie ma nic wspólnego z reactjs :)

0

Super, teraz dziala. Dzieki! Jak sie nauczyles tych wyrazen regularnych? Tez chce je umiec :)

2

Szczerze? Zawsze googluje :D jak już znajde wyrażenie, które działa, albo prawie działa, to używam takiej strony: https://regex101.com/. Tam z prawej strony masz napisane co oznacza dana cześć wyrażenia. I po prostu starałem się je zrozumieć. Z czasem zaczynasz zapamiętywać rzeczy, które się najczęściej przydają. Nigdy nie uczyłem się ich na pamięć.

2

Dla mnie regexy to coś strasznego. Czasem jak muszę to coś z nimi robię, ale zawsze w wielkich męczarniach i z poczuciem niesmaku ;)

1

@cerrato: Ja mam podobne odczucia. Najgorsze w tym wszystkim, ze dobrze by bylo, zeby je umiec. A jak juz umiesz, to uzywasz je raptem z 3-5 razy w ciagu calego roku, noo moze delikatwie czesciej 10 razy :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1