Dynamisches Dropdownmenü: Enter soll nicht IMMER auslösen
sliwalker
- javascript
Hallo,
der Titel beschreibt es nicht komplett.
Ich habe ein input-textfield dass sich per AJAX Daten je nach Tastedruck holt. Dort öffnet sich ein navigierbarer Tooltip. Nun kann man mit Enter einen Eintrag auswählen. Dann wird der Text des Eintrags in das input-textfield übertragen.
Soweit so gut.
Jetzt ist es so, dass ich dem Formular sage, es soll überprüfen ob ein Eintrag aus dem Tooltip ausgewählt wurde.
onSubmit=\"if (detailSearchBranchList.isSomethingSelected()) return false\"
Ist etwas ausgewählt, so wird das Formular nicht abgeschickt, eben weil ja nur Text vom Tooltip zum input-textfield übertragen werden soll.
Jetzt ist ein Eintrag ausgewählt und der Text steht drin. Ein weiteres Enter soll jetzt aber das Formular abschicken. Da die bedingung immer noch zutrifft wird es aber nicht abgeschickt. Auch ein Klick auf den Button wird logischerweise nicht ausgeführt. Ich habe den Button zusätzlich mit
onclick='javascript:document.formDetailSearch.submit();'
belegt, aber das geht natürlich auch nicht.
Ich kann nach dem übertragen des Textes auch nicht einfach die Selection (die mit detailSearchBranchList.isSomethingSelected() überprüft wird) löschen, weil dann schon beim Übertragen das Submit ausgelöst würde.
Hat jemand eine Idee wie man das besser lösen könnte?
Bin für jede Hilfe dankbar.
greetz
SLi
Ich kann nach dem übertragen des Textes auch nicht einfach die Selection (die mit detailSearchBranchList.isSomethingSelected() überprüft wird) löschen, weil dann schon beim Übertragen das Submit ausgelöst würde.
Sorry, aber ich verstehe dein Problem nicht.
Am besten machst du mal eine Beispielseite (ohne Ajax), damit der Ablauf klarer wird. Ich verstehe nicht ganz, warum die Auswahl im Tooltip mit Enter bestätigt werden muss (okay, das erscheint noch logisch), aber warum wird damit das Formular abgesendet? Sind das Formularfelder, auf denen der Fokus liegt?
Allgemein kannst du solche Probleme lösen, indem du eine Variable setzt, die den aktuellen Modus speichert. Also Fokus im Textfeld, Fokus im Tooltip usw. Wenn das Formular abgesendet wird, schaust du, welcher Status gerade aktuell ist und behandelst das Ereignis entsprechend.
Mathias
Jetzt ist ein Eintrag ausgewählt und der Text steht drin. Ein weiteres Enter soll jetzt aber das Formular abschicken. Da die bedingung immer noch zutrifft wird es aber nicht abgeschickt.
Nach dem Übertragen ist der Eintrag ausgewählt, also musst du etwas anderes prüfen als »ist ein Eintrag ausgewählt«.
Hat jemand eine Idee wie man das besser lösen könnte?
Ein Suchfeld, das auch nur für die Suche zuständig ist und mit dem Formular selbst nichts zu tun hat.
Die Auswahl wird dann im per Ajax geladenen Auswahlmenü getroffen. Diese Formularfelder sind dann normativ.
Oder du machst einen klassischen Ajax-Autocomplete, wo das Absenden des Formulars überhaupt nicht mit dem Bestätigen eines Vorschlages verwechselt werden kann - bzw. weil die Vorschläge fokussierbare a-Elemente und keine Formularfelder sind. Die Navigation in den Vorschlägen kann durchaus mit Tastatur möglich sein (Tabulator, Pfeiltasten, Enter). Hat ein Vorschlag den Fokus und drückt man Enter, klappen die Vorschläge zu, der Wert des inputs wird aktualisiert und das input-Feld wird fokussiert.
Mathias
Jetzt ist ein Eintrag ausgewählt und der Text steht drin. Ein weiteres Enter soll jetzt aber das Formular abschicken. Da die bedingung immer noch zutrifft wird es aber nicht abgeschickt.
Nach dem Übertragen ist der Eintrag ausgewählt, also musst du etwas anderes prüfen als »ist ein Eintrag ausgewählt«.
Das ist nicht möglich, weil zum Suchformular diverse andere Felder gehören, die alle ausgefüllt sein können oder auch nicht. Einzige Problematik ist ja dabei, dass das Formular abgeschickt wird, weil das Caret im Textfeld steht, dass zum Formular gehört.
Hat jemand eine Idee wie man das besser lösen könnte?
Ein Suchfeld, das auch nur für die Suche zuständig ist und mit dem Formular selbst nichts zu tun hat.
Die Auswahl wird dann im per Ajax geladenen Auswahlmenü getroffen. Diese Formularfelder sind dann normativ.
Sinn des ganzen war, ein Eingabefeld zu haben, wo Werte dynamisch geladen werden. Zuerst war es ein select-Element, aber bei ca. 5000 Werten und bis zu 5 diser select-Elementen auf einer Seite hat der IE gestreikt. Mozilla konnte es nach eingebautem Caching, damit die Suche nicht jedesmal neu ausgeführt wurde. Sprich, das was in den Vorschlagslisten geladen wird(Tooltip mit li-Elementen HTML-technisch bzw. Objekte in einer Liste als JavaScript-Pendant), sollen dann auch ins Eingabefeld übertragen werden, damit der User es sehen kann und es nach abschicken auch als Suchkriterium genutzt werden kann.
Deshalb meine ich zu verstehen, dass ein Suchfeld das nicht zum Formular gehört, wohl nicht geht. Richtig?
Oder du machst einen klassischen Ajax-Autocomplete, wo das Absenden des Formulars überhaupt nicht mit dem Bestätigen eines Vorschlages verwechselt werden kann - bzw. weil die Vorschläge fokussierbare a-Elemente und keine Formularfelder sind. Die Navigation in den Vorschlägen kann durchaus mit Tastatur möglich sein (Tabulator, Pfeiltasten, Enter). Hat ein Vorschlag den Fokus und drückt man Enter, klappen die Vorschläge zu, der Wert des inputs wird aktualisiert und das input-Feld wird fokussiert.
Eine klassische Ajax-Autocomplete? Was ist denn klassich? Wie oben beschrieben füge ich eine ul-Liste mit li-Elementen auf der Seite ein, die ich mit CSS gestalte und formatiere. Dahinter liegt ein JavaScript Objekt dass eine Liste mit Werten hält und weitere steuervariablen.
Die EventListener habe ich auf die Liste und das zugehörige input-textfield gelegt. Irgendwas daran nicht konform?
Aber ich probiere mal einen Nebensatz von Dir aus. Nämlich das input-textfield bei einem KeyEvent zu fokussiren. Vielleicht hilft das ja gegen das Auslösen des Submits. Oder kann ich den KeyEvent auch konsumieren? zerstören, während ich ihn bearbeite?
Hier mal ein Auszug aus meiner Bearbeitung des Events. Da ein event.consume(9 rein oder so würde ja helfen, denke ich.
function branchListKeyboardAction(element, branchListAutoCompleteListAsParam, branchListTextField, eventIncoming)
{//alert("branchListKeyboardAction");
switch (eventIncoming.keyCode) {
case 27: // ESC
branchListAutoCompleteListAsParam.setVisible(false);
break;
case 38: // KEYUP
branchListAutoCompleteListAsParam.selectPrevious();
break;
case 40: // KEYDOWN
branchListAutoCompleteListAsParam.selectNext();
break;
case 13: // ENTER
//alert("enter");
var selectedObject = branchListAutoCompleteListAsParam.getSelectedObject();
var textField = document.getElementById( branchListTextField );
textField.value = selectedObject.title;
break;
default:
{
var currentEventChar = (String.fromCharCode(eventIncoming.keyCode)).toLowerCase();
var currentValue = element.value;
currentValue += currentEventChar;
if ((currentValue.basicTrim()).length > 2) {
this.branchListAutoCompleteList = branchListAutoCompleteListAsParam;
searchBranch(encodeURI(currentValue));
}
}
}
}
Bitte mal ein funktionierendes Beispiel, so kann ich das echt nicht nachvollziehen bzw. muss mutmaßen:
Der Fokus befindet sich die ganze Zeit im Formularfeld. Die Auswahl in den Vorschlägen erfolgt mit den Pfeiltasten. Die Bestätigung erfolgt mit einem Enter im Formularfeld, wodurch der Feldwert aktualisiert wird.
Klar, wenn du das Modell verfolgst, kommst du in die Bredouille. Ich wüsste auch nicht, wie du das umgehen und eindeutig Enter zum Vorschlag bestätigen und zum Formular absenden unterscheiden kannst. Wie gesagt würde ich dir ein anderes Modell vorschlagen, wo sich dieses Problem überhaupt nicht ergibt.
Wenn es nicht stimmt, was ich oben vermutet habe, und der Fokus auch mal auf einem Element in der Vorschlagsliste liegt: Wieso wird dann, wenn der Fokus dort liegt, das Formular abgesendet beim Drücken von Enter? Behandelt branchListKeyboardAction nur Ereignisse in der Vorschlagsliste oder auch zusätzlich die Ereignisse beim input?
Aber ich probiere mal einen Nebensatz von Dir aus. Nämlich das input-textfield bei einem KeyEvent zu fokussiren. Vielleicht hilft das ja gegen das Auslösen des Submits.
Oder kann ich den KeyEvent auch konsumieren? zerstören, während ich ihn bearbeite?
Standardaktion unterdrücken
Das ist im Grunde das, was du im submit mit return false erledigst. Das geht genauso auch in deiner Handlerfunktion.
Mathias
Bitte mal ein funktionierendes Beispiel, so kann ich das echt nicht nachvollziehen bzw. muss mutmaßen:
Der Fokus befindet sich die ganze Zeit im Formularfeld. Die Auswahl in den Vorschlägen erfolgt mit den Pfeiltasten. Die Bestätigung erfolgt mit einem Enter im Formularfeld, wodurch der Feldwert aktualisiert wird.
Klar, wenn du das Modell verfolgst, kommst du in die Bredouille. Ich wüsste auch nicht, wie du das umgehen und eindeutig Enter zum Vorschlag bestätigen und zum Formular absenden unterscheiden kannst. Wie gesagt würde ich dir ein anderes Modell vorschlagen, wo sich dieses Problem überhaupt nicht ergibt.
Wenn es nicht stimmt, was ich oben vermutet habe, und der Fokus auch mal auf einem Element in der Vorschlagsliste liegt: Wieso wird dann, wenn der Fokus dort liegt, das Formular abgesendet beim Drücken von Enter? Behandelt branchListKeyboardAction nur Ereignisse in der Vorschlagsliste oder auch zusätzlich die Ereignisse beim input?
Aber ich probiere mal einen Nebensatz von Dir aus. Nämlich das input-textfield bei einem KeyEvent zu fokussiren. Vielleicht hilft das ja gegen das Auslösen des Submits.
Oder kann ich den KeyEvent auch konsumieren? zerstören, während ich ihn bearbeite?
Standardaktion unterdrücken
Das ist im Grunde das, was du im submit mit return false erledigst. Das geht genauso auch in deiner Handlerfunktion.Mathias
Hallo Mathias,
vielen Dank für Deine Hilfe.
Das mit dem Fokus macht Sinn. Der Fokus bleibt die ganze Zeit im Textfeld. Die Navigation in der Liste passiert im Prinzip ausschließlich durch die KeyEvents die ich im Textfeld abfange. Somit nützt es nichts den Fokus zu setzen.
Das Problem waren ganz klar die Standarevents. Danke für deinen Link. Das kannste ich noch nicht. "return false" bringt bei mir nichts. Ich kann nicht erklären warum, aber ich vermute dass es entweder am switch liegt, der scheinbar nicht nach einem return aussteigt, sondern erst beim break? Oder es liegt daran, dass ich onKeyPress abfange und der Rückgabewert davon die Standardaktion nicht unterdrücken kann. Ich weiß nicht.
Zumindest geht es jetzt, weil ich folgendes im Eventhandler-Switch eingefügt habe:
if (eventIncoming.preventDefault) {
eventIncoming.preventDefault();
} else {
eventIncoming.returnValue = false;
}
Das funktioniert im Chrome, IE, und Firefox.
Vielen dank nochmal.
greetz
SLi
Das mit dem funktionierenden Beispiel ist leider nicht so einfach.
Du kennst es vielleicht...
Aber da es jetzt funktioniert und die Kernlösung auch hier hinterlegt ist, brauche ich denke ich kein Beispiel mehr posten...