Autor | Zpráva | ||
---|---|---|---|
ForestCZE Profil |
#1 · Zasláno: 12. 5. 2020, 01:34:47
Zdravím, mám následující kód:
function Searching() { $("#insuranceSearching").keyup(function(){ let val = $(this).val(); let url = window.location.href; window.location.replace(url + "&search=" + val); }); } Když začnu psát do inputu, změní se mi odkaz a hodnota v GET. Problém je v tom, že to refreshne stránku. Jak to udělat bez refreshnutí? Děkuji předem za pomoc. |
||
Kajman Profil |
#2 · Zasláno: 12. 5. 2020, 02:14:12
Můžete to dávat do hash části místo do query stringu. Tedy za znak # - to se ma server neposílá.
|
||
Keeehi Profil |
Ale jo, jde to.
Živá ukázka Kvůli history API - replaceState to má omezení hlavně na IE10+. To je nutné pro manipulaci s tou url, bez toho to nejde. Pak pro vytvoření nové url (přidání, nebo nahrazení searche v query stringu) jsem použil URL API. To má ještě horší podporu ale pro jednoduchost ukázky to bylo výhodné. Není to však nutné a pokud si ten string zvládneš sestavit jinak dá se to klidně vynechat. Smazání searche v obecné url není vůbec nic triviálního. Po nějaké době testování jsem přišel na toto, což funguje celkem dobře, ale může to mít své mouchy. window.location.href.replace(/(?<=[&?])search=[^&]*&*/g,"") ? , nebo & , nebo vůbec nic a pak search=<hodnota>
No a nebo když použiješ tu Kajmanovu metodu s hashem, bude ti to fungovat i ve starších prohlížečích. Je tam trochu problém s tím, že hash se na server neodesílá, takže výsledky hledání se nemohou vrátit ihned, když někdo na takovou stránku přijde z odkazu, ale bude se muset nejdříve načíst prázdná* stránka a pak odeslat ajaxový požadavek s hledáním. Takže to bude déle trvat. *prázdná znamená search=""
Samozřejmě optimální řešení by bylo udělat kombinaci obou, kde moderní replaceState by byla preferovaná varianta s fallbackem na hash variantu. Ovšem to už je docela komplexní systém. Jinak do té ukázky jsem přidal ještě jednu featuru. Ten search se nedělá okamžitě, ale až s 300ms zpožděním. Je zbytečné posílat požadavek s každým úhozem uživatele. Stačí to přece až když dopíše. |
||
ForestCZE Profil |
#4 · Zasláno: 12. 5. 2020, 12:54:19
Kajman:
Děkuji Keeehi Tušil jsem, že to bude složitější. Moc děkuji za živou ukázku a za pěkné vysvětlení. Nějak to zkusím a popřípadě ještě napíšu. |
||
Časová prodleva: 12 dní
|
|||
ForestCZE Profil |
Pokoušel jsem se to přepsat na JS
function searching() { var searchTimeout; var searchExamination = function(){ var xhttp; xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function(){ if(xhttp.readyState === 4 && xhttp.status === 200) document.getElementById("snippet--examinations").innerHTML = "Whatever"; xhttp.open("POST", window.location.href, true); xhttp.send(); }; }; var examination = document.getElementById("examinationSearching"); if(examination !== null) { examination.addEventListener("keyup", function(){ clearTimeout(searchTimeout); var value = this.value; var url = new URL(window.location.href); url.searchParams.set("search", value); window.history.replaceState({}, "", url.toString()); searchTimeout = setTimeout(searchExamination, 300); }); } } Fce searchExamination se provede, soudě podle console, ale ten ajax se neprovede. Co dělám špatně? |
||
Kajman Profil |
#6 · Zasláno: 24. 5. 2020, 08:15:29
Asi máte open a send v místě, které se vykoná až po vyřízení požadavku. Ten se tedy nikdy nepošle. Ty metody dejte až za definici návratové funkce.
|
||
ForestCZE Profil |
Kajman:
Já hlupák. Vůbec jsem si toho nevšiml. Moc děkuji :) |
||
lionel messi Profil |
#8 · Zasláno: 24. 5. 2020, 08:30:50
ForestCZE:
Ako píše Kajman: var searchExamination = function(){ var xhttp; xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function(){ if(xhttp.readyState === 4 && xhttp.status === 200) document.getElementById("snippet--examinations").innerHTML = "Whatever"; }; xhttp.open("POST", window.location.href, true); xhttp.send(); }; |
||
ForestCZE Profil |
Ještě jedna věc - s JS defacto začínám. V jQuery mám:
success: function(data){ $("#snippet--examinations").html(data.snippets['snippet--examinations']); } Jak tedy získám data? Zkoušel jsem: document.getElementById("snippet--examinations").innerHTML = xhttp.responseText.snippets['snippet--examinations']; Ale nefunguje. Jak by to mělo být? |
||
ForestCZE Profil |
#10 · Zasláno: 24. 5. 2020, 10:04:26
Tak jsem zjistil, že přes jQuery se ta data vrací jako JSON a JS to vrací jako string. Lze to nějak nekomplikovaně převést na JSON?
|
||
lionel messi Profil |
#11 · Zasláno: 24. 5. 2020, 10:14:23
|
||
ForestCZE Profil |
lionel messi:
Problém je, že ta data nejsou v JSON formátu. Tudíž ani nechápu, jaktože je jQuery jako JSON vrací. JSON.parse jsem samozřejmě zkoušel, ale dostanu: Uncaught SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse (<anonymous>) at XMLHttpRequest.xhttp.onreadystatechange |
||
Kajman Profil |
#13 · Zasláno: 24. 5. 2020, 12:30:28
ForestCZE:
„Problém je, že ta data nejsou v JSON formátu.“ Pokud není možné použít JSON formát, napište si vlastní parser podle Vašeho formátu dat. |
||
Serg Profil |
#14 · Zasláno: 24. 5. 2020, 13:30:02
ForestCZE:
„Tudíž ani nechápu, jaktože je jQuery jako JSON vrací.“ Záleží kterou metdou se ten AJAX volá. Základní metodou je $.ajax , tam je parametr dataType, který když se nezadá, tak zkusí formát dat uhodnout, a asi si jQuery myslí že data vypadají jako json. Ostatní metody jako $.get(), $.post(), $.getJSON() jsou jen kratší zápisy pro $.ajax() s jiným výchozím nastavením, ale jen $.getJSON přenastavuje dataType na "json", u ostatních by to mělo zůstat výchozí, tedy že to jQuery zkusí uhodnout.
„Problém je, že ta data nejsou v JSON formátu.“ Možná by stálo za to ten dataType nastavit např na "html", nebo "text" pokud server nevrací výsledek v JSON formátu. Dokumentace tady: api.jquery.com/jquery.ajax Trochu níž je popsaný dataType a jaký hodnoty jdou nastavit a co dělají |
||
Keeehi Profil |
Na to hádání datového typu ajaxem v jquery pozor. Když si to totiž myslí, že odpověď je javascript, nebo html s javascriptem, tak ten javascript bezostyšně spustí. V kombinaci s uživatelským vstupem v hledání to může teoreticky způsobovat XSS zranitelnost. Proto je vždy dobré dataType explicitně uvádět.
|
||
ForestCZE Profil |
Kajman:
„Pokud není možné použít JSON formát, napište si vlastní parser podle Vašeho formátu dat.“ Nakonec jsem zjistil, že stačí přidat: xhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest"); Momentálně to vrací: {"state":{"emsid":"17ba0791499db908433b80f37c5fbc89b870084b"},"snippets":{"snippet--examinations":" <table class=\"tab tab_h\">\n <tr>\n <th>Jméno</th>\n <th>Narozen(a)</th>\n <th>Druh</th>\n <th>Výsledky</th>\n <th>Zapsáno</th>\n <th>Provedl(a)</th>\n <th>Vyřešil(a)</th>\n </tr>\n \n </table>\n"}} Potřebuji z toho dostat "snippet--examinations" Předpokládám, že to budu muset parsovat, takže něco jako: var json = JSON.parse(xhttp.response); // A nevím, jak to získat. Jestli to chápu správně, tak je to celé vnořené do state EDIT: Tak snad takto: var json = JSON.parse(xhttp.response); console.log(json["snippets"]["snippet--examinations"]); |
||
Časová prodleva: 5 let
|
0