input type=search, datalist und action
beatovich
- html
- javascript
hallo
Ich habe in der https://beat-stoecklin.ch/nav_demo.html ein Suchformular mit datalist wie folgt.
<form class="search" onsubmit="this.action=document.getElementById('fsearch').value">
<input id="fsearch" type="search" list="pages" placeholder="🔍">
<datalist id="pages">
<option value="pub/kontakt.html">Kontakt</option>
<option value="pub/kontakt.html#impressum">Impressum</option>
<option value="pub/musik-gitarrenunterricht-laufental.html">Musik: Gitarrenunterricht</option>
<option value="https://wiki.selfhtml.org/wiki/Benutzer:Beatovich">SelfHtml: Bugreport</option>
<option value="klapperlogic.html">Javascript: Klapper-Logic</option>
<option value="/">Home</option>
</datalist>
<button type="submit">🔍</button>
</form>
Gibt es eine einfache Abfrage, ob der submittete String einem option.value entspricht, so dass ich andernfalls darauf reagieren kann und einen Query-String auf eine Suchseite senden kann?
danke für Tipps.
Hallo beatovich,
der Gunnar-Hinweis: Dein Input ist nicht beschriftet. Placeholder sind keine Beschriftung. Ob ein Lupensymbol im Submitbutton hinreichend bedienbar ist, weiß ich nicht.
solltest Du value und Option-Text vertauschen, sonst steht nachher die Adresse im Eingabefeld. Das willst Du nicht, glaube ich.
Du könntest mit querySelectorAll die Options der Datalist einsammeln und die values dieser Options mit dem Suchfeld vergleichen.
Rolf
hallo
- der Gunnar-Hinweis: Dein Input ist nicht beschriftet. Placeholder sind keine Beschriftung.
Ja es fehlt ein aria-label beim Button. Aber label können auch anderswo notiert sein, und das ist hier der Fall.
- solltest Du value und Option-Text vertauschen, sonst steht nachher die Adresse im Eingabefeld. Das willst Du nicht, glaube ich.
Es wird bei datalist der Inhalt von Optionen durchsucht. In deinem fiddle sind die option values nutzlos.
Und da bei gefundener Adresse diese wohl auch gesendet wird, ist mir egal ob die im Textfeld steht.
- Du könntest mit querySelectorAll die Options der Datalist einsammeln und die values dieser Options mit dem Suchfeld vergleichen.
Oder einfacher, bei erstellen des Formulars alle values in ein Object aufnehmen. Existiert die Object-Eigenschaft nicht, handelt es sich um einen unabhängigen Querystring.
Hallo beatovich,
Es wird bei datalist der Inhalt von Optionen durchsucht. In deinem fiddle sind die option values nutzlos.
Das ist ein Browserunterschied. Ich habe Chrome verwendet, der durchsucht beides. Ich wusste nicht, dass der Fuchs das anders macht. Sorry.
Oder einfacher, bei erstellen des Formulars alle values in ein Object aufnehmen.
Klar, kann man machen. Die Schleife, die die Options durchläuft, brauchst Du aber auf jeden Fall. Egal ob im JS oder serverseitig. Das Index-Objekt ist eine Mikrooptimierung, die eine halbe Millisekunde spart und dafür mehr Speicher belegt.
Rolf
hallo
Klar, kann man machen. Die Schleife, die die Options durchläuft, brauchst Du aber auf jeden Fall.
Warum denn?
Wenn ich datalist dynamisch zusammnbaue, kann ich gleich ein JS-Object füttern. Da muss ich doch nicht mehr die html-optionen durchlaufen.
Es wird ja nicht mal selected in den html-options gesetzt.
Egal ob im JS oder serverseitig. Das Index-Objekt ist eine Mikrooptimierung, die eine halbe Millisekunde spart und dafür mehr Speicher belegt.
hallo
Gibt es eine einfache Abfrage, ob der submittete String einem option.value entspricht, so dass ich andernfalls darauf reagieren kann und einen Query-String auf eine Suchseite senden kann?
Ich mache sowas immer serverseitig und da gibt es mehrere Möglichkeiten:
1. den submitteten Eintrag gibt es
2. den submitteten Eintrag gibt es nicht
3. der submittete Eintrag ist nicht zulässig
Das ganze Form dient der Einstellung eines neuen Eintrages, Bearbeiten und Löschen. Die Fälle (1) und (2) sind im nachgelagerten Formular eindeutig sichtbar, bei (3) erfolgt eine Fehlermeldung. In dem Moment wenn der Focus das Eingabefeld verlässt, geht der aktuelle Value ab zum Server und dort erfolgt ein Checkout. Mit der Response werden die restlichen Formularfelder befüllt und sofern es sich um einen validen neuen Eintrag handelt, steht da überall undefined
damit man das auch sieht. Ansonsten sind die ausgecheckten Daten nicht zu übersehen.
MfG
hallo
https://beat-stoecklin.ch/nav_demo.html
Enthält nun eine neue Suchformular-Komponente als js.datei
Eventuell könnt ich ja generell den Einbau von einem implementierten datalist abhängig machen.
Zukunftsmusik: eigentlich sollt eine sitemap als Quelle für die datalist verwendet werden.
Ich nehme wie immer Bugs entgegen.
// USAGE
//
// insert this Code, where you want the form to appear
// <div hidden id="searchPages" data-searchUri=""></div>
//
// embed the script
// <script src="js/searchPages.js"></script>
var submitSearchPage =( function(){
var searchPages={
defs: [
["pub/kontakt.html" , "Kontakt Email"],
["pub/kontakt.html#impressum" , "Impressum Datenschutz"],
["pub/musik-gitarrenunterricht-laufental.html" , "Musik Gitarrenunterricht"],
["https://wiki.selfhtml.org/wiki/Benutzer:Beatovich" , "SelfHtml Bugreport"],
["klapperlogic.html" , "Javascript Klapper-Logic"],
["/" , "Home"]
],
searchUri:false,
form : '<label tabindex="0" for="fsearch" aria-label="Suche" title="Suche">🔍</label>\
<form class="search" onsubmit="submitSearchPage(event, this)">\
<input id="fsearch" type="search" list="searchPages" placeholder="🔍">\
<datalist id="searchPages"></datalist>\
<button aria-label="Suche starten" type="submit">🔍</button>\
</form>',
uri: {},
};
function submitSearchPage(ev, form){
var url = document.getElementById('fsearch').value;
if(searchPages.uri[url] != undefined){
form.action=url;
}
else if(searchPages.searchUri){
form.action = searchPages.searchUri+"?"+url;
}
else{
ev.preventDefault();
return false;
}
}
function initSearchPages(){
searchPages.root = document.getElementById("searchPages");
if(! searchPages.root) return;
if(searchPages.root.dataset.searchUri != undefined){
searchPages.searchUri = searchPages.root.dataset.searchUri;
}
searchPages.root.outerHTML=searchPages.form;
searchPages.links=document.querySelectorAll("a[href]");
for(var i=0; i < searchPages.links.length; i++){
if(! searchPages.links[i].href.match('#') ) searchPages.defs.push( [ searchPages.links[i].href , searchPages.links[i].innerText ] );
}
searchPages.datalist=document.getElementById("searchPages");
for(var i=0; i < searchPages.defs.length; i++){
var el= document.createElement("option");
el.value=searchPages.defs[i][0];
el.innerText=searchPages.defs[i][1];
searchPages.uri[ searchPages.defs[i][0] ] = searchPages.defs[i][1] ;
searchPages.datalist.append(el);
}
}
document.addEventListener('DOMContentLoaded', initSearchPages, false);
return submitSearchPage;
})();