Autor | Zpráva | ||
---|---|---|---|
Tori Profil |
#1 · Zasláno: 23. 11. 2011, 17:35:18
Pěkný večer,
jak by se dalo v JS docílit, aby porovnávání řetězců fungovalo jako v MySQL s utf8_unicode_ci? Totiž: označuju v nějakém textu např.jména spisovatelů, jejich ID vybírám ze selectu v modálním okně. Do okna zároveň posílám označené jméno, aby se mohl předvyplnit formulář na přidání nové položky do číselníku. Chtěla jsem docílit, aby se taky v selectu vybrala položka co nejblíž tomu označenému jménu (kvůli skloňování to málokdy je přesná shoda) - to mi funguje, kromě případů, kdy je ve jméně diakritika. Např.když v selectu jdou za sebou "Kabát, Káča, Kalina, Karas" a dám hledat "Karas", tak mi hledání skončí už na "Káče". Položky selectu procházím takhle: function najdiVSelectu(sel, t) { var ln = sel.length; var missed = false; var part = (t.indexOf(',') == -1 ? null : t.slice(0, t.indexOf(','))); var inic = t.charAt(0); var opt; // console.info('cely text = '+t+", part = "+part); for (var i=0; i<ln; i++) { opt = sel[i].text; // console.info(t, opt, part); if (inic == opt.charAt(0)) { missed = true; if (opt.indexOf(t) == 0) { /* shoda */ sel[i].selected = true; break; } else if (opt > t) { /* jsme za */ if (part != null && opt.indexOf(part) == 0) { /* da se hledat jen cast a shoduje se */ sel[i].selected = true; } else { /* nelze hledat cast = oznac predchozi */ sel[(i-1)].selected = true; } break; } /* neni option od stejne inicialy = pouzij predchozi. pokud predchozi neexistuje, nic se nedeje, prvni je implicitne vybrany. */ } else if (missed === true) { sel[(i-1)].selected = true; break; } } } Zatím mě napadlo jen použít něco jako tady. Není nějaký jednodušší postup, než každou z řekněme pár stovek položek selectu převádět na nějaký porovnávatelný řetězec? Díky moc za radu a pardon za nevelmi pěkný kód. |
||
__construct Profil |
#2 · Zasláno: 23. 11. 2011, 20:24:58 · Upravil/a: __construct
Tori:
Pokiaľ som správne pochopil čo chceš: Predpokladám, že mená autorov máš uložené v nejakej databázi. Dobré riešenie by bolo pridať do tabuľky stĺpec s oddiakritizovaným menom malými písmenami jednorázovo pri vypĺňaní tabuľky. Potom pri hľadaní prevedieš hľadaný výraz do takej istej formy a pohľadáš ho v tabuľke. |
||
Tori Profil |
#3 · Zasláno: 23. 11. 2011, 21:28:48 · Upravil/a: Tori
__construct:
Díky, to by určitě šlo, jen obsah selectu se dynamicky mění a položky tahám AJAXem, tak jsem to chtěla proto řešit až v browseru. Příště zkusím použít váš návrh, zatím jsem to udělala takhle: var collation = {}; /* Porovná dva řetězce, vrací 0 = shoda, -1 = první je větší, 1 = druhý je větší */ function strcmp(s1, s2) { if (collation['a'] == undefined) { // anebo je lepší Object.keys(collation).length == 0 ? /* znaky v každé skupině se porovnávají stejně jako první z nich */ var chars = [ 'aáäàãâ', 'b', 'cćč', 'dď', 'eéěëèê', 'f', 'g', 'h', 'iíïìî', 'j', 'k', 'lĺľ', 'm', 'nńňñ', 'oóôòõöő', 'p', 'q', 'rŕř', 'sśš', 'tť', 'uúùůüũû', 'v', 'w', 'x', 'yý', 'zźž' ]; var key,val; for (var i=0; chars[i] !== undefined; i++) { key = chars[i].charAt(0); var j=0; while (val = chars[i].charAt(j)) { collation[val] = key; collation[val.toUpperCase()] = key; j++; } } } /* porovnává jen počet znaků podle kratšího slova */ var ln = Math.min(s1.length, s2.length), l1, l2; for (var i=0; i<ln; i++) { l1 = s1.charAt(i); l2 = s2.charAt(i); if (l1 == l2) { continue; } else if (collation[l1] > collation[l2]) { return -1; } else if (collation[l2] > collation[l1]) { return 1; } } return 0; } /* označí nejbližší položku v selectu. 1.param = <select> prvek, 2.param = hledaný text */ function searchSel(sel, t) { var ln = sel.length; var missed = false; var inic = t.charAt(0).toUpperCase(); var opt,cmp; for (var i=0; i < ln; i++) { opt = sel[i].text; /* počítá se s tím, že položky jsou seřazené podle abecedy, takže nejdřív kontroluje iniciálu */ if (inic == opt.charAt(0).toUpperCase()) { missed = true; cmp = strcmp(t, opt); if (cmp > -1) { sel[(i-cmp)].selected = true; return null; } } else if (missed === true) { sel[(i-1)].selected = true; return null; } } } |
||
Časová prodleva: 12 let
|
0