• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

[ERLEDIGT] In Tabelle mit Pfeiltasten navigieren

blabla333

Mitglied
Ich habe eine Tabelle, bei der die Zellen mit Input-Feldern gefüllt sind. Nun würde ich gerne mit den Pfeiltasten zwischen diesen Feldern wählen können und das eben in alle Richtungen, so dass ich ähnlich einer Excel-Tabelle schnell Werte eingeben bzw. ändern kann. Kann man so etwas umsetzen?
 
Danke.

Allerdings weiß ich nicht wie ich diesen Teil umsetzen soll:

Ich habe Zellen, die eine Checkbox und ein Textfeld beinhalten. Ich springe mit den Pfeiltasten von Checkbox zu Checkbox und kann diese entsprechend auswählen. Wenn der Fokus auf einer Checkbox liegt, sollte der User die Möglichkeit haben einfach loszutippen. Der Cursor springt dann automatisch in des Textfeld.
Irgendwie würde das ja bedeuten, dass man alle möglichen Zeichen abfragen müsste. Das geht doch bestimmt irgendwie einfacher, oder?
Also: User schreibt einen Text, d.h. drückt einen Buchstaben -> Springen zum Textfeld, so dass die Eingabe dort erfolgt.
 
Du musst nicht alle möglichen Zeichen abfragen, ein keydown() Event für die Checkboxes sollte reichen. Ich habe bisher so etwas noch nicht gemacht, aber mein erster Ansatz würde in die Richtung gehen:

Code:
$(':checkbox')on('keydown', function() {
    $(target).focus();
})

Wobei target das zugehörige Textfeld wäre, welches dann durch traversieren gesucht wird.
 
Sei dir bewusst, dass Tronjer jQuery-Quellcode als Vorschlag bringt. Wenn Du bereits jQuery in deine Webseite eingebunden hast, kannst Du das natürlich auf dem Weg machen. Doch es geht auch ohne jQuery:

HTML:
<input type="checkbox" name="check" value="1" id="check1" onchange="document.getElementById(this.id + "_textfield").focus()"><input type="text" name="check1_textfield" value="">

Könnte man natürlich ebenso in einer Funktion auslagern.
 
Danke für eure Hilfe!!

Leider komme ich nicht so ganz zurecht. :-(

Vielleicht hilft es das ganze Konzept zu beschreiben. Ich dachte an folgende Funktionsweise:
1) Die erste Zeile wird farblich markiert und ist somit "aktiviert".
2) Mit der Pfeiltaste (oder Tab-Taste?) kann der User zur nächsten Zeile springen.
3) Drückt er die Leertaste, so wird die Checkbox aktiviert oder deaktiviert.
4) Beginnt der User zu tippen, so wird die Checkbox deaktiviert, der Cursor springt in das Textfeld und schreibt automatisch hier rein.

HTML:
<table><tr>    <td>Bezeichnung 1</td>    <td>        <span><input type="checkbox" name="chk1" checked> keine</span>        <textarea name="textfeld1"></textarea>    </td></tr><tr>    <td>Bezeichnung 2</td>    <td>    <span><input type="checkbox" name="chk2" checked> keine</span>    <textarea name="textfeld2"></textarea></td></tr><tr>    <td>Bezeichnung 3</td>    <td>    <span><input type="checkbox" name="chk3" checked> keine</span>    <textarea name="textfeld3"></textarea></td></tr></table>

Mein Ansatz wäre dieser:
- Bei drücken der Tab-Taste wird der Fokus auf die erste Checkbox gesetzt und die zugehörige Zeile bekommt eine weitere Klasse zugeordnet (über CSS wird dann die Farbe geändert)
- Wird nun die Tab-Taste erneut gedrückt (oder die Pfeil nach unten Taste), so wird der Fokus auf die nächste Checkbox gesetzt und wieder die Klasse der aktuellen Zeile geändert. Dabei muss aber auch die alte Klasse wieder zurückgesetzt werden.

Die Umsetzung macht mir aber Schwierigkeiten:

document.onkeydown = function(event) {
if (event.keyCode == 9) {
$("#chk1").focus();
}
else {
$("#textfeld").focus();
}

}

Das funktioniert so natürlich noch nicht wirklich.
Wie setze ich es um, dass bei der Tab-Taste nur dann die erste Checkbox aktiviert wird, wenn noch gar keine Auswahl vorhanden ist und ansonsten die nächste aktiviert wird?
Zudem habe ich die Schwierigkeit, dass die ids der Checkboxen individuell sind, d.h. keine Zahlen als Bezeichnungen haben und ich somit nicht einfach nur hochzählen kann...
 
Zuletzt bearbeitet:
Du musst deine Aufgabe strukturieren.

Erstelle ein einfaches keydown() Event und lasse dir so etwas console.log('foo').zurückgeben. Sollte das funktionieren, dann erweitere es um die Abfrage des Keycodes.

Im nächsten Schritt vergiss das Event und überlege dir, wie du von der Checkbox zur dazugehörigen Textarea traversierst. Das könnte zum Beispiel ein Sibling sein. Oder du machst es wie von mir vorgeschlagen und verwendest jQuery. Da gibt es Funktionen wie is(), has(), not(), hasClass(), etc. die das Ansteuern von HTML-Elementen und Bilden von Selektoren erleichtern, z.B.: $(':checkbox'). Du willst das Event ja über die Checkboxes triggern und nicht auf den Body legen.

Anschließend bringst du beides zusammen und schaust dir die Funktion fokus() an.
 
