Denkanstoß: Auswahl per Pfeiltasten @ Autovervollständigung

Templorials

Erfahrenes Mitglied
Grüß euch..

Ich hab mir gerade mit Hilfe von AJAX ein Autovervollständigunsscript gebastelt, was eigentlich auch wunderbar funktioniert.

Jedoch kann man bist jetzt die Vorschläge nur per Maus auswählen.. Es wäre natürlich schön wenn man auch mit den Pfeiltasten rauf und runter und mit Enter die auswahl bestätigen könnte.

Jedoch weiß ich nicht wie ich das realisieren könnte.

Zurzeit is die Ausgabe so das unter dem Input Feld einfach ein div mit den Vorschlägen erscheint..

MFG Michael
 
Du könntest denn onkeydown-Event-Handler benutzen, mit dem man fast alle Tasten abfangen kann (selbst F1 - F12).

Schönen Tag noch
Master of Chess
 
Wie Master of Chess bereits sagte , lege einfach einen keyDown Event auf das gesammte Dokument und frage dann den Tasten Schlüssel ab von der Taste die eben gedrückt wurde.

Hier ein kleiner Code Schnippsel von meiner Funktion die ich dies bezüglich gemacht habe , selbes Projekt Auto Suggest mit Tasti Navi ;)

38 ist pfeiltaste rauf
40 ist Pfeiltaste nach unten
13 wäre die Return Taste

naviElement ist quasi der Layer wo dann alle Objekte drinnen liegen.

Es sei hier noch angemerkt das der Event expliziet noch für den IE nun festgelegt werden müsste , ich schick den Event aber vorher zu einer anderen Funktion welche das für mich erledigt welche dann alles an diese Funktion weiterleitet und den aktuellen Event schon weiter leitet also so das er auch für den IE gültig ist. Sonst müsstest hier noch den Event anpassen da es sonst nicht im IE klappen würde.

Code:
                function keyPressed (evt) {
                    var curKey = evt.keyCode;
                                    
                    switch (curKey) {
                        case 38:
                            if(curElement && curElement.previousSibling) {
                                curElement = curElement.previousSibling;                                
                            }
                        break;
                        case 40:
                            if(curElement) {
                                if(curElement.nextSibling) {
                                    curElement = curElement.nextSibling;
                                }
                            } else {
                                curElement = naviElement.firstChild;
                            }
                        break;
                        case 13:
                            if(curElement) {
                                alert(curElement.firstChild.nodeValue);
                            }
                        break;
                        default:  return;
                    }
                }

Probleme die Du bekommen könntest , wären zum Beispiel das scrollen des layers wo die Elemente drinnen liegen sofern du overflow als CSS gesetzt hast , weiss nicht ob man nun ein Focus auf ein DIV Element legen kann, da dieser sich dann nicht mit scrollt.
Naja kurz um es eskaliert und Du darfst Dich schon mal mit dem Gedanken anfreunden eigene Scrollbars zu programmieren.
 
Zuletzt bearbeitet:
Hi..

dankesehr!

