INPUT Text-Feld automatisch an Breite anpassen

QuHno

Außer Betrieb
Ich stehe gerade vor dem Problem, dass ich ein bei folgendem Code:
HTML:
<form action=''>
<p>
<input type="text" class="test" id="command" value="Command" />
</p>
</form>
das INPUT Feld dynamisch an die Breite des Textes anpassen möchte bzw. muss, mir sind die Ideen ausgegangen und ich habe auch leider nichts passendes im Netz gefunden (wahrscheinlich nach den falschen Begriffen gesucht...)

Ein TEXTAREA anstelle des INPUT kommt leider in diesem Fall nicht in Frage und ich möchte nach Möglichkeit nicht an Fontgrößen oder Typen herumschrauben, das soll soweit alles default bleiben, wie es der Benutzer in seinem Browser eingestellt hat.

CSS und|oder JS Lösungen sind OK, serverseitige Sachen nicht, da es auch offline funktionieren muss und der IE6 ist mir piepegal, es muss nur in aktuellen Browsern laufen. Falls jemand eine Lösung hat, würde ich mich wirklich freuen, wenn (si)e(r) sie hier mit uns teilen würde :)
 
Hallo Quhno

JETZT weiss ich, was mein Dozent damals gemeint hat, als er von Problemen mit der
Länge von Textfeldern sprach...

Ich habe da was ausprobiert, aber es ist wirklich nur q&d:

HTML:
<body>

<form action='' name="meinformular">
<p>
<input type="text" class="test" name="cmdfeld" id="command" value="Command12345678901234567890" />
</p>
</form>
<script language="JavaScript">
<!-- 
var factor = 1.15;
window.document.meinformular.cmdfeld.size = window.document.meinformular.cmdfeld.value.length * factor;
// -->
</script>

</body>

hth
 
Das mit Faktor und .length war auch so meine erste Idee :D

... hat leider den Nachteil, dass es z.B. auf einem Handy nicht funktioniert (OK, auf ein paar schon, aber nicht alle haben einen vollwertigen Browser bzw. Bildschirm) und bei Schriften mit unterschiedlicher Laufweite fürchterlich in die Hose gehen kann (Verdana z.B. ist breiter als Arial oder Helvetica, Mac rückt die Buchstaben dichter zusammen als Win etc. pp.). Leider kann man sich auch nicht darauf verlassen, dass immer die passenden Schriften vorlegen, und man kann den Benutzer auch nicht dazu zwingen, genau diese zu wählen. Ebenso geht es schief, wenn der Browser des Benutzers keinen Festweiten-Font für Formularfelder benutzt.

Die 1.15 als Formfaktor funktionieren bei einem passenden Buchstaben-Mix bestimmt recht gut, aber INPUT Felder haben leider die unangenehme Eigenschaft, dass man da alles mögliche eingeben kann. Einfacher Test: bei iiiiiiiiiii wird es auf diese Art zu breit, bei mmmmmmmm könnte es zu schmal werden. Noch schlimmer wird es bei CJK Zeichen (Ein Feld des Formulars muss auch die aufnehmen können, der Rest ist nur Standard ASCII) bei denen habe ich keine Ahnung wie man da die korrekten Laufweiten erzielt - zumal es auch Varianten gibt, bei denen ein wilder Mix aus lateinischen und CJK Zeichen auftritt, speziell im japanischen.

Leider hab ich außer der Anzahl der Buchstaben in einem INPUT Eingabefeld auch noch keine Eigenschaft gefunden, die mir die Länge des Textes in Pixeln ausgibt, wenn es das gäbe, wäre das die Lösung all meiner Probleme. Bei TEXTAREA könnte man z.B. .scrollWidth und .offsetWidth miteinander vergleichen und einfach COLS hinzufügen oder entfernen wenn scrollWidth > offsetWidth ist oder umgekehrt, aber bei INPUT gibt es diese Eigenschaft AFAIK nicht ... :(
 
Ich habe noch ein wenig mit div und span herumexperimentiert.
Aber ich bin mir inzwischen auch sicher, dass dies wegen der proportionalen
Schriftzeichen sogar unmöglich zu berechnen ist.

Generierst Du die HTML Dateien?. Dann könntest Du ja das Wort auch in einen
span einbetten, und den mit einem border formatieren.

Das einzige, was ich noch mit einem input-Feld hingekriegt habe, klappt nur,
wenn es das letzte Element auf dieser Zeile ist:

HTML:
<form action=''>
<p>
<input type="text" class="test" id="command" value="IIIIXXXXiiiiimmmmm" />
</p>
</form>



#command {
    text-decoration: underline;
    border-style: hidden;
}
 
Nope, die Seite ist fertig, ich will lediglich dass der User seine Eingaben auch sehen kann und dass sie nicht (zu sehr) abgeschnitten werden.

Es dreht sich um 5 nebeneinander liegende Felder und ich wollte halt, dass jedes nur so viel Platz einnimmt, wie es braucht, speziell da meistens eins der Felder leer ist. Wäre halt schön, wenn das dann auf z.B. 16px Breite zusammenschrumpfen würde und die anderen den zusätzlichen Platz nutzen könnten ...
 
also der obige ansatz ist der einzige den es gibt...man kann es noch ein wenig tunen:
- Schrift mit fester breite nutzer (Courier Familie)
- Schrift mit fester Pixelbreite angeben (z.B. 10px oder 12px)
- Zahl der Zeichen mit Pixelbreite (ggfs. + einige Pixel) multiplizieren
Breite kann man dann auch beim tippen noch anpassen (wenn das gewünscht ist)

Insgesamt natürlich sehr unüblich und sicherlich auch kein gutes/belastbares Design (gerade wenn dir auch der Mobile-Web Bereich wichtig ist). Wie schaut das denn aus, kann man das nicht anders lösen?
 
Ich selbst stelle den Seitencode nicht zur Verfügung, kann also am eigentlichen HTML nichts machen. Das JS, was die Breiten anpasst und noch ein paar sonstige Funktionen hinzufügt wird erst später dazu geladen.

Ich bin mittlerweile auf dem Trichter, dass ich einfach einen window load event Handler an die Input Felder hänge und sie doch per .replaceChild(selectBox, this) durch eine Textarea mit einer Höhe von 1 Reihe ersetze und dabei id und name übernehme. Dann noch ein wenig "code sanitation" dazu, damit die in Textareas möglichen Zeilenumbrüche fliegen gehen und zum Schluss die Breite dynamisch mittels scrollWidth und offsetWidth usw. angepasst.

Nicht schön vom Code her, optisch aber soweit OK und funktioniert mit jeder Schriftfamilie und auch auf Handies mit einem vollwertigen Browser - für die anderen gibt's eh eine eigene Seite.

... wäre halt nur schön gewesen, wenn das mit den eigentlichen Input Feldern funktioniert hätte...
 
Wenn du doch eh schon mit javascript und DOM-Manipulation rumspielst, warum verzichtest du dann nicht gleich auf in Inputfeld, und zeigst dem User seine Eingabe direkt in einem DIV an? JS captured jeden Fliegenschiss an Tastatureingabe, und kann das auch bequem in ein innerHTML/nodevalue als Text übertragen. Der Fliesstext kommt dann von selbst, auch mit der richtigen Breite. ;)
 
Weil nicht jeder JS an hat bzw. nicht an haben kann / darf.

Mit den Input Feldern (die ich in Textareas umwandle, die sich dank ein klein wenig JS exakt so stylen lassen wie DIVs) bleibt das Formular auf alle Fälle benutzbar, es sieht halt nur besch...eiden aus wenn JS aus ist. Genau so, wie es besch...eiden aussieht, wenn CSS aus aber JS an ist, wie es z.B. bei den meisten Screenreaden der Fall ist. So, wie es jetzt ist, reicht ein Klick auf den "Absenden" (Submit) Button und weg ist es - gleichgültig wie es aussieht oder ob JS an oder aus ist - ohne dass ich mich großartig darum kümmern muss. Bei DIVs müsste ich erst die Werte auslesen ...

Wenn ich es mit umgewidmeten DIVs mache, ist es ein grober Verstoß gegen alle Acessibility Regeln, die es so gibt - und ich (Err ... , das Script) hätte mehr Arbeit, wenn ich es versenden wollte.

DIV = Nein wegen Navi im Screenreader. Der erkennt sehr wohl eine Textarea oder ein Input als Eingabefeld, aber kein DIV, gleichgültig was ich da mache. Und nein, man kann sie nicht per object detection oder Browser sniffing erkennen, da sie normalerweise auf einen der handelsüblichen, aktuellen Bowser aufsetzen ;)
 
mmh...ich verstehe jetzt gerade nicht, warum es mit Textareas besser geht wie mit den Inputfeldern? Wenn ich ich richtig lese passt du jetzt aber sowieso nichts an den Inhalt an, sondern die Felder an der verfügbaren Breite.
 
Das stimmt nicht ganz :D
Bei Textareas kann ich so etwas machen:

Code:
function editTextInput(area){
	while ((area.scrollWidth) > (area.offsetWidth)) {
		area.cols++;
	}
	while (area.scrollWidth +8 < (area.offsetWidth)) {
		area.cols--;
	}
}

und diesen Code z.B. so aufrufen:
HTML:
<textarea id="parameter" rows="1" cols="20" onkeyup="editTextInput(this);"></textarea>

Da aber bei Input scrollWidth und offsetWidth immer gleich ist, klappt das bei Input nicht...

Ich habe halt mehrere Inputs in einer Reihe und wenn in ein Feld viel eingegeben wird, sieht man nicht mehr, was man geschrieben hat. Da aber vom Benutzer nie alle Felder gleichzeitig ausgefüllt werden, wollte ich sie halt in der Breite anpassbar machen, so dass man immer genug Platz hat. Der eigentliche Code ist ein klein wenig komplexer, da er alle nicht in Benutzung befindlichen verkleinert, aber das obige ist so die Basis, mit der ich arbeite.

Klappt übrigens auch prima mit ...Height, man muss dann nur ...Width durch ...Height ersetzen und cols mit rows und aus der 8 evtl. eine 10 oder 15 machen, und schon hat man ein Texteingabefeld, welches sich an die Größe des eingegebenen Textes anpasst.

Vorteil für den User:
Er muss nicht mehr eine viel zu kleine Textarea scrollen.
Nachteil der Scriptlösung:
Bei Ausgeschaltetem JS hat er eine normale Textarea, also kein wirklicher Nachteil, wenn man die Initialgröße nicht zu klein gewählt hat. Der User muss dann halt scrollen, wenn er mehr eingeben will - aber das muss er ja bei 90% aller Webseiten, ist es also gewohnt:D
 
Oben