Was das Traversieren angeht, kann ich mich in den Ebenen nach oben und unten bewegen, aber wie spreche ich ein Element auf der gleichen Ebene an?

HTML:
<td><input type=checkbox id=chk1><textarea id=text1></textarea></td>

Über
Code:
 $("#chk1").parent("td");
würde ich die umgebende Zelle ansprechen, aber ich möchte darin ja die Textarea haben und darauf den Fokus setzen.
 
Die Methoden parent(), sibling() und children() lassen sich chainen. Du müsstest also eine Art Wegbeschreibung á la 1 node aufwärts, 1 node nach rechts, 1 node nach unten, etc., erzeugen. In pure JS geht es allerdings immer nur Ebene für Ebene, während man in jQuery auch mehrere Ebenen höher, tiefer und auf dem gleichen Level springen kann.
 
Ok, damit bin ich bis jetzt so weit gekommen: http://jsfiddle.net/zDY8h/1/
Beim Tippen springt er automatisch ins Textfeld.

Es ergeben sich folgende Probleme:
1) Er springt zwar wie gewünscht mit der Nach-unten-Pfeil-Taste zur darunterliegenden Checkbox, allerdings geht es dann nicht weiter. Er springt zurück :-(
2) An welcher Stelle kann ich die Klasse "highlight" wieder entfernen? Es reicht nicht, wenn der Focus nicht mehr auf der Checkbox liegt, da man bei Schreiben eines Textes ja auch nicht mehr in der Checkbox, wohl aber noch in der aktivierten Zeile, ist.
 
Gedanklich finde ich es einfacher, wenn jede Checkbox eine ID bekommt, dann würde das springen auch über mehrere Tabellen hinweg funktionieren:
Edit this Fiddle - jsFiddle

Aber wie spreche ich die Checkboxen an bzw. wie erhöhe ich die ID-Nummer? Schwierig ist dann auch, wie man die aktuelle ID (zum Berechnen der nächsten Checkbox) erhält, wenn der Cursor z.B. in der Textarea ist.

*grummel* echt ärgerlich, dass man einen einfachen Gedanken - nämlich einfach nur per Tastendruck nach oben oder unten in einer Tabelle zu navigieren - so schwer umzusetzen ist. Zumindest gestaltet es sich für mich so schwierig...
 
Zugegeben, die Aufgabe ist bissi knifflig. Ich habe das Script etwas umgebaut und ein Formular daraus gemacht. Außerdem verzichte ich komplett auf traversieren und benutze statt dessen das data-Attribut von HTML, um korrespondierende Felder zu adressieren und dynamisch IDs zu erstellen. Damit das funktionert, müssen die IDs eine durch den '_' getrennten aufsteigende Nummer besitzen.

Man könnte hier noch weiter abstrahieren, in dem die data-Atttribute beim Laden dynamisch aus den IDs erzeugt und den Elementen zugewiesen werden. Aber ich habe sie mal statisch ins HTML geschrieben.

Den focus() beim Laden habe ich mal weggelassen. Dafür funktioniert es auch mit dem Tabkey.

Mit dem Ansatz solltest du das Script erweitern können. Ansonsten als Auftrag in die Jobbörse.

HTML:
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<style type="text/css">
		.gray {background-color: #c0c0c0; }
		.highlight {background: darkgray;}
	</style>
	<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
	</head>
<body>

<form>
	<p>
		<label data-label="box_1" for="box_1">Box 1</label>
		<input data-box="box_1" type="checkbox" id="box_1" />
		<textarea data-area="box_1" class="gray"></textarea>
	</p>
	<p>
		<label data-label="box_2" for="box_2">Box 2</label>
		<input data-box="box_2" type="checkbox" id="box_2" />
		<textarea data-area="box_2" class="gray"></textarea>
	</p>
</form>

<script type="text/javascript">
$(':checkbox').on('keydown', function(event) {
	// Wenn Arrow Down gedrückt wird
	if (event.keyCode == 40) {
		// lege Focus auf Textarea
		$(".gray[data-area='" + $(this).attr('id') + "']").focus();
	}
});

$('.gray').on('keydown', function(event) {
	// Wenn Arrow Down gedrückt wird
	if (event.keyCode == 40) {
		// Baue aus dem data-Attribut die ID der nächsten Checkbox (erhöhe um 1)
		var data = $(this).attr('data-area');
		var id_part = data.split('_');
		var id = '#' + id_part[0] + '_' + (parseInt(id_part[1]) + 1);
		$(id).focus();
	}
});

$(':checkbox').on('focusin', function(event) {
	// Markiere die Checkbox
	$(this).prop('checked', true);
	// addClass für Textarea
	$("label[data-label='" + $(this).attr('id') + "']").addClass('highlight');
	
});

$('.gray').on('focusout', function(event) {
	// Entferne Markierung
	$('input').prop('checked', false);
	//Entferne die Klasse
	$('label').removeClass('highlight');
});
</script>
</body>
</html>

Die Einrückungen macht der Editor hier. :(
 
Wow, super. Tausend Dank!
Es ist nicht ganz das, was ich brauche, aber mit deiner riesigen Hilfe konnte ich jetzt alles so umsetzen, wie benötigt.
Manchmal hänge ich an einem Schritt fest und komme einfach nicht weiter und danach flutscht es dann wieder...
 
Anmerkung am Rande: Statt des data-Attributs ließe sich auch eine CSS-Klasse verwenden, und es wäre natürlich eleganter, die key-Events zum Schluss in einer gemeinsamen Funktion zu kapseln, vielleicht mit $.each().
 
Zuletzt bearbeitet:
Zurück
Oben