Türchen 13: Feldtypen und Formularen im Magento Backend

Schön das ihr es zum dreizehnten Türchen des Adventskalenders geschafft habt. Da ich schon lange einmal aufschreiben wollte, welche Möglichkeiten die Formulare im Magento-Backend bieten, fangen wir heute mal mit den Formularen an.

Wie man Formulare erzeugt, wisst ihr vermutlich alle, der Vollständigkeit halber aber ein Beispiel:

class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Price extends Mage_Adminhtml_Block_Widget_Form
{
    protected function _prepareForm()
    {
        $product = Mage::registry('product');

        $form = new Varien_Data_Form();
        $fieldset = $form->addFieldset('tiered_price', array('legend'=>Mage::helper('catalog')->__('Tier Pricing')));

        $fieldset->addField('default_price', 'label', array(
                'label'=> Mage::helper('catalog')->__('Default Price'),
                'title'=> Mage::helper('catalog')->__('Default Price'),
                'name'=>'default_price',
                'bold'=>true,
                'value'=>$product->getPrice()
        ));

        $fieldset->addField('tier_price', 'text', array(
                'name'=>'tier_price',
                'class'=>'requried-entry',
                'value'=>$product->getData('tier_price')
        ));
	[...]

        $this->setForm($form);
    }
}// Class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Price END

Wenn man seinen Block von Mage_Adminhtml_Block_Widget_Form ableitet und sich an die Standards hält, die Magento vorgibt, passiert das meiste von allein. Wer wissen will, wie man Formulare grundsätzlich baut, schaut mal zu Ben Robbie, der hat einen Artikel geschrieben, wie man Formulare und Grids baut.

In diesem Artikel möchte ich mich aber auf Feldtypen konzentrieren. Leider gibt es viel zu wenige Artikel dazu, was dazu führt, dass ich immer im Core wühlen muss, welche Typen es gibt und welche Konfigurationsmöglichkeiten sie haben. Ich möchte hier einen Überblick bieten, das führt leider dazu, dass ich nicht in alle Details gehen kann. Aber wenn hier schon der Anfang gelegt ist, seid ihr herzlich eingeladen einen Artikel zu schreiben, ich freue mich auch über Links via Mail.

Bevor wir uns jetzt in die Feldtypen stürzen, eine kurze Beschreibung eines Felds:

	$configuration = array($key => $value)
	$fieldset->addField($name, $typ, $configuration);

Für die meisten Elemente ist es sinnvoll in der Konfiguration ein Label und einen Namen anzugeben, außerdem kann man den meisten Feldern einen Wert (value) geben. Zusätzlich kann man die Felder als Pflichtfelder definieren, indem man den Wert für "required" auf "true" setzt. Zuletzt kann man die CSS-Klasse via "class" setzen, um z.B die Prüfung auf Text (input-text) zu realisieren. Nicht zu vergessen ist, dass man viele HTML-Attribute über die Konfiguration übergeben kann, welche genau findet ihr in der Methode getHtmlAttributes().

Und ein letzter Tipp: Die Methode addField gibt euch das erzeugte Element zurück, auf diesem können weitere Setter angewendet werden.

Feldtypen

Die verschiedenen Feldtypen findet man hier:

lib/Varien/Data/Form/Element/

Um sie ein wenig zu sortieren unterscheide ich mutwillig drei Typen: Auswahl von vorgegebenen Antworten, Eintragen eigener Antworten und alles andere ;-). Ursprünglich wollte ich sie nach dem Alphabet sortieren, aber ich habe gerade beschlossen zu probieren, sie sinnvoll zu sortieren.

Vorgaben machen

Wenn man die Antworten gerne vorgeben möchte, stehen folgende Typen zur Verfügung.

Checkbox.php

checkbox

Fangen wir mit den einfachen Elementen an, der Typ Checkbox ist genau das, eine Checkbox. Ist sie markiert, wird der Wert übertragen, wenn nicht, dann nicht. Wie oben beschrieben, hat sie ein Label, einen Namen und einen Wert.

Checkboxes.php

checkboxes

Mehrere Checkboxen. Man kann beliebig viele Checkboxes damit erzeugen. Es gibt dabei den Konfigurationsschlüssel "values" => array($value => $label). Damit ist es möglich verschiedene Werte zur Selektion vorzugeben.

Multiselect.php

multiselect

Und da wären wir auch schon beim Multiselect. Ein Multiselect erfüllt auf den ersten Blick den gleichen Zweck wie Checkboxes, der entscheidende Unterschied ist aber, dass man die Optionen sortieren kann und "optgroup"s definieren kann um das ganze Übersichtlicher zu gestalten

Um die Werte zu sortieren, muss der Wert für "values" folgendermaßen angegeben werden:

$values = array(
			array(
				'label' => 'optgroup',
				'value' =>
					array(
						array(
							'value' => 'test',
							'label' => 'label'
						)
//						[…] Hier können beliebig viele Optionen kommen
					)
			),
//			[…] Hier können beliebig viele Optgroups kommen
		);

Außerdem müsst ihr beachten, dass der value als Array angegeben wird. Aber wie immer gilt: Es gibt nur einen Weg Magento zu lernen, Core lesen!

Tipp: Die Optgroups sind dabei optional.

Date.php

date

Der Einfachheit halber, verweise ich hier auf den Artikel von Daniel Barty. Er hat schon schön aufgeschrieben, wie man die Felder benutzt. Ergänzen sollte man nur, dass es einen Konfigurationsschlüssel mit dem schönen Namen "time" gibt, der boolsch ist. Er tut was sein Name sagt und erweitert das Feld um die Zeit, wenn er true ist.

Time.php

time

Ich denke die Zeit ist selbsterklärend :-)
Zu beachten ist die Darstellung in drei Select-Boxen. Ich habe noch nicht danach gesucht, weil ich es bisher nie gebraucht habe, aber ich gehe davon aus, das Magento eine Methode bietet um die Zeit "einfach" weiter zu verarbeiten, ähnlich wie bei Daten (Datums?), und das zusammenfügen nicht händisch machen zu müssen.

… Jetzt habe ich doch gesucht, weil ich nicht mehr wusste, wie die Methode: Mage_Core_Controller_Varien_Action::_filterDates() hieß :-) Daneben gibt es eine Methode: _filterDateTime(), rauszukriegen wie die funktioniert überlasse ich aber euch, insb. weiß ich nicht, ob die nur für DateTime-Kobinationen oder auch nur Zeit funktioniert.

Radio.php

radio

Wofür Radio da ist, habe ich noch nicht begriffen, ein einzelner Radio-Button macht in meinen Augen erstmal nicht soviel Sinn.

Radios.php

radios

Mehrere davon, ergeben dann aber einen Sinn. Die Werte werden als Array übergeben, jeder Eintrag hat Wert (value) und Label (label).

$values = array(
 array(
	 'value' => 'val1',
	 'label' => 'lab1'
 ),
 array(
	 'value' => 'val2',
	 'label' => 'lab2'
 ),
 array(
	 'value' => 'val3',
	 'label' => 'lab3'
 ),
);

Select.php

select

Ein Select ist ein . Ein Anwendungsfall diesen Typ der Textarea vorzuziehen ist, z.B. wenn man die Zeilenumbrüche an bestimmten Stellen möchte und die Zeilenlänge begrenzt ist, also z.B. für die Adresse auf der Rechnung. Das Fenster im Kuvert ist ja nur begrenzt lang.

Tipp: Um die Anzahl der Zeilen zu ändern ist lineCount die Eigenschaft die ihr ändern wollt.

Note.php

note

Ihr wollt eine Notiz in dem Formular hinterlegen? Benutzt "note"! In die Konfiguration noch "text" hinterlegt und ihr macht eure Benutzer glücklich. Denn sie wissen jetzt, was von ihnen erwartet wird.

Obscure.php

obscure

Komischer Name für "Password". Wobei, nicht so ganz. Das Problem bei Passwort-Feldern ist, dass die Eingabe zwar maskiert ist, aber im HTML-Code das Passwort immer noch steht. Um das zu verhindern kann man "obscure" benutzen. Ist ein Wert gesetzt steht in dem Feld *****, ist keiner gesetzt ist es leer.

Achtung: Ich weiß nicht, ob man bei der Weiterverarbeitung mit dem Feld aus Versehen die Daten eines Objekts überschreiben kann, oder das verhindert wird, aber ihr dürft das gerne ausprobieren und in den Kommentaren hinterlassen.

Password.php

password

Und nun steigen wir in den HTML-Standard ab und es wird langweilig… Passwort ist bekannt, hoffe ich.

Text.php

text

<input type="text">, muss ich mehr schreiben?

Textarea.php

textarea

Und das ist eine <textarea>, ööddeee :-)

Und der Rest…

Schauen wir uns an, was wir sonst noch so haben.

Label.php

label

Wenn ihr nicht wollt, dass der Benutzer den Wert verändern nehmt ihr Label. Label erzeugt links ein Label, wie üblich und zeigt den Wert nur an, ohne die Möglichkeiten zu bieten, ihn zu ändern.

Submit.php

submit

Ein Submit-Button, sollte auch bekannt sein.

Button.php

button

Gibt eine Button. Für das Formular und die Datenverarbeitung erstmal nicht so interessant, aber mit JavaScript kann man viel Spaß haben.

Hidden.php

Ein . Kann man eigentlich auch in die Session schreiben, wenn man es nach dem Abschicken des Formulars wieder haben will? Vollkommen richtig, ABER ich z.B. benutze es um die Daten eines flexibles Formulars, das mit JavaScript generiert wird als JSON zu speichern und via verstecktem Feld zu übertragen.

Danke fürs Lesen

Ihr habt bis hierhin durchgehalten? Schön, ich hoffe ich habe euch damit geholfen. Wie immer freuen wir Blogger uns über einen Kommentar. Und in der Hoffnung Tobi schmeißt ihn nicht raus, kann ich jetzt endlich mal einen eigenen Flattr-Button setzen:


Flattr this

Du hast Fehler gefunden und weißt viel mehr über Formulartypen? Ich habe wichtige Dinge vergessen? Schreibt es in die Kommentare oder einen eigenen Artikel und postet den Link in die Kommentare!

So jetzt noch der Code-Schnippsel mit dem ich das alles ausprobiert habe, es ist unsortiert und hat für viele Fälle zuviele Konfigurationsschlüssel, aber es nicht anzuhängen, hilft euch vermutlich auch nicht :-)

<?php $fieldtype = array( 	'button', 	'checkbox', 	'checkboxes', 	'column', 	'editor', 	'file', 	'gallery', 	'hidden', 	'image', 	'imagefile', 	'label', 	'link', 	'multiline', 	'multiselect', 	'note', 	'obscure', 	'password', 	'radio', 	'reset', 	'select', 	'submit', 	'text', 	'textarea', 	'time' ); $multiselect = array( 	array( 		'label' =--> 'optgroup',
		'value' => array(
			array(
				'value' => 'test',
				'label' => 'label'
			)
		)
	)
);
foreach ($fieldtype as $f) {
	$fieldset->addField($f, $f, array(
			 'label' => $f,
			 'name' => $f,
			 'values' => $f == 'multiselect' ? $multiselect : array(
				 'value1' => 'value1Label',
				 'value2' => 'value2Label'
			 ),
			 'value' => $f == 'multiselect' ? array('value1') : 'value1',
			 'comment' => 'comment',
			 'href' => 'http://www.ikonoshirt.de',
			 'line_count' => 5,
			 'text' => 'text',
			 'cols' => 1,
			 'rows' => 1,
			 'default_html' => 'test'
	));

}
$f = 'radios';
$fieldset->addField($f, $f, array(
			 'label' => $f,
			 'name' => $f,
			 'values' => array(
				 array(
					 'value' => 'val1',
					 'label' => 'lab1'
				 ),
				 array(
					 'value' => 'val1',
					 'label' => 'lab1'
				 ),
				 array(
					 'value' => 'val1',
					 'label' => 'lab1'
				 ),
			 ),
			 'value' => $f == 'multiselect' ? array('value1') : 'value1',
			 'comment' => 'comment'
	));

	$fieldset->addField('start', 'date', array(
	      'name' => 'start',
	      'label' => Mage::helper('core')->__('Startdate (yyyy-mm-dd)'),
	      'class' => 'validate-date',
	      'required' => true,
	      'format' => 'yyyy-MM-dd hh:mm:ss',
	      'image' => $this->getSkinUrl('images/grid-cal.gif'),
				'time' => true
	    ));



Ein Beitrag von Fabian Blechschmidt
Fabian's avatar

Fabian Blechschmidt entwickelt seit 2004 mit PHP. Vier Jahre später hat er sich damit selbstständig gemacht und ist seit 2011 auf Magento fokusiert. Im Oktober 2011 hat er erfolgreich die Prüfung zum Magento Certified Developer absolviert. In seiner Freizeit besucht er gerne Magento Stammtische und hält unter anderem dort Vorträge. Außerdem organisiert er mit an den Magento Hackathons.

Alle Beiträge von Fabian

Kommentare
Fabian Blechschmidt am

Da ich gerade über noch schönere Beispiele gestolpert bin: http://www.excellencemagentoblog.com/magento-admin-form-field

Michael am

Vielen Dank Fabian für die Auflistung. Und wem diese Typen noch nicht langen, kann sich seine eigene Typen anlegen. Ich habe die Weihnachtsfeiertage genutzt, um eine kleine Beschreibung zu diesem Thema zu schreiben.

http://auit.de/code-snippets/ein-magento-datentyp-timeline-108-article

Bastian Ike am

Zum Thema (Multi-)Selects: SourceModels wären hier noch eine Alternative zu Arrays.

Ansonsten, wie Andreas schon schreibt, eine gute Übersicht!

Andreas von Studnitz am

Danke für die umfangreiche Zusammenfassung, das ist perfekt zum Nachschlagen.

Dein Kommentar