Wer (y)A(ml) sagt, muss auch B sagen

YAML ist unser hochgeschätztes CSS Framework, bitte nie wieder ohne! Wie man YAML und SilverStripe vereint, haben wir schon in einem unserer Blogbeiträge gezeigt. YAML hat bezüglich Formularen sehr genaue Anforderungen an das Markup, denen SilverStripe von Haus aus nicht gerecht wird. Da werden zum Beispiel <input> Felder in <div> geschachtet. Wer das ändern möchte, muss tief in die Trickkiste greifen. Aber uns ist ja bekanntlich kein Trick zu schwer ;-)

Sascha hat en passent ein Modul für SilverStripe entwickelt, das er CustomHtmlForm genannt hat. Einmal installiert bietet es dem Programmierer mittels Templates volle Kontrolle über das Markup und verändert den Umgang mit JavaScript.

Im folgenden Beispiel will ich den Weg zu einem Kontaktformular beschreiben. Jedes Formular hat eine eigene Klasse und mit dieser fange ich jetzt an:

class ContactForm extends CustomHtmlForm {

protected $formFields = array(
'Name' => array(
'type' => 'TextField',
'title' => 'Name',
'checkRequirements' => array(
'isFilledIn' => true,
'hasMinLength' => 3
)
),
'Email' => array(
'type' => 'TextField',
'title' => 'Email Adresse',
'value' => '',
'checkRequirements' => array(
'isFilledIn' => true,
'isEmailAddress' => true
)
),
'Message' => array(
'type' => 'TextareaField',
'title' => 'Nachricht',
'checkRequirements' => array
(
'isFilledIn' => true,
'hasMinLength' => 3
)
)
);

protected $preferences = array(
'submitButtonTitle' => 'absenden'
);

protected function fillInFieldValues() {
$member = Member::currentUser();
if ($member) {
$this->formFields['Name']['value'] = $member->Surname;
$this->formFields['Email']['value'] = $member->Email;
}
}

protected function submitSuccess($data, $form, $formData) {

$email = new Email(
'info@pourlatable.de',
'rlehmann@pixeltricks.de',
'Kontaktformular Anfrage',
''
);

$email->setTemplate('MailContact');
$email->populateTemplate(
array(
'Name' => $formData['Name'],
'Email' => $formData['Email'],
'Message' => str_replace('\r\n', '<br>', nl2br($formData['Message']))
)
);

$email->send();
}

}

 

Im Array $formFields werden die Felder des Formulars definiert. „Name“ ist der Identifier des Formularfeldes, „type“ ist der SilverStripe Feldtyp und „title“ ist die Beschriftung des Feldes. Mit „checkRequirements“ kann man eine Reihe von Validierungsmethoden konfigurieren. Es gibt zur Zeit die Methoden hasSpecialSigns, isEmailAddress, isCurrency, isDate, isFilledIn, isFilledInDependantOn, isNumbersOnly, hasMinLength, hasLength, mustEqual, mustNotEqual.

Im Array $preferences wird hier nur die Beschriftung des Submit Buttons festgelegt.

Die Methode fillInFieldValues() dient zum Befüllen der Eingabefelder. Im Bespiel werden die Felder „Name“ und „Email“ mit den entsprechenden Werten eines eingeloggten Nutzers befüllt.

Die Methode submitSuccess() wird aufgerufen, wenn keine Validierungsfehler aufbetreten sind. Im Gegensatz zur herkömmichen Action-Methode eines SilverStripe Formulars wird hier noch das Array $formData mitgeführt, das die Formulareingaben enthällt.

So, das Formular brauch jetzt noch ein Template und muss in einen Controller implementiert werden. Ich fange mit dem „CustomHtmlForm“-atierten Template an. Es wird unter themes/blackcandy/templates/layout/ abgespeichert:

<% if IncludeFormTag %>
<form class="yform" $FormAttributes >
<% end_if %>

$CustomHtmlFormMetadata

<fieldset>
<legend>Kontaktformular</legend>
<div class="subcolumns">
<div class="c50l">
<div class="subcl">
$CustomHtmlFormFieldByName(Name)
</div>
</div>
<div class="c50r">
<div class="subcr">
$CustomHtmlFormFieldByName(Email)
</div>
</div>
</div>
$CustomHtmlFormFieldByName(Message)
</fieldset>

<div class="actionRow">
<div class="type-button">
<% control Actions %>
$Field
<% end_control %>
</div>
</div>
<% if IncludeFormTag %>
</form>
<% end_if %>

Das Formular ist auf YAML-Art gestaltet. Mit $CustomHtmlFormFieldByName() werden die einzelnen Felder eingebaut. Der Parameter ist der Identifier des Feldes. Zum restlichen Zauber kann ich nicht viel sagen, das muss euch Sascha näher bringen ;)

Jetzt muss das Formular noch in einem Controller „angemeldet“ und aufgerufen werden. Das geschieht in der init() Methode des Controllers:

public function init() {
$this->registerCustomHtmlForm('ContactForm', new ContactForm($this));
parent::init();
}

Der Aufruf im Template des Controllers findet dann durch

$InsertCustomHtmlForm(ContactForm)

statt. So einfach geht das mit SilverStripe, ein wenig pixeltricks und unserem Modul CustomHtmlForm.

Das Modul CustomHtmlForm kann hier auf bitbucket heruntergeladen werden.

Die (nur auf englisch verfügbare) API-Dokumentation ist hier auf unserer SilverCart-Projektseite.

Tags: