Skip to content

Commit 2172ba4

Browse files
castamirdg
authored andcommitted
ControlGroup: allows Container inside ControlGroup [Closes #96]
1 parent 6d140bc commit 2172ba4

File tree

5 files changed

+262
-2
lines changed

5 files changed

+262
-2
lines changed

src/Forms/Container.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ public function getCurrentGroup()
196196
public function addComponent(Nette\ComponentModel\IComponent $component, $name, $insertBefore = NULL)
197197
{
198198
parent::addComponent($component, $name, $insertBefore);
199-
if ($this->currentGroup !== NULL && $component instanceof IControl) {
199+
if ($this->currentGroup !== NULL) {
200200
$this->currentGroup->add($component);
201201
}
202202
return $this;
@@ -431,6 +431,9 @@ public function addContainer($name)
431431
{
432432
$control = new self;
433433
$control->currentGroup = $this->currentGroup;
434+
if ($this->currentGroup !== NULL) {
435+
$this->currentGroup->add($control);
436+
}
434437
return $this[$name] = $control;
435438
}
436439

src/Forms/ControlGroup.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,16 @@ public function add(...$items)
3737
if ($item instanceof IControl) {
3838
$this->controls->attach($item);
3939

40+
} elseif ($item instanceof Container) {
41+
foreach ($item->getComponents() as $component) {
42+
$this->add($component);
43+
}
4044
} elseif ($item instanceof \Traversable || is_array($item)) {
4145
$this->add(...$item);
4246

4347
} else {
4448
$type = is_object($item) ? get_class($item) : gettype($item);
45-
throw new Nette\InvalidArgumentException("IControl items expected, $type given.");
49+
throw new Nette\InvalidArgumentException("IControl or Container items expected, $type given.");
4650
}
4751
}
4852
return $this;

tests/Forms/ControlGroup.phpt

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
/**
4+
* Test: Nette\Forms\ControlGroup.
5+
*/
6+
7+
use Tester\Assert;
8+
use Nette\Forms\ControlGroup;
9+
10+
require __DIR__ . '/../bootstrap.php';
11+
12+
13+
function createContainer() {
14+
$container = new Nette\Forms\Container;
15+
$container->addText('street', 'Street');
16+
$container->addText('town', 'Town');
17+
return $container;
18+
}
19+
20+
$form = new Nette\Forms\Form;
21+
22+
23+
// controls only
24+
$group = $form->addGroup();
25+
$form->addText('name', 'Name');
26+
$form->addText('surname', 'Surname');
27+
28+
Assert::same($group, $form->getGroup(0));
29+
Assert::true($form->getGroup(0) instanceof ControlGroup);
30+
Assert::equal(2, count($group->getControls()));
31+
Assert::equal([$form['name'], $form['surname']], $group->getControls());
32+
33+
34+
// container only
35+
$group = $form->addGroup('Address');
36+
$form->addComponent(createContainer(), 'address');
37+
38+
Assert::same($group, $form->getGroup('Address'));
39+
Assert::true($form->getGroup('Address') instanceof ControlGroup);
40+
Assert::equal(2, count($group->getControls()));
41+
Assert::equal([$form['address']['street'], $form['address']['town']], $group->getControls());
42+
43+
44+
// nested containers
45+
$group = $form->addGroup('Nested');
46+
$container = createContainer();
47+
$container->addComponent(createContainer(), 'child');
48+
$form->addComponent($container, 'parent');
49+
50+
Assert::equal(4, count($group->getControls()));
51+
Assert::equal([$form['parent']['street'], $form['parent']['town'], $form['parent']['child']['street'], $form['parent']['child']['town']], $group->getControls());
52+
53+
54+
// container and controls
55+
$group = $form->addGroup('Mix');
56+
$form->addText('foo');
57+
$form->addComponent(createContainer(), 'mix');
58+
$form->addText('bar');
59+
60+
Assert::equal(4, count($group->getControls()));
61+
Assert::equal([$form['foo'], $form['mix']['street'], $form['mix']['town'], $form['bar']], $group->getControls());
62+
63+
64+
// addContainer
65+
$group = $form->addGroup('Container');
66+
$container = $form->addContainer('container');
67+
$container->addText('text1');
68+
$container->addText('text2');
69+
70+
Assert::equal(2, count($group->getControls()));
71+
Assert::equal([$form['container']['text1'], $form['container']['text2']], $group->getControls());
72+
73+
74+
// addContainer recursive
75+
$group = $form->addGroup('Container');
76+
$container1 = $form->addContainer('outer');
77+
$container2 = $container1->addContainer('inner');
78+
$container2->addText('text');
79+
80+
Assert::equal(1, count($group->getControls()));
81+
Assert::equal([$form['outer']['inner']['text']], $group->getControls());
82+
83+
Assert::equal(6, count($form->getGroups()));
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<form action="" method="post">
2+
3+
<fieldset>
4+
<table>
5+
<tr>
6+
<th><label for="frm-name">Name</label></th>
7+
8+
<td><input type="text" name="name" id="frm-name" class="text"></td>
9+
</tr>
10+
11+
<tr>
12+
<th><label for="frm-surname">Surname</label></th>
13+
14+
<td><input type="text" name="surname" id="frm-surname" class="text"></td>
15+
</tr>
16+
</table>
17+
</fieldset>
18+
19+
<fieldset>
20+
<legend>Address</legend>
21+
22+
<table>
23+
<tr>
24+
<th><label for="frm-address-street">Street</label></th>
25+
26+
<td><input type="text" name="address[street]" id="frm-address-street" class="text"></td>
27+
</tr>
28+
29+
<tr>
30+
<th><label for="frm-address-town">Town</label></th>
31+
32+
<td><input type="text" name="address[town]" id="frm-address-town" class="text"></td>
33+
</tr>
34+
35+
<tr>
36+
<th><label for="frm-address-country">Country</label></th>
37+
38+
<td><input type="text" name="address[country]" id="frm-address-country" class="text"></td>
39+
</tr>
40+
</table>
41+
</fieldset>
42+
43+
<fieldset>
44+
<legend>Shipping Address</legend>
45+
46+
<table>
47+
<tr>
48+
<th><label for="frm-shippingAddress-street">Street</label></th>
49+
50+
<td><input type="text" name="shippingAddress[street]" id="frm-shippingAddress-street" class="text"></td>
51+
</tr>
52+
53+
<tr>
54+
<th><label for="frm-shippingAddress-town">Town</label></th>
55+
56+
<td><input type="text" name="shippingAddress[town]" id="frm-shippingAddress-town" class="text"></td>
57+
</tr>
58+
59+
<tr>
60+
<th><label for="frm-shippingAddress-country">Country</label></th>
61+
62+
<td><input type="text" name="shippingAddress[country]" id="frm-shippingAddress-country" class="text"></td>
63+
</tr>
64+
65+
<tr>
66+
<th><label for="frm-note">Note</label></th>
67+
68+
<td><textarea name="note" id="frm-note"></textarea></td>
69+
</tr>
70+
</table>
71+
</fieldset>
72+
73+
<fieldset>
74+
<legend>Nested</legend>
75+
76+
<table>
77+
<tr>
78+
<th><label for="frm-parent-street">Street</label></th>
79+
80+
<td><input type="text" name="parent[street]" id="frm-parent-street" class="text"></td>
81+
</tr>
82+
83+
<tr>
84+
<th><label for="frm-parent-town">Town</label></th>
85+
86+
<td><input type="text" name="parent[town]" id="frm-parent-town" class="text"></td>
87+
</tr>
88+
89+
<tr>
90+
<th><label for="frm-parent-country">Country</label></th>
91+
92+
<td><input type="text" name="parent[country]" id="frm-parent-country" class="text"></td>
93+
</tr>
94+
95+
<tr>
96+
<th><label for="frm-parent-child-street">Street</label></th>
97+
98+
<td><input type="text" name="parent[child][street]" id="frm-parent-child-street" class="text"></td>
99+
</tr>
100+
101+
<tr>
102+
<th><label for="frm-parent-child-town">Town</label></th>
103+
104+
<td><input type="text" name="parent[child][town]" id="frm-parent-child-town" class="text"></td>
105+
</tr>
106+
107+
<tr>
108+
<th><label for="frm-parent-child-country">Country</label></th>
109+
110+
<td><input type="text" name="parent[child][country]" id="frm-parent-child-country" class="text"></td>
111+
</tr>
112+
</table>
113+
</fieldset>
114+
115+
<table>
116+
<tr>
117+
<th></th>
118+
119+
<td><input type="submit" name="_submit" value="Order" class="button"></td>
120+
</tr>
121+
</table>
122+
123+
</form>

tests/Forms/Forms.renderer.5.phpt

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
/**
4+
* Test: Nette\Forms default rendering containers inside groups.
5+
*/
6+
7+
use Tester\Assert;
8+
9+
require __DIR__ . '/../bootstrap.php';
10+
11+
12+
function createContainer() {
13+
$container = new Nette\Forms\Container;
14+
$container->addText('street', 'Street');
15+
$container->addText('town', 'Town');
16+
$container->addText('country', 'Country');
17+
return $container;
18+
}
19+
20+
$form = new Nette\Forms\Form;
21+
22+
// controls only
23+
$form->addGroup();
24+
$form->addText('name', 'Name');
25+
$form->addText('surname', 'Surname');
26+
27+
// container only
28+
$form->addGroup('Address');
29+
$form->addComponent(createContainer(), 'address');
30+
31+
// container + control
32+
$form->addGroup('Shipping Address');
33+
$form->addComponent(createContainer(), 'shippingAddress');
34+
$form->addTextArea('note', 'Note');
35+
36+
// nested containers
37+
$form->addGroup('Nested');
38+
$container = createContainer();
39+
$container->addComponent(createContainer(), 'child');
40+
$form->addComponent($container, 'parent');
41+
42+
$form->setCurrentGroup();
43+
$form->addSubmit('submit', 'Order');
44+
45+
$form->fireEvents();
46+
47+
Assert::matchFile(__DIR__ . '/Forms.renderer.5.expect', $form->__toString(TRUE));

0 commit comments

Comments
 (0)