# Smilies in Textfeldern berreits als Bilder anzeigen



## Eistee (2. Februar 2005)

Hi,
ich habe für einige meiner Scripts mal ein simples JS geschrieben, dass klickbare Smilies in eine Textbox einfügt z.B. als "" - eben so wie in vielen Gästebüchern oder Foren.
Denke soweit ist jedem klar was ich meine 
Nun habe ich in neuen vBulletins (3.XX) gesehen, dass es anscheinend auch möglich ist, die Smilies in der Textbox berreits als richtige Bilder anzuzeigen... 
Da ich leider kaum Ahnung von JS habe, würde ich mich freuen, wenn mir vielleicht jemand hier erklären könnte, wie so etwas funktioniert.
Mein code sieht bisher so aus:

```
function smilie(thesmilie) 
{
	document.signGuestbook.message.value += thesmilie+" ";
	document.signGuestbook.message.focus();
}
```
und wird so aufgerufen:

```
<a href="javascript:smilie(':)')"><img src="smile.gif" border="0"></a>
```

Ich hoffe, ihr könnt mir ein wenig weiterhelfen.


----------



## Sven Mintel (3. Februar 2005)

Das funktioniert nicht mit <textarea>... dafür brauchst du einen IE  ab Version 5.5 oder einen Gecko-Browser(Netscape7, Mozilla, Firefox etc.).
Das Ganze, was wie ein <textarea> aussieht, ist eigentlich ein <iframe>

Infos zur Technik:
Gecko's: http://www.mozilla.org/editor/midas-spec.html
IE: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmshtml/html/createwp.asp
IE + Geckos:http://www.mozilla.org/editor/ie2midas.html


Weitere Deteils liefert dir die Suche nach "DesignMode"


----------



## Eistee (3. Februar 2005)

Ich habe also eine html-datei, die ich mit Hilfe von JS "editable" mache und dann in einen iframe lade, der an der Stelle der textarea sitzt?!
Könntest du mir das vielleicht mal anhand meines Beispiels mit den smilies von oben erklären?
Ich steig da noch nicht ganz durch...


----------



## Sven Mintel (3. Februar 2005)

Beispiel

Kommandos kann man in dem editierbaren Dokument im  iFrame ausführen per *execCommand()*
Das Kommando, um Bilder einzufügen, heisst "InsertImage"

weitere Erklärungen stehen im Quelltext.


----------



## Quaese (4. Februar 2005)

Hi Sven,

in deinem Beispiel hast du in der Funktion *insert_image* in der letzten if-Anweisung statt
*objEditor* nur *oEditor* geschrieben. Ansonsten klasse Beispiel!

Ciao
Quaese


----------



## Eistee (4. Februar 2005)

Danke für das Beispiel!
Aber wie habe kann ich nun die Daten aus dem iframe mit php verabeiten?
Muss der iframe dafür wie gewohnt in ein Formular eingebunden sein und ich kann seinen Inhalt, nach abschicken des Formulars,  dann über die id als Variable ansprechen oder wie habe ich mir das vorzustellen?

Sind alle hier gelisteten Kommandos möglich?
http://www.mozilla.org/editor/midas-spec.html


----------



## Sven Mintel (4. Februar 2005)

Um den Inhalt des iFrames per Formular zu senden, musst du in das Elterndokument bspw. ein verstecktes Formularfeld einbinden, dem du vor dem Senden als *value* den Inhalt(*innerHTML*) des iFrame -Dokumentes zuweist.

Zu den Kommandos.... bin ich grad nicht auf dem Laufendem ...probiers einfach aus(vergleiche die Kommandos vorher am Besten mit den IE-Kommandos und lese die Informationen hinter allen 3 Links)


----------



## Eistee (4. Februar 2005)

Hab grad mal ein wenig rumprobiert:

```
<html>
<head>
<title>DesignMode</title>
<script language="JavaScript" type="text/JavaScript">
<!--
function init()
{
	objEditor=document.getElementById('editor').contentWindow;
    objEditor.document.designMode = 'on';
    objEditor.focus();
}
window.onload=init;
//-->
</script>
</head>

<body>
<input type="submit" name="bold" value="B" onClick="javascript:objEditor.execCommand(bold, false, null)"><br>
<iframe id="editor" width="500px" height="200px">
</iframe>
</body>
</html>
```
So wird zwar ein iframe angezeigt in dem ich auch schreiben kann, aber ich kann denn markierten Text nicht *Fett* stellen.
Hab ich da was falsch verstanden? Wie muss der Code erichtig aussehen?


