Missing english text?
All text from cpiapp.org will be translated to english. Please stay patient... or help!
Webdesign mit dem CP:IApp Framework
Formulare mit dem CP:IApp-Framework erstellen
Formulare waren für Web-Anwendungen schon immer grauenhaft aufwendig. Schon alleine das Erstellen des HTML-Codes mit CSS und JavaScript/AJAX raubt viele Stunden. Sollen Formulare mehrsprachig angezeigt werden können, wird es in der Regel aufhören, Spaß zu machen.
Mit cpIApp gibt es Regeln für den HTML-Code, aber es gibt noch keine Designer-Applikation, mit der man Dreamweaver und Co ersetzen kann. Aber CP:IApp bietet viele Erleichterungen auf der Serverseite.
Unter dem Abschnitt "Für SW-Entwickler" werden noch andere Methoden vorgestellt, wie man Formulare bauen und managen kann.
Standardisierung mit Bezeichnern
Das cpIApp-Framework automatisiert viele Vorgänge, zum Beispiel die Auswertung des Formulars und die erneute Anzeige nach einem Fehler. Dazu ist ein kleines Reglement notwendig:
- Alle Datenfelder, die im POST-Request erscheinen, beginnen mit "FLD_". Alle anderen Bezeichner sind erlaubt, können aber nicht in die automatische Formularverarbeitung einbezogen werden.
- Alle Wertangaben, wie oben VAL_BENNAME, beginnen mit "VAL_". Die Applikation setzt hier automatisch
Werte ein, die z.B. aus der Datenbank kommen. Beispiel:
<input type="text" id="ID_BENNAME" maxlength="30" value="{VAL_BENNAME}" name="FLD_BENNAME"/> - Alle id-Attribut-Bezeichner beginnen mit "ID_". Das ist vor allem im Zusammenhang mit JavaScript notwendig, nicht für die cpIApp-Library.
- Alle Fehler-Platzhalter beginnen mit dem Prefix "ERR_".
- Für ein Feld wie FLD_BENNAME stehen also die Prefixe FLD_, ID_, VAL_ und ERR_ bereit. Der Teilbegriff "BENNAME" muß dabei immer gleich sein.
- Für eine Auswahlliste, die mit dem select-Tag aufgebaut wird, muß der Programmierer mehr arbeiten. Aber im Design ist es einfach:
<select name="FLD_IDEESTATUS" id="ID_IDEESTATUS" size="4"> <!--{OPTIONS_IDEESTATUS}--> <option value="1">reine Idee</option> <option value="2">Idee + schriftliches Konzept</option> <option value="3">Idee + Prototyp</option> <option value="4">Idee + Businessplan</option> <option value="10">Sonstiger Status </option> </select>Das Prefix "OPTIONS_" wird verwendet, um Einträge aus der Datenbank automatisiert einzusetzen. Damit der Designer das Formular schön gestalten kann und der Programmierer eine Vorstellung vom Inhalt bekommt, werden ein paar option-Einträge hinzugefügt, die später aus dem Template gelöscht werden. Wenn man eine select-Box einsetzt, deren Optionen nicht aus der Datenbank kommen, sondern direkt im HTML-Code erstellt werden können, muß dennoch bestimmt werden, welche Option markiert ist, wenn ein Datensatz geladen wird. Deshalb gilt hier die Syntax:<select name="FLD_IDEESTATUS" id="ID_IDEESTATUS" size="4"> <option value="1" {SELECTED_IDEESTATUS_1} >reine Idee</option> <option value="2" {SELECTED_IDEESTATUS_2} >Idee + schriftliches Konzept</option> <option value="3" {SELECTED_IDEESTATUS_3} >Idee + Prototyp</option> <option value="4" {SELECTED_IDEESTATUS_4} >Idee + Businessplan</option> <option value="10" {SELECTED_IDEESTATUS_10} >Sonstiger Status </option> </select>
Dabei ist das abschließende Postfix von {SELECTED_IDEESTATUS_1} die "_1" und das entspricht exakt dem Attribut value. - Für CheckBoxes (Kontrollfeld) gelten folgende Regeln:
<input type="checkbox" id="ID_BPLAN" name="FLD_BPLAN" value="1" {CHECKED_BPLAN} />Das cpIApp-Framework ersetzt den Platzhalter CHECKED_BPLAN mit einem Leerstring, oder, wenn der Wert angekreuzt sein soll, mit dem XML-Attribut "checked="checked"" - RADIOBOX
Zur Sache
Wenn man ein Formular anlegt, legt man zu jedem form-Tag drei versteckte Standard-Felder an.
<form action="/antwortseite.html" method="POST"
enctype="application/x-www-form-urlencoded"
accept-charset="utf-8" name="form_abcd" class="xform" >
<input type="hidden" name="FORM_NAME" value="form_abcd" />
<input type="hidden" name="FORM_CHARSET" value="testÜ" />
<input type="hidden" name="FLD_UNIQUEID" value="{VAL_UNIQUEID}" />
Der FORM_NAME
Das wichtigste Feld ist "FORM_NAME". Das value-Attribut bestimmt einen Bezeichner, den die cpIApp-Library und die eigene Web-Anwendung auswertet und daraus bestimmt, welches Plugin, welche Methode welcher Klasse aufgerufen wird, um den POST-Request auszuwerten. Verwendet man einen Bezeichner, der schon irgendwo im System reserviert ist, wird das Regelwerk für die Formulare Unstimmigkeiten entdecken.
Welche Bezeichner für eine Webanwendung reserviert sind, kann man als Administrator online ansehen, wenn man die Dispatcher-Tabelle betrachtet (Menupunkt "Zugriffe" oder "Access"). Jede Webanwendung kann jeden Bezeichner für sich reservieren und auch einen Bezeichner verwenden, der eigentlich von der cpIApp-Library verwendet wird, zum Beispiel "form_kontakt": der Begriff wird von cpIApp ausgewertet und ein POST-Request aus dem Kontakt-Formular wird erwartet. Wenn die Anwendung den Begriff mit der Methode formMethod() abfängt und behandelt, kann die Anwendung das Standardverhalten neu bestimmen.
Das Feld FORM_CHARSET
Das Feld FORM_CHARSET mit dem value-Attribut "testÜ" ist ein Trick, mit dem man einwandfrei erkennen kann, ob die Formulardaten in Latin-1-, Windows- oder UTF-8-Codierung gesendet werden.
Die Unique-ID
Zum Schutz vor POST-Angriffen bietet cpIApp einen Mechanismus mit einer Unique-ID an. Dafür ist das Feld FLD_UNIQUEID da, dessen Name nach dem Prefix "FLD_" aber auch anders lauten kann. So sollte jedes Formular einen eigenen Namen haben, wenn mehrere Formulare auf einmal angezeigt werden. Das value-Attribut beinhaltet einen cpIApp-Platzhalter für Formulare: {VAL_UNIQUEID}. Der Wortteil "UNIQUEID" muß genauso lauten wie beim Namen mit "FLD_".
Der Primary-Key
Oft braucht man ein zusätzliches Feld im Formular: einen Key, mit dem ein dargestellter Datensatz eindeutig identifiziert wird. Dazu wird ein Feld wie folgt eingefügt:
<input type="hidden" name="FLD_KEY" value="{VAL_KEY}" />
Statt "KEY" kann man natürlich auch einen anderen Namensteil verwenden
Die CSS-Formatierung
Nach vielen zeitraubenden Experimenten, Formulare mit CSS zu gestalten bin ich immer wieder zu den Tabellen zurückgekehrt. Ich will Formulare, die man vergrößern kann, wenn der Bildschirm das erfordert oder man schlecht sieht. Aufgrund der vielen Bugs im Internet-Explorer ist es viel einfacher, wenn man das alles in Tabellen anordnet. Seit Anfang 2009 verwende ich auch die Formular-Klassen des CSS-Frameworks YAML. Mit diesen ist einfacher möglich, tabellenfreie Formulare zu bauen. Nun verwende ich je nach Bedarf Tabellen oder nicht. Für die alten Tabellenformulare habe ich die YAML-Klassen erweitert und für form die xform-class hinzugefügt. Ich verwende erstmal ein Standard-Design für Formulartabellen:
| Label-Spalte | Eingabe-Spalte | Hilfetexte |
Ich habe nichts dagegen, wenn mir jemand ein Tabellen-loses Design liefert, auf dem ich aufbauen kann. Vielleicht enthält das YAML-Framework (das ich immer verwende) bereits diese Möglichkeiten. Aber das ist hier im weiteren erstmal egal.
Hier kommt eine beispielhafte Tabellen-Zeile:
<tr >
<td ><label for="ID_BENNAME" cpForms:textid="100501"
cpForms:textgroup="LBL" cpForms:textnote="Anmeldeformular"
>Gewünschter Benutzername</label></td>
<td ><input type="text" id="ID_BENNAME" maxlength="30"
value="{VAL_BENNAME}" name="FLD_BENNAME"/></td>
<td >{ERR_BENNAME}<span cpForms:textid="100502"
cpForms:textgroup="HLP" cpForms:textnote="Anmeldeformular"
>Dies ist der spätere Anmeldename (Login).
Wenn der gewünschte Name bereits vergeben ist, erhalten Sie die
Möglichkeit zur Änderung.</span></td>
</tr>
Zu diesem Beispiel und allen folgenden ist noch zu anzumerken, dass ich intensiv mit CSS-Formatierung arbeite. Wann immer möglich, verzichte ich einfach auf die Angabe von CSS-Klassen in den Tags und formatiere zum Beispiel das label so:
#content form table tr td > label { font-weight: bold; color: #000; }
CSS bietet hierfür unglaubliche Möglichkeiten. Wenn ich mir heute die HTML-Template-Syntax von cpIApp ansehe, denke ich immer wieder, dass ich das auch mit XSLT, mit XUL oder sonstwas hätte machen können. Aber immer wieder muß ich daran denken, dass meine Methode performanter und effizient ist.
Mehrsprachigkeit mit Platzhaltern und XML-Attributen
Die HTML-Tags wie hier <label> enthalten XML-Attribute, die mit "cpForms:" beginnen. "cpForms" wird von cpIApp als Selector vorgegeben. Mit den Attributen "textid", "textgroup" und "textnote" wird bestimmt, dass der im label-Tag stehende Text ein übersetzbarer Text ist. Der Webdesigner trägt hier den (deutschen) Vorgabetext ein. Der Parser des cpIApp-Frameworks erzeugt dann automatisch einen Eintrag in der Tabelle languages mit der textid, die hier angegeben wurde. Wenn der Eintrag schon existiert, wird er aus der Datenbank eingelesen (bzw. aus dem Shared-Memory geholt). Hat der Benutzer Englisch eingestellt und existiert zu der textid ein englischer Text, wird der englische Text ausgegeben.
Wenn ein Webdesigner mit der Arbeit beginnt, bekommt er zunächst eine Gruppe von textid's zugewiesen, die er dann in den Formularen einsetzen kann. Ein Kommentarbereich am Anfang der HTML-Datei mit den verwendeten textid's erleichtert die Übersicht für den Programmierer.
Hier ist ein Beispiel mit einer Auswahlliste und einer weiteren Syntax für Mehrsprachigkeit:
<tr class="odd">
<td><label
for="ID_IDEESTATUS">{LID:151014:Status der Geschäftsidee:LBL}</label>
</td>
<td><select name="FLD_IDEESTATUS" id="ID_IDEESTATUS" size="4">
<!--{OPTIONS_IDEESTATUS}-->
<option value="1">reine Idee</option>
<option value="2">Idee + schriftliches Konzept</option>
<option value="3">Idee + Prototyp</option>
<option value="4">Idee + Businessplan</option>
<option value="10">Sonstiger Status </option>
</select>
</td>
<td>{ERR_IDEESTATUS}{LID:151025:Das ist eine Hilfe für
das IDEESTATUS Feld:HLP}</td>
</tr>
Anstelle der XML-Attribute cpForms:textid kann man auch den Spezialplatzhalter {LID:::} verwenden. Dieser erlaubt eine kürzere Schreibweise und kann auch bei Buttons innerhalb von value-Attributen eingesetzt werden - hat aber den Nachteil, dass der Webdesigner nicht mehr das wirkliche Design zu sehen bekommt. Die Platzhalter stören.
Weitere Hinweise
Soll ein Feld ein Auto-Complete-Feld sein (also Textvorschläge via Ajax vom Server holen), dann setzt der Webdesigner ein HTML-Kommentar mit dem Wort <!--AutoComplete--> hinter das input-Feld.
Zu jedem Feld dürfen <!--Notizen--> gemacht werden, zum Beispiel über Eingabe-Restriktionen oder Zusammenhänge.
Beispiel-Formular forms/user/register.html
<!--[[Registrierungsformular]]-->
<div id="form_registration" class="form_container">
<!-- text-id von 100500 bis 100560 -->
<h1 cpForms:textid="100500" cpForms:textgroup="TIT" cpForms:textnote="Titel Benutzerregistrierung">Benutzerregistrierung</h1>
<p >{ICT:form/register:vorbemerkung}</p>
<p >{ICT:form/register:sichere-daten} Die hier aufgeführten, mit <img src="{IMGPATH}/safedata.gif" hspace="4" width="8" height="10" alt="(X) " />
gekennzeichneten Daten sind nicht öffentlich. Sie selbst entscheiden einzeln für jeden Kontakt, ob Sie diesem solche Daten freigeben.
Als Plattformbetreiber verpflichten wir uns, zu keinem Zeitpunkt private Daten Dritten zur Verfügung zu stellen.</p>
<form action="{FORM_ACTION}" method="POST" enctype="application/x-www-form-urlencoded"
accept-charset="utf-8" name="form_userreg" class="xform" >
<input type="hidden" name="FORM_NAME" value="form_userreg" />
<input type="hidden" name="FORM_CHARSET" value="testÜ" />
<input type="hidden" name="FLD_REGUNIQUEID" value="{VAL_REGUNIQUEID}" />
<table class="xform" width="100%" cellpadding="8" cellspacing="0" border="0" summary="">
<tr >
<td ><label for="ID_BENNAME" cpForms:textid="100501" cpForms:textgroup="LBL" cpForms:textnote="Anmeldeformular">Gewünschter Benutzername</label></td>
<td ><input type="text" id="ID_BENNAME" maxlength="30" value="{VAL_BENNAME}" name="FLD_BENNAME"/></td>
<td >{ERR_BENNAME}<span cpForms:textid="100502" cpForms:textgroup="HLP" cpForms:textnote="Anmeldeformular">Dies ist der spätere Anmeldename (Login).
Wenn der gewünschte Name bereits vergeben ist, erhalten Sie die Möglichkeit zur Änderung.</span></td>
</tr>
<tr >
<td ><label for="ID_BENPWD" cpForms:textid="100504" cpForms:textgroup="LBL" cpForms:textnote="Anmeldeformular">Gewünschtes Passwort</label> <img alt="(X) " src="{IMGPATH}/safedata.gif" width="8" height="10" hspace="4" /></td>
<td ><input type="password" id="ID_BENPWD" maxlength="30" value="" name="FLD_BENPWD"/></td>
<td ><span cpForms:textid="100505" cpForms:textgroup="HLP" cpForms:textnote="Anmeldeformular">Mit diesem Passwort
melden Sie sich in Zukunft am System an. Maximal 30 Zeichen.</span></td>
</tr>
<tr >
<td ><label for="ID_BENPWD2" cpForms:textid="100506" cpForms:textgroup="LBL" cpForms:textnote="Anmeldeformular">Passwort-Wiederholung</label> <img alt="(X) " src="{IMGPATH}/safedata.gif" width="8" height="10" hspace="4" /></td>
<td ><input type="password" id="ID_BENPWD2" maxlength="30" value="" name="FLD_BENPWD2"/></td>
<td >{ERR_BENPWD}<span cpForms:textid="100507" cpForms:textgroup="HLP" cpForms:textnote="Anmeldeformular">Zur Sicherheit gegen Tippfehler</span></td>
</tr>
<tr >
<td ><label for="ID_EMAIL" cpForms:textid="100508" cpForms:textgroup="LBL" cpForms:textnote="Anmeldeformular">Ihre E-Mailadresse</label> <img alt="(X) " src="{IMGPATH}/safedata.gif" width="8" height="10" hspace="4" /></td>
<td ><input type="text" id="ID_EMAIL" maxlength="255" value="{VAL_EMAIL}" name="FLD_EMAIL"/></td>
<td >{ERR_EMAIL}<span cpForms:textid="100509" cpForms:textgroup="HLP" cpForms:textnote="Anmeldeformular">Diese E-Mail-Adresse ist für Ihre Identifikation wichtig. Sie erhalten wichtige E-Mails an diese Adresse, zum Beispiel müssen Sie Ihre Mitgliedschaft über einen per Mail zugesandten Bestätigungs-Code bestätigen.</span></td>
</tr>
<tr>
<td ><label for="ID_VORNAME" cpForms:textid="100510" cpForms:textgroup="LBL" cpForms:textnote="Anmeldeformular">Vorname</label> <img alt="(X) " src="{IMGPATH}/safedata.gif" width="8" height="10" hspace="4" /></td>
<td ><input type="text" id="ID_VORNAME" maxlength="80" value="{VAL_VORNAME}" name="FLD_VORNAME"/></td>
<td >{ERR_VORNAME}<span cpForms:textid="100511" cpForms:textgroup="HLP" cpForms:textnote="Anmeldeformular">Bitte geben Sie Ihren Namen in korrekter Groß-/Kleinschreibung ein, weil dieser so auf Ihrer Kontaktseite erscheint.</span></td>
</tr>
<tr>
<td ><label for="ID_NACHNAME" cpForms:textid="100512" cpForms:textgroup="LBL" cpForms:textnote="Anmeldeformular">Nachname</label> <img alt="(X) " src="{IMGPATH}/safedata.gif" width="8" height="10" hspace="4" /></td>
<td ><input type="text" id="ID_NACHNAME" maxlength="80" value="{VAL_NACHNAME}" name="FLD_NACHNAME"/></td>
<td >{ERR_NACHNAME}<span cpForms:textid="100513" cpForms:textgroup="HLP" cpForms:textnote="Anmeldeformular">Ihr Nachname inklusive führender </span></td>
</tr>
<tr>
<td ><label for="ID_GTAG" cpForms:textid="100514">Geburtstag</label> <img alt="(X) " src="/img/safedata.gif" width="8" height="10" hspace="4" /></td>
<td ><input type="text" id="ID_GTAG" maxlength="10" value="{VAL_GTAG}" class="rechts" name="FLD_GTAG"/>
</td>
<td >{ERR_GTAG}<span cpForms:textid="100515" >Bitte geben Sie Ihren Geburtstag in der ISO-Form YYYY-MM-TT an, zum Beispiel 1960-12-23.</span></td>
</tr>
<tr>
<td ><label for="ID_CTRY" cpForms:textid="100516">Landescode</label></td>
<td ><input type="text" id="ID_CTRY" maxlength="2" value="{VAL_CTRY}" name="FLD_CTRY"/>
</td>
<td >{ERR_CTRY}<span cpForms:textid="100517" >Bitte geben Sie das Land an, in dem Ihr Hauptwohnsitz liegt. Der Landescode entspricht der Norm ISO 3166-2 (z.B. DE, AU, CH)</span></td>
</tr>
<tr>
<td ><label for="ID_LANG" cpForms:textid="100518" >Muttersprache</label></td>
<td ><input type="text" id="ID_LANG" maxlength="2" value="{VAL_LANG}" name="FLD_LANG"/></td>
<td >{ERR_LANG}<span cpForms:textid="100519">Bitte geben Sie den Sprachen-Code Ihrer Muttersprache an. Der ISO 639-2 Code für deutsch ist de, für englisch en</span></td>
</tr>
<tr>
<td ><label for="ID_USRGROUP" cpForms:textid="100520">Benutzergruppe</label></td>
<td ><select name="FLD_USRGROUP" id="ID_USRGROUP">
<option cpForms:textid="100521" value="1">Interessent</option>
<option cpForms:textid="100522" value="2">Investor</option>
<option cpForms:textid="100523" value="3">Projektanbieter</option>
<option cpForms:textid="100524" value="4">Unternehmensberater</option>
<option cpForms:textid="100525" value="5">Rechtsanwalt</option>
<option cpForms:textid="100526" value="6">Steuerberater</option>
<option cpForms:textid="100527" value="7">Notar</option>
</select>
</td>
<td ><span cpForms:textid="100530">Bitte wählen Sie die Benutzergruppe sorgfältig aus! Wählen Sie im Zweifel die Gruppe Interessent. Der Wechsel von der Gruppe Interessent zu einer der anderen Gruppe ist vorgesehen. Sie können später auch in mehreren Gruppen Mitglied sein.</span></td>
</tr>
</table>
<div class="type-text">
<label for="ID_USERLOGIN" cpForms:textid="100540">Speichern</label>
<input class="btnsubmit" type="submit" name="BTN_USERLOGIN" value="{LID:24:Anmelden:LBL}" />
<span cpForms:textid="100541">Speichern Ihrer Daten in der Datenbank des Systems</span>
</div>
</form>
</div>

