You are not logged in.

  • Login

1

Monday, February 23rd 2009, 10:27pm

Subform (Fieldset) in XML-Config-Datei - Zend Framework

Hi Mädels,

ich suche schon seit einiger Zeit eine Möglichkeit in einer Config-Datei eingelesen mit Zend_Config Subforms, also quasi Formular-Elemente in einem Fieldset, in der Config-Datei so zu speichern, dass Zend_Form sie dann auch wie alle anderen Elemente automatisch in ein Formular lädt. Wie müsste diese Angabe in etwa aussehen? Hat da irgendwer bisher Erfahrungen mit machen können?

Gruß
Lemmi

PS: Falls ich mich undeutlich ausgedrückt haben sollte: http://framework.zend.com/manual/de/zend…ickstart.config

2

Tuesday, February 24th 2009, 12:18am

Was für ein Zufall, damit wollte ich mich die Tage auch beschäftige :)
Ich steck noch in der Doku, aber dort steht doch eigentlich alles drin? (Punkt 21.2.7)

Die Xml Datei würde ich genau so aufbauen wie die Ini Datei.

XML Code

1
2
3
4
5
6
7
8
9
10
11
<development>
<user>
<login>
<action>/user/login</action>
<method>post</method>
</login>
<elements>
...
</elements>
</user>
</development>


Und dann natürlich nicht Zend_Config_Ini sondern Zend_Config_Xml nutzen :P


Mit praktischen Erfahrungen kann ich dir leider nicht dienen.

3

Tuesday, February 24th 2009, 9:50am

Und wie würdest du subforms oder displaygroups dort einarbeiten? Das weiß ich weder bei einer ini- noch bei einer xml-Configdatei.

4

Tuesday, February 24th 2009, 10:26am

Gut, displayGroups konnte ich mittlerweile einbinden. Nur subforms scheinen nach diesem Prinzip nicht zu funktionieren. (http://framework.zend.com/manual/de/zend…rm.forms.config)

5

Saturday, February 28th 2009, 5:34pm

So, falls es irgendwen noch interessiert. Das Zend-Framework ist sicherlich genial. Jedenfalls in vielerlei Hinsicht. Ausnahme bildet da meiner Meinung nach Zend_Form. Ich habe noch nie so viel Arbeit damit gehabt, ein Formular eines Frameworks in ein gewünschtes Layout einzuarbeiten.

Die Lösung, die ich nun in der DevZone von Zend fand, ist im Grunde noch ein Stück simpler. Jedenfalls bei Zend. Ich hab nun einfach eine Klasse für jedes Formular, dass wieder eine eigene Klasse (in meinem Fall Virb_Form) erbt, die wiederrum die Zend_Form Klasse erbt. Mit ein Paar Veränderungen in den add-Funktionen (Elements, Subforms, DisplayGroups), konnte ich so meine gewünschten Decoratoren einarbeiten, ohne mich mit eigenen Abzumühen oder die Config-Datei zu benutzen (was ich bis dato immer noch nicht geschafft habe).
Für alle, die es interessiert, hier die Virb_Form-Klasse. Sie ist natürlich noch nicht ausgereift und auch noch nicht wirklich ausführlich getestet. Auch die Decoratoren können momentan nur über das direkte Ändern der Klassenvariable geändert werden. Naja, ihr kennt das sicherlich. Sowas entwickelt sich mit der Zeit. Ach und bevor ich es vergesse: Kommentare fehlen natürlich auch noch. Aber da sich die meisten Funktionen auch selbst erklären, ist das in diesem Kontext denke ich erstmal nicht so wichtig.

Die Virb_Form-Klasse aus meinem sich noch entwickelnden ACP:
(Die Klasse hat noch zwei feine Extra. Ich weiß nicht, wie man so unkomfortabel entwickeln kann, naja, leider sind jegliche Buttons ganz nach System in einem einzellnen Container. So stellt das Framework also nicht die Möglichkeit, Buttons zum Absenden und Zurücksetzen, wie man es zum Beispiel auch hier im Forum hat, nebeneinander darzustellen. Das wird hier je nach Name des Elements erledigt und per DisplayGroup umgesetzt. Des Weiteren bekommt jeder Container eines Formular-Elements im HTML-Tag nicht nur eine spezifische Klasse (wie im Folgenden "element"), sondern darüber hinaus auch noch typspezifische Klassen-Angaben. So kann jedes Element je nach Typ formatiert werden. Zum Beispiel: submit-button - <div class="element button submit">)

PHP Quellcode

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<?php
 
class Vipanel_Form extends Zend_Form
{
	public $element_decorators = array(
		'ViewHelper',
		'Errors',
		array(array('data' => 'HtmlTag'), array('tag' => 'div', 'class' => 'element')),
		'Label',
		array(array('row' => 'HtmlTag'), array('tag' => 'div', 'class' => 'container'))
	);
 
	public $button_decorators = array(
		'ViewHelper'
	);
 
	public $button_group_decorators = array(
		'FormElements',
		array(array('data' => 'HtmlTag'), array('tag' => 'div', 'class' => 'element buttons')),
		array(array('row' => 'HtmlTag'), array('tag' => 'div', 'class' => 'container')),
	);
 
	public $display_group_decorators = array(
		'FormElements',
		array(array('group' => 'HtmlTag'), array('tag' => 'div', 'class' => 'display-group')),
	);
 
	public $subform_decorators = array(
		'FormElements',
		'Fieldset'
	);
 
	public $form_decorators = array(
		'FormElements',
		array('HtmlTag', array('tag' => 'div', 'class' => 'vipanel-form')),
		'Form',
	);
 
	private $__button_group_for = array(
		'submit', 'reset', 'button', 'image'
	);
 
	private $__button_group_id = 'buttons';
 
	protected $_element_groups = array(
		'button' => array('image', 'reset', 'submit'),
		'image' => array('captcha'),
		'multielements' => array('checkbox', 'multi', 'multicheckbox', 'multiselect', 'radio'),
		'multirows' => array('select', 'multiselect', 'textarea'),
		'input' => array('password', 'text')
	);
 
	private $__element_types = array();
 
	public function addElement($element, $name = null, $options = null)
	{
		parent::addElement($element, $name, $options);
 
		if($element instanceof Zend_Form_Element) {
			$name = $element->getName();
			$type = strtolower($element->getType());
			$type = substr($type, 18);
		}else {
			$type = $element;
			$element = $this->getElement($name);
		}
 
		$decorator = $this->element_decorators;		
 
		if(in_array($type, $this->__button_group_for)
		&& (null !== $name && '_button' == substr($name, -7))) {
 
			$decorator = $this->button_decorators;
 
			$display_group = $this->getDisplayGroup($this->__button_group_id);
			if(null === $display_group) {
				$group_options['decorators'] = $this->button_group_decorators;
				$this->addDisplayGroup(array($name), $this->__button_group_id, $group_options);
			}else {
				if($this->removeElement($name)) {
					$display_group->addElement($element);
				}
			}
		}
 
		if(empty($options['decorators'])) {
			$element->setDecorators($decorator);
		}
 
		$row_decorator = $element->getDecorator('data');
		if(false !== $row_decorator) {
			$class_names = array($row_decorator->getOption('class'));
			foreach($this->_element_groups as $group_name => $group_types) {
				foreach($group_types as $group_type) {
					if($type == $group_type) {
						$class_names[] = $group_name;
						continue 1;
					}
				}
			}
			$class_names[] = $type;
			$row_decorator->setOption('class', implode(' ', $class_names));
		}
 
		return $this;
	}
 
	public function addDisplayGroup(array $elements, $name, $options = null)
	{
		if(empty($options['decorators'])) {
			$options['decorators'] = $this->display_group_decorators;
		}
		return parent::addDisplayGroup($elements, $name, $options);
	}
 
	public function addSubForm(Zend_Form $form, $name, $order = null)
	{
		$decorators = $form->getDecorators();
		if(empty($decorators)) {
			$form->setDecorators($this->subform_decorators);
		}
 
		return parent::addSubForm($form, $name, $order);
	}
 
	public function loadDefaultDecorators()
	{
		$this->setDecorators($this->form_decorators);
	}
}


So kann jedes Formular mit einer separaten Klasse erstellt werden:

PHP Quellcode

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
<?php
 
class Auth_Login extends Vipanel_Form
{
	public function init()
	{
		$this->addElement('text', 'username', array(
			'label' => 'Username',
			'required' => true
		));
		$this->addElement('password', 'password', array(
			'label' => 'Password',
			'required' => true
		));
 
		$submit = $this->createElement('submit', 'login_button', array(
			'label' => 'Anmelden'
		));
 
		$this->addElement($submit);
 
		$reset = $this->createElement('reset', 'reset_button', array(
			'label' => 'Zurücksetzen'
		));
 
		$this->addElement($reset);
	}
}


So brauche ich einfach nur die Klasse aufrufen und rendern. Soweit das einfachste, was ich finden konnte.

Gruß
Lemmi

Similar threads

Social bookmarks