----------



## Sven Mintel (4. Februar 2005)

Einigermassen korrekt musst du da schon arbeiten.... die Browser sind zwar recht fehlertolerant, alles können sie aber nicht ausbügeln



Die Kommandos müssen im *document*-Objekt des iFrame ausgeführt werden, nicht im iFrame(window)-Objekt selbst
Der Command-Identifier(hier:bold) gehört in Anführungszeichen

ergo:

```
onClick="objEditor.document.execCommand('bold', false, null)"
```


----------



## Eistee (4. Februar 2005)

Habs jetzt hinbekommen:

```
<html>
<head>
<title>DesignMode</title>
</head>
<script language="JavaScript" type="text/JavaScript">
function init()
{
	try
	{
        document.getElementById('editor').contentWindow.document.designMode = 'on';
    }
	catch(e)
    {
        alert('Der Editor funktioniert in deinem Browser nicht');
    }
}
</script>
<body onLoad="init()">
<button onClick='document.getElementById("editor").contentWindow.document.execCommand("bold", false, null); document.getElementById("editor").contentWindow.focus();'><b>B</b></button>
<br>
<iframe id="editor" width="500px" height="200px">
</iframe>
</body>
</html>
```

Ich hab aber noch ein Frage zu deinem Beispiel mit den Smilies weiter oben.
Wenn ich ein Bild in den Text einfüge kann ich das durch die Anhalter an allen Ecken und Seiten ja in der Größe skalieren. Nun wäre eine solche Funktion aber ein Sicherheitsrisiko für z.B. ein Forum oder GB.
Ist es auch irgendwie möglich diese Anhaltepunkte durch einen Befehl zu unterdrücken, bzw. die Skalierfunktion allein zu verbieten?


----------



## Sven Mintel (4. Februar 2005)

Man könnte sicher entsprechende Sachen im Editor unterbinden.

 Da eine schlussendliche Verarbeitung der Eingaben jedoch ohnehin serverseitig erfolgen muss, ist es jedoch vorteilhafter, das dort zu entfernen, z.B. mit regulären Ausdrücken.


----------



## Eistee (4. Februar 2005)

Du weist also nicht zufällig, wie man das unterbindet, oder?  
Ist mein Code von oben soweit in Ordnung?
Ich bin nach den Anleitungen im msdn und von midas gegangen. Es funktioniert so im IE als auch unter Mozilla problemlos und entspricht den Spezifaktionen auf mozilla.org.

Muss ich auch zwnagsweise einen iframe benutzen? Wäre ein div-Container nicht auch möglich?


----------



## Sven Mintel (4. Februar 2005)

Du *musst* ein iFrame benutzen... mit einem <div> funktioniert es nur im IE.


----------



## Eistee (4. Februar 2005)

Alles klar 
Ein Frage hab ich allerdings immer noch.
Bei Druck auf Enter wird ja immer eine zeile übersprungen - wie von Editoren gewohnt.
Ist es irgendwie möglich, einen weichen Zeilenumbruch (Shift+Enter) zu erzwingen, so  dass der Zeiger einfach nur in die nächste Zeile springt?


----------



## Eistee (4. Februar 2005)

Ich hab jetzt einfach noch ein wenig weiter probiert und stehe nun vor neuen Problemen... 
Das mit den Smilies funktioniert jetzt weitestgehend.

http://www.alkbrueder.de/2005/signGB.php

Wenn man nun allerdings irgendwo auf der Seite klickt, so wird der Smily an dieser Stelle und nicht im IFrame eingefügt  
Ich habe absichtlich nicht deinen Code 1:1 übernommen, da ich zum Üben erstmal nur das allerwesentlichste einbauen wollte.
Wo liegt mein Fehler?

Wie kann ich ausserdem die Hintergrundfarbe und Größe, Aussehen der Schrift im IFrame ändern?


----------



## Sven Mintel (5. Februar 2005)

Zu den Smileys ausserhalb des <div>'s... du musst vor execCommand() den focus() an das <div> übergeben....

Zu den Formaten.... dafür gibts die Command-Identifier, Details dazu stehen auf den von mir verlinkten Seiten.

Prinzipiell... da du jetzt ein <div> und kein iFrame mehr verwendest, gibt es auch kein "contentWindow" mehr.

Die Kommandos musst du direkt im "document" ausführen, das <div> kannst du per 

```
document.all.htmlbox
```
..ansprechen... wenn du ihm bspw. den Fokus übergeben musst.

Zu dem Zeilenumbruch... mann kann da Shift/Enter verwenden.
Enter alleine erzeugt halt wie in anderen Editoren einen neuen Absatz.

Wenn dir dieses Verhalten nicht gefällt.... im IE könnte man im Editor die Enter-Taste abfangen und stattdessen per "pasteHTML" ein <br> einfügen.
...oder halt bei der serverseitigen Verarbeitung leere Absätze durch ein <br> ersetzen.

Threads zum Thema "Tastatureingaben abfangen" solltest du hier einige finden... eine Reihe davon bezogen sich auch speziell auf die[ENTER]-Taste.


----------



## Eistee (5. Februar 2005)

Die divs hatte ich gestern nur zum Probieren eingesetzt. Jetzt isses wieder nen iframe, da die divs ja im Mozilla ja leider nicht funktionieren 
Mich interessiert jetzt aber immer noch, wie ich das Aussehen des Frames anpassen kann. Mir gehts hier besonders um Schriftart/-farbe/-größe und die Hintergrundfarbe des iframes. Ausserdem soll der Text auch wirklich links oben beginnen und nicht mit 1cm Abstand vom Rand...
Wie schaff ich das? Mit CSS scheints nicht ohne weiteres zu gehen. Gibt es ausser dem iframe noch eine Andere Technik, die auch im Mozilla funktioniert? Spans vielleicht?!


----------



## Eistee (5. Februar 2005)

Ich hab grad mal versucht, den Hintergrund und die Schrift per backcolor etc zu definieren.
Leider find ich nirgends eine Erklärung, wie diese Commands angewendet werden müssen. Bei Moziila steht da imer nur "untested right now" 
Kannst du mir da vielleicht helfen?


----------



## Sven Mintel (5. Februar 2005)

_Ausserdem soll der Text auch wirklich links oben beginnen und nicht mit 1cm Abstand vom Rand..._

   Dafür gibts die marginheight-Angabe in iFrames.

   Was die Schrift betrifft... das geht ganz normal, wie bei Mozilla und MS beschrieben

```
execCommand('FontName',false,'Schriftart');
```
 
   Zu der Hintergrundfarbe im Mozilla.... die Meldung ist doch eindeutig, oder  ...sie steht zumindest nicht umsonst da, und dieser Hinweis steht auch bei der Kommando-Auflistung bei Mozilla.
  Besorg dir einen aktuellen Mozilla,... da funktioniert beides.

 Allerdings solltest du mal genau lesen, was diese beiden  Kommandos in IE/Mozilla bewirken.... das unterscheidet sich nämlich.


----------



## Eistee (5. Februar 2005)

Sorry, aber ich kann dir da absolut nicht mehr folgen.
Wo finde ich ich mal eine Auflistug der Commads für den IE und wie ich sie anwenden muss?
An welche Stelle muss ich die Hintregrundfarbe und Schrift festelgen?

```
document.getElementById("htmlbox").contentWindow.document.execCommand('FontName', false, 'Arial');
```
So stehts bei mir derzeit am Ende der init-Funktion - und es funktioniert nicht.
Wie muss das execCommand für backcolor aussehen?

```
document.getElementById("htmlbox").contentWindow.document.execCommand('backcolor', false, '#F5F5FF');
```
So gehts jedensfalls nicht.


----------



## Sven Mintel (5. Februar 2005)

Command Identifiers (Internet Explorer - DHTML)... die unterstrichenen Texte auf Webseiten sind sogenannte Links... dahinter verbergen sich oftmals hilfreiche Informationen.

Ansonsten... wie Kommandos angewendet werden, steht dort nun wirklich überall.... ich werds dir nicht für jedes einzelne Kommando vorkauen.

Vielleicht liest du dir erstmal alles in Ruhe durch


----------



## Eistee (5. Februar 2005)

Genau die Seite hatte ich bisher wohl übersehen.
Aber dann sind meine beiden Kommandos doch eigentlich richtig aufgebaut, oder?!
Wäre nett, wenn du mir zumindest dabei noch einmal unter die Arme greifen könntest.


----------



## Sven Mintel (5. Februar 2005)

Was soll ich da helfen ... es steht alles da:
*So stehts bei mir derzeit am Ende der init-Funktion*
Wenn du  init() aufrufts, ist das iFrame leer, und nix ausgewählt.

Mit execCommand() verändert man idR. die Auswahl->leeres Dokument->nix ausgewählt....nix wird verändert.

Ausnahme ist die Hintergrundfarbe im Mozilla... dort bezieht sich das Kommando auf das gesamte Dokument(wie dort nachzulesen)... und wird auch entsprechend umgesetzt.


----------



## Eistee (5. Februar 2005)

Danke!
Im Mozilla funktionierts jetzt bestens - nur im IE siehts bescheiden aus...
http://www.alkbrueder.de/2005/signGB.php

Also sehe ich das Jetzt richtig, dass es im IE keinerlei Möglichkeit gibt, die Hintergrundfarbe für das gesame Dokument zu setzen bzw. das Aussehen der Schrift vorzugeben?!


----------



## Sven Mintel (5. Februar 2005)

Du kannst eine HTML-Datei in das iFrame einbinden, und das darin per CSS regeln.
Oder ein HTML-Dokument "on the fly" per open() ins iFrame laden und  per write() den nötigen Code(incl.CSS) hineinschreiben.


----------



## Eistee (5. Februar 2005)

Werds wohl über ein eingebundenes Dokument mit CSS lösen....
Denke, dass ich jetzt soweit alles Grundlegende verstanden habe 
Könntest du mir vielleicht noch kurz erklären, wie ich den innerHTML des iframe einem versteckten Feld zuweise? Das muss ja wahrscheinlich auch per JS geschehen...


----------



## Sven Mintel (6. Februar 2005)

Den HTML-Code im iFrame kannst du per

```
document.getElementById('idDesIframe').contentWindow..document.body.innerHTML
```
 ermitteln. Diesen wiese dem *value* -Attribut des jeweiligen Formularfeldes zu.

Optimalerweise solltest du das Formular per POST senden... da das recht schnell zu viel Daten für GET werden können.


----------



## Eistee (6. Februar 2005)

hmmm
das klappt leider nicht ganz so wie es soll 


```
<input name="message" type="hidden" id="message" value='document.getElementById("htmlbox").contentWindow..document.body.innerHTML'>
```

So wird nicht der Inhalt des Frames ausgelesen, sondern der Wert entspricht der JS-Anweisung.


----------



## Sven Mintel (6. Februar 2005)

du musst den value dem Feld mit JS zuweisen, nicht die JS-Anweisung hineinschreiben.

SelfHTML:Fomularelemente-value


----------



## Eistee (6. Februar 2005)

Ich muss schon wieder nerven...
Hab jetzt folgendes hinter das </form>-Tag gehängt:

```
<script language="JavaScript" type="text/JavaScript">
document.signGuestbook.message.value = document.getElementById("htmlbox").contentWindow.document.body.innerHTML;
</script>
```
Nun wird aber kein Wert über geben.
Das wird wohl daran liegen, dass das Script einmal beim Aufruf der seite durchlaufen wird und zu diesem Punkt noch keine Eingaben geschehen sind.
Wie muss es richtig aussehen?


----------



## Sven Mintel (6. Februar 2005)

Die Zuweisung muss erst dann erfolgen, wenn das Formular gesendet werden soll.... z.B. per* onsubmit*


----------



## Eistee (6. Februar 2005)

Super - jetzt klappts


----------



## Eistee (7. Februar 2005)

Hab noch eine Frage.
Wie genau kann ich jetzt tastatur-Eingaben (Enter) abfangen und den Absatz durch einen Zeilenumbruch ersetzen.
Das funktioniert ja wahrscheinlich irgendwie mit onKeyDown.
An welcher stelle muss das Abfangen passieren, und wie stell ich das überhaupt an?


----------



## Sven Mintel (8. Februar 2005)

Enter abfangen: http://www.tutorials.de/tutorials154293.html&highlight=enter

Absatz durch Zeilenumbruch ersetzen geht  am Besten bei der serverseitigen Weiterverarbeitung per preg_replace().

Ein RegExp-Tutorial findest du bei den PHP-Tutorials.


----------

