Günter Marchewka: Formate in Textarea ???

Beitrag lesen

Hallo Verena,

Der Inhalt der Seiten ist dazu in deiner Access-DB gespeichert. Um die Texte zu ändern, wird der Inhalt der DB in ein Textarea-Feld eingelesen.

Zur Abrundung der ganzen Bearbeitung möchte ich jetzt auch noch die Möglichkeit schaffen, Teile des Textes in fett oder kursiv zu formatieren.

hallo andreas,
hallo Cheatah,
das mit dem WYSIWIG würde ich auch nicht entwickeln wollen, aber es geht auch mit "halb-wysiwig" mit
textarea. Darin den Text eingeben und bearbeiten lassen und anschliessend in einem
div das Ergebnis anzeigen.

Zum Thema "Text markieren" und verändern in einer Textarea kann ich Euch nur sagen,
mit dem IE es geht hervorragend, erstklassig positioniert und fast 100% problemlos.
(Da Verena von einer Access-DB redet, liegt es nahe, das ihre Benutzer mit dem IE arbeiten.)
Es gibt kein Problem, die Position zu bestimmen, an der ein Anwender mit der Maus geklickt hat oder
den Text zu ermitteln, der markiert wurde.
Genauso kann an den jeweiligen Positionen beliebig etwas eingefügt werden, sei es an einer bestimmten Position
sei es um einen markierten Text herum.
Eine Suche im Archiv liefert dazu gute Treffer.
Einen Tip von Antje Hoffmann habe ich seit längerem ausgebaut und nutze ihn zur vollen Zufriedenheit.

Hier nun die Technik:
Es ist ganz simpel, wenn man mit dem selection-Objekt und createRange() arbeitet.

Zunächst ein paar Variable definieren:
<!-- optional !--> var oMover = '#FF0000';// Farbe für den onMouseover-Effekt
<!-- optional !--> var oMout  = '#0000FF';// Farbe für den onMouseout-Effekt
<!-- zwingend !--> var FEsel        = ''; // Zwischenspeicher für selektierte Werte

Ein Button, der ein bequemes Bedienen ermöglicht, irgendwo auf der Seite.
<button name="selEintrag"
        type="button"
        id="selEintrag"
        onMouseup="javascript:selEintrag()"
        title="\n Einfügen von HTML-Tags in einen Text \n\n Klicken Sie in ein Textfeld oder. \n\n markieren Sie einen Text um die Aktion zu starten.\n\n Klicken Sie dann auf diesen Button. \n"
        onMouseover="this.style.color=oMover;"
        onMouseout="this.style.color=oMout;">
        <a>Einfügen</a>
</button>

Eine beliebige Anzahl von <textarea>-Elementen, bei denen nur wichtig ist, das irgendein Ereignis eine
Wertzuweisung zu der Variablen FEsel macht. Hierin ist nachher der markierte Text (=generated-Status des
selection-Objekts) oder kein markierter Text, aber eine Klickposition (=degenerated-Status des selection-Objekts)

<textarea id="FE1"
          name="FE1"
          wrap="virtual"
          cols="80"
          rows="8"
          onClick="FEsel=selection.createRange()">
          "  userText  "
</textarea>

Irgendeine Funktion, die irgendetwas mit der Selektion macht, wenn die Benutzer auf den Button drücken.

function selEintrag()
 {
  if (!FEsel){ alert('Achtung!\n\nSie haben weder in ein Eingabefeld geklickt, noch einen Text markiert.\n\nBitte führen Sie eine dieser Aktionen aus, bevor Sie "Einfügen" wählen.');return;}

selWert = FEsel.text; // übertragen des selektierten Wertes
  if (debuginfo >= '3') alert('Hinweis:\n\n An die Einfügenfunktion wird folgender Wert übergeben:\n\n' + selWert);

Hier ist ein Aufruf für einen Dialog, über den die Benutzer bestimmte Formatierungen auswählen können

var arr = showModalDialog( "Einfuegen.htm",
                             selWert,
                             "font-family:Verdana; font-size:12; dialogWidth:28em; dialogHeight:46em" );

Der Rückgabewert entscheidet, wie weiter verfahren wird.
arr ist null, wenn der Dialog geschlossen wurde, ohne das irgendetwas darin ausgewählt wurde, dann passiert gar nichts.
Gibt es aber einen Rückgabewert, so muss etwas passieren.
Hier werden drei Möglichkeiten abgefragt:
1. Sonderfunktion der markierte Text sollte über den Dialog in eine Tabelle gewandelt werden, dann wird der
   Inhalt der Selektion einfach ersetzt durch den Rückgabewert. Das bedeutet, ich kann den selektierten
   Inhalt in etwas beliebig anderes umwandeln.
2. Sonderfunktion alles HTML im markierten Text soll entfernt werden. Rettungsfunktion für versehentlich
   eingefügte HTML-Tags, die wieder entfernt werden sollen. Das ist der Teil, weshalb ich sagte nicht
   ganz 100% gut. Bei geschachtelten Tags (Tag im Tag durch Fehlbedienung) bleibt unter Umständen vom
   letzen Tag der Text hinter dem vorletzten schliessenden ">" bis zum letzten schliessenden ">" (inklusive)
   stehen. Weiter entfernt die replace-Funktion auch die Zeichenkombination "<>" was nicht unbedingt
   gewollt sein muss. Ich habe aber keine Schreibweise für den regulären Ausdruck finden können, der das
   verhindert. Meine Schwäche...
3. Die "normale" Aktion den markierten Text mit den ausgewählten HTML-Tags umrahmen. Dazu wird der Rückgabewert
   in zwei Teile zerlegt (Das muss im Dialog entsprechend codiert sein, das der Rückgabewert in dieser Form
   geliefert wird.). Im ersten Teil steht das öffenende Tag, im zweiten das schliesende Tag.
   Die Selektion wird dann anschliessend mit den Teilen umrahmt.

Die reine Wertzuweisung an die Selektion führt dazu, dass der Text in der angeklickten Textarea an der
angeklickten Stelle ersetzt wird und alles ist so wie es sein soll.
Zum Schluss muss noch die Selektion negiert werden, damit man nicht unabsichtlich ein zweites Mal damit arbeitet.

if (arr != null)
  {
    var htmlTag=arr.split('|');
    var rg=FEsel;
    if (htmlTag[0] == 'in Tabelle wandeln') { rg.text = htmlTag[1]; return;}
    else if (htmlTag[0] == 'alles HTML entfernen') {rg.text = rg.text.replace(/<[^>]*>/g,''); return;}
    else rg.text=htmlTag[0]+rg.text+htmlTag[1];
    FEsel = !FEsel;
    return
  }
  FEsel = !FEsel;

}
Gruß
Günter

P.S.: Die angegebene Adresse zeigt ein leicht anderes Beispiel mit ähnlicher Technik. Feste Einfügelogik ohne markieren eines Textes. Da sind die Benutzer auf die vorgegebenen Möglichkeiten eingeschränkt.