OOP Forms
Ik heb net een klein OOP classje gemaakt die een form op het beeld tevoorschijn geeft.
Ik ben totaal niet tevreden met het renderen van forms.
Ik heb tot nu toe 1 element gemaakt en dat is de 'text' element.
Hebben jullie wat tips om het renderen beter laten te verlopen?
Code (php)
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
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
<?php
class Form
{
private $_fields = array();
private $_attribs = array();
//todo
public function setAttrib($attribName, $attribValue) { $this->_attribs[$attribName] = $attribValue; }
public function getAttrib($attribName) { return $this->_attribs[$attribName]; }
public function addField($field)
{
$this->_fields[] = $field;
}
public function render()
{
$returnValue = '<form';
if (isset($this->_attribs['method']))
{
$returnValue .= ' method="' . $this->_attribs['method'] . '"';
}
else
{
$returnValue .= ' method="post"';
}
if (isset($this->_attribs['action']))
{
$returnValue .= ' action="' . $this->_attribs['action'] . '"';
}
$returnValue .= '>';
foreach ($this->_fields as $field)
{
$returnValue .= $field->render();
}
$returnValue .= '</form>';
return $returnValue;
}
}
?>
class Form
{
private $_fields = array();
private $_attribs = array();
//todo
public function setAttrib($attribName, $attribValue) { $this->_attribs[$attribName] = $attribValue; }
public function getAttrib($attribName) { return $this->_attribs[$attribName]; }
public function addField($field)
{
$this->_fields[] = $field;
}
public function render()
{
$returnValue = '<form';
if (isset($this->_attribs['method']))
{
$returnValue .= ' method="' . $this->_attribs['method'] . '"';
}
else
{
$returnValue .= ' method="post"';
}
if (isset($this->_attribs['action']))
{
$returnValue .= ' action="' . $this->_attribs['action'] . '"';
}
$returnValue .= '>';
foreach ($this->_fields as $field)
{
$returnValue .= $field->render();
}
$returnValue .= '</form>';
return $returnValue;
}
}
?>
Form_Element:
Code (php)
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
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
<?php
class Form_Element
{
public $_properties = array();
public $_label = '';
public $_name = '';
public $_value = '';
public function __construct($fieldName)
{
$this->_name = $fieldName;
}
public function setProperty($property, $value)
{
$this->_properties[$property] = $value;
}
public function setValue($value)
{
$this->_value = $value;
}
public function setLabel($label)
{
$this->_label = $label;
}
}
?>
class Form_Element
{
public $_properties = array();
public $_label = '';
public $_name = '';
public $_value = '';
public function __construct($fieldName)
{
$this->_name = $fieldName;
}
public function setProperty($property, $value)
{
$this->_properties[$property] = $value;
}
public function setValue($value)
{
$this->_value = $value;
}
public function setLabel($label)
{
$this->_label = $label;
}
}
?>
Form_Element_TextField:
Code (php)
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
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
<?php
class Form_Element_TextField extends Form_Element
{
public function render()
{
$returnValue = '';
if (isset($this->_label))
{
$returnValue .= '<label>' . $this->_label . '</label>';
}
$returnValue .= '<input type="text"';
$returnValue .= ' name="' . $this->_name . '"';
foreach ($this->_properties as $prop => $value)
{
$returnValue .= ' ' . $prop . '="' . $value . '"';
}
$returnValue .= ' />';
return $returnValue;
}
}
?>
class Form_Element_TextField extends Form_Element
{
public function render()
{
$returnValue = '';
if (isset($this->_label))
{
$returnValue .= '<label>' . $this->_label . '</label>';
}
$returnValue .= '<input type="text"';
$returnValue .= ' name="' . $this->_name . '"';
foreach ($this->_properties as $prop => $value)
{
$returnValue .= ' ' . $prop . '="' . $value . '"';
}
$returnValue .= ' />';
return $returnValue;
}
}
?>
- geen public properties maken, zorg dat je controle hebt over wat er in staat
- de prefix _ voor een propertienaam gebruiken sommige mensen omdat ze dan aangeven dat het niet public is. Ik zelf vind dat een beetje onzin, maar waarom gebruik je hem ook voor public properties?
- gebruik volledige namen of erkende afkortingen, dus of setAttribute of setAttr, maar ga liever geen zelf verzonnen afkortingen gebruiken.
- typ alles op dezelfde manier, dus niet zomaar 2 methods die op 1 regel staan.
Dan inhoudelijk:
- Elk Form Element moet een render method hebben, deze moet je dus verplicht stellen. Maak daarom Form_Element abstract en geef hem een abstracte render method
- Ik weet niet wat je hier fout aan vind, dit is hoe het hoort en hoe ik het ook gebruik (zie bijv. mijn OOPbuilder project waar ong. hetzelfde gebeurd).
Een eventuele abstracte superclass zou ik wel gebruiken om de standard attributen van een form element al in te bouwen. Een text, submit, checkbox, radiobutton etc zijn allemaal van het type 'input' en hebben (of kunnen) allemaal een class, id, name, value, type. Die kan je dus al in de superclass inbouwen zodat je niet voor alle elementen hetzelfde hoeft te doen.
Erwin, het lijkt me niet nodig om nog een extra interface bovenop onze momenteel al superklasse Form_Element te bouwen. Als je die nou abstract maakt met een abstracte method en elk element extend die Form_Element dan heb je volgens mij al het juiste effect?
Wat ik er fout aan vind is het hergebruiken van andere elementen.
Zo moet ik dan iedere keer die
Doen bij ieder nieuw element, dat is toch niet mooi?
Nu houd je het op forms, maar voor tabellen en andere elementen heb je het ook nodig. Ook die moet je kunnen renderen.
Simpel addChild methode erbij en je kan op een zeer eenvoudige wijze een hele boom opbouwen die je met 1 call kan renderen.
Er is vast een pattern voor, maar ik zo 1-2-3 niet een naam ervoor vinden.
Toevoeging op 02/07/2012 15:53:26:
Als voorbeeldje, dit is de interface die ik gebruik en al mijn view classes die pagina elementen bouwen implementeren die:
Code (php)
Aan het einde heb ik dan 1 $root en die hoef ik alleen maar te echoen en de hele boom wordt opgebouwd. Inclusief forms, tabellen, scripts, head, alles.
Hmm, ja daar dacht ik ook aan toen ik op reageren drukte. Aan dat laatste (addchild) had ik nog niet gedacht, maar klinkt geweldig!
Met dat addChild en de interface, kan je zowel form als element die interface laten implementeren. Je kan dan een form bouwen door elke keer form elementen (labels, input elementen, buttons) eraan toe te voegen middels de addChild. Bij het renderen moet je ervoor zorgen dat elk element ook de render() method van zijn child-elementen op het juiste moment aanroept en het wegschrijven gaat dan feitelijk vanzelf.