Bei meinem Turbogears-Projekt verwende ich zur Formularanzeige und -validierung die empfohlenen ToscaWidgets. Die Dokumentation dazu ist spärlich, aber wenn man verstanden hat, dass es sehr einfach ist eigene Templates zu verwenden, kommt man sehr gut mit ihnen zurecht.
Nur eines hat mir gestern und heute Kopfzerbrechen bereitet: die Validierung bei der Verwendung des FormFieldRepeater-Widgets. Dieses wird benötigt, wenn man wiederholende Formularbereiche – wie z.B. mehrere Email-Adressen pro Kontakt – verwenden möchte. Hier ein kleines Code-Beispiel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | class EmailSubForm(twf.TableFieldSet): template = "…" hover_help = True class fields(WidgetsList): id = twf.HiddenField(validator=twv.Int(not_empty=True)) email = twf.TextField( label_text='Email-Address', validator=twv.Email(not_empty=True)) remarks = twf.TextField( label_text='Remarks', validator=twv.UnicodeString(not_empty=True)) class ContactForm(twf.TableForm): hover_help = True template = "…" submit_text = "Update Contact" class fields(WidgetsList): name = twf.TextField( label_text='Name', validator=twv.UnicodeString(not_empty=True)) […] emails = twf.FormFieldRepeater( widget=EmailSubForm(), repetitions=0) |
So weit, so gut. Das Formular ´ContactForm´ wird auf der Website angezeigt inklusive der vorhandenen Email-Adressen im "Unterformular" ´EmailSubForm´. Fehler bei der Eingabe im Hauptformular werden auch angezeigt – z.B. keine Eingabe im Feld ´name´. Jedoch wird auf Eingabefehler im Unterformular nicht geprüft!
Ich habe Herrn Google gefragt, viel gelesen, nichts gefunden was mir
weitergeholfen hätte. Die Lösung kam durch ausprobieren. Setzt man den Wert für
repetitions (letzte Zeile) auf 1 funktioniert alles. Warum? keine Ahnung.
Die korrigierte Fassung des ContactForms sieht so aus:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class ContactForm(twf.TableForm): hover_help = True template = "…" submit_text = "Update Contact" class fields(WidgetsList): name = twf.TextField( label_text='Name', validator=twv.UnicodeString(not_empty=True)) […] emails = twf.FormFieldRepeater( widget=EmailSubForm(), repetitions=0) |
Ich hoffe ich vergesse es nicht und es hilft jemandem weiter :-)