die Idee hatte ich auch schon..
jedoch schaff ich das irgentwie nicht umzusetzten.. auch mit deinem Schnipsel nicht :(

hm..
 
Nun gut hier mal der 2. Anlauf von mir damals

wo es nur um die Key Navigation geht an sich.

Man möge mir meine Tab Taste drückerei verzeihen hatte damals noch nicht die Option an das er es als normalen Space rechnet nunja sieht nen bissel verkorkst aus wohl.
Code:
<html>
	<head>
        <style type="text/css">
            div.showLayer {
                height:60px;
                width:200px;
                overflow:auto;
            }
        </style>
		<script type="text/javascript">
		   /**
			* Hilfsfunktion für Eventhandling
			* @access public
			* @param Object element , welches Object den Event auslöst
			* @param String type , welcher Eventhandler kommt in Frage
			* @param String callBack , callBack Funktion welche den event verarbeitet
			* @param Object returnParams optionale Rückgabe Parameter
			* @return object event;
			* @return object html object;
			*/
			function eventHandling(element,type,callBack,returnParams) { 
				/*
				  * eventhandler festlegen
				  */				  
				var returnParams = returnParams;				
				  
				if(document.addEventListener) { //gute Browser
					if(type.match(/^on/)) type = type.replace(/^on/,"");
						element.addEventListener(type,handleEvent,false);
				} else { // IE
					if(!type.match(/^on/))	type = "on"+type; 
						element.attachEvent(type,handleEvent);
				}
				
				function handleEvent (evt) {
					
					var event  = (evt)?evt:(window.event)?window.event:'';
								
						if(event.stopPropagation) {
							event.stopPropagation();
						} else {
							event.cancelBubble = true;
						}
						
						var target = event.srcElement || event.currentTarget;						
					
					callBack.call(callBack,event,target,(returnParams)?returnParams:null);
				}
			}
			
			function keynavigation (obj) {
			
                var curElement  = null;
                var naviElement = null;
                            
                function clearSpaces (strOut) {
                    strOut = strOut.replace(/>\s+/gm,'>');	
            		strOut = strOut.replace(/\s+</gm,'<');			
            		strOut = strOut.replace(/>\s+</gm,'><');
            					                                
            		return strOut;
                }
                            
                function keyPressed (evt) {
                    var curKey = evt.keyCode;
                                    
                    switch (curKey) {
                        case 38:
                            if(curElement && curElement.previousSibling) {
                                curElement = curElement.previousSibling;                                
                                document.getElementById('check').innerHTML = curElement.firstChild.nodeValue;
                            }
                        break;
                        case 40:
                            if(curElement) {
                                if(curElement.nextSibling) {
                                    curElement = curElement.nextSibling;
                                    document.getElementById('check').innerHTML = curElement.firstChild.nodeValue;
                                }
                            } else {
                                curElement = naviElement.firstChild;
                                document.getElementById('check').innerHTML = curElement.firstChild.nodeValue;
                            }
                        break;
                        case 13:
                            if(curElement) {
                                alert(curElement.firstChild.nodeValue);
                            }
                        break;
                        default:  return;
                    }
                }
            
				this.init = function () {
                    eventHandling(document,"keydown",keyPressed);
                    obj.innerHTML = clearSpaces (obj.innerHTML); 
                    naviElement   = obj;
                }
			
			}
			
			window.onload = function () {
				var k = new keynavigation(document.getElementById('navitree'));
					k.init();
			}
		</script>
	</head>
	<body>
        <div class="showLayer">
    		<ul id="navitree">
    			<li>Halle</li>
    			<li>Merseburg</li>
    			<li>Querfurt</li>
    			<li>Leipzig</li>
    			<li>Hamburg</li>
    			<li>Berlin</li>
    		</ul>
        </div>
        <div id="check"></div>
	</body>
</html>

Wie Du sehen kannst gibt es eine HTML Liste mit einigen Städten nun , diese Liste schicke ich direkt an die KeyDown Klasse hoch.

Als Hilfsfunktion nutze ich die Eventhandling Funktion womit wir dann diesen keyDown Event auf dem gesammten Dokument regestrieren einfach in der init.
 
Zuletzt bearbeitet:
Hi, danke bin jetzt doch mit der Funktion alleine zurecht gekommen..

Das erste Ergebniss kann ich schonmal auswählen.. jedoch weiter nicht mehr

Irgentwie funktionieren next/previousSibling nicht.. hab das mal extern ausprobiert..

bei:
Code:
<div id="searchpanel">
<div id="search_1">bla</div>
<div id="search_2">bla</div>
<div id="search_3">bla</div>
</div>

funktionert zwar searchpanel -> firstChild.. da bekomm ich search_1.
Jedoch search_1 -> nextSibling gibt mir undefinied...

Habs auch mit einer Liste versucht..
 
Ja das macht dein Script soweit schon richtig , genau genommen ist die nextSibling auch undefined vom Inhalt her.

Es klingt nun komisch aber gibst Du Dir mal den nodeType aus dann wirst Du sehen das dieser Knoten nur #text heisst und nicht li oder div oder ähnliches , kurz um es sind alle knoten Punkte die er nun findet die Leerzeichen im DOM Baum.

Code:
<ul>
    <li>element_0</li>#text
    <li>element_1</i>#text
     ...
    <li>element_n</li>#text
</ul>

alles was als #text makiert ist , sind sozusagen freizeichen im HTML Code seien es Zeilenumbrüche beim Editieren oder Freizeichen die man selber rein gearbeitet hat.
Schreibst alles brav hintereinader gibt es damit keine Probleme mehr.

Oder aber hier diese Lösung.
Code:
obj.innerHTML = clearSpaces (obj.innerHTML);  //obj = html liste in meinen Fall

/*
 * Funktion um die Leerzeichen zwischen den HTML Tags raus zu löschen
*/
function clearSpaces (strOut) {
     strOut = strOut.replace(/>\s+/gm,'>');	
     strOut = strOut.replace(/\s+</gm,'<');			
     strOut = strOut.replace(/>\s+</gm,'><');
            					                                
     return strOut;
}
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück