Skip to content

Commit 058d330

Browse files
committed
Render GridForm with new builder method
1 parent 4710e8f commit 058d330

File tree

5 files changed

+178
-156
lines changed

5 files changed

+178
-156
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace WebApp\BootstrapTheme\GridForm;
4+
5+
class FieldSetRenderer extends \WebApp\BootstrapTheme\FieldSetRenderer {
6+
7+
public function __construct($theme, $component) {
8+
parent::__construct($theme, $component);
9+
$this->addClass('grid-fieldset');
10+
}
11+
12+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
namespace WebApp\BootstrapTheme\GridForm;
4+
5+
class FormGroupRenderer extends \WebApp\Renderer {
6+
7+
public function __construct($theme, $component, $builder, $elementRenderer) {
8+
parent::__construct($theme, $component);
9+
$this->builder = $builder;
10+
$this->elementRenderer = $elementRenderer;
11+
$this->componentSizes = 'col-'.implode(' col-', explode(' ', $component->getAnnotation('grid-form/component-size', 'sm-12 md-8 lg-10')));
12+
}
13+
14+
public function startRow() {
15+
$rc = '';
16+
if ($this->component->getAnnotation('grid-form/new-row', FALSE) || !$this->builder->hasRow()) {
17+
if ($this->builder->hasRow()) {
18+
$rc .= '</div>';
19+
$rc = $this->builder->endRow();
20+
}
21+
$rc .= $this->builder->startRow();
22+
}
23+
return $rc;
24+
}
25+
26+
public function render() {
27+
// Ensure a row
28+
$rc = $this->startRow();
29+
30+
$child = $this->component;
31+
$error = $child->getError();
32+
$rc .= '<div class="form-group '.$this->getComponentSizeClasses().($error != NULL ? ' has-error' : '').'" id="form-group-'.$child->getId().'">';
33+
$rc .= $this->renderLabel();
34+
if ($error != NULL) {
35+
$this->addClass('is-invalid');
36+
$this->addAttribute('aria-describedby', 'validationFeedback-'.$child->getId());
37+
}
38+
39+
// we need to push defaultBuilder again
40+
$this->theme->pushRendererBuilder(new \WebApp\Builder\DefaultRendererBuilder($this->theme));
41+
$rc .= $this->elementRenderer->render();
42+
43+
$help = $child->getHelp();
44+
if ($help != NULL) {
45+
$rc .= '<small class="form-text text-muted">'.$help.'</small>';
46+
}
47+
$error = $child->getError(); // Could have been rendered already
48+
if ($error != NULL) {
49+
$rc .= '<div id="validationFeedback-'.$child->getId().'" class="invalid-feedback">'.$error.'</div>';
50+
}
51+
52+
// Undo defaultBuilder again
53+
$this->theme->popRendererBuilder();
54+
55+
$rc .= '</div>';
56+
return $rc;
57+
}
58+
59+
protected function renderLabel() {
60+
$rc = '';
61+
$label = $this->component->getLabel();
62+
if ($label != NULL) {
63+
$required = $this->component->isRequired() ? '<sup class="text-danger">*</sup>' : '';
64+
//$style = is_a($this->component, 'WebApp\Component\DynamicField') ? ' style="margin-top: 0.5em;"' : '';
65+
$rc .= '<label for="'.htmlentities($this->component->getId()).'">'.$label.$required.'</label>';
66+
}
67+
return $rc;
68+
}
69+
70+
public function getComponentSizeClasses() {
71+
return $this->componentSizes;
72+
}
73+
74+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
namespace WebApp\BootstrapTheme\GridForm;
4+
5+
class GridFormRendererBuilder extends \WebApp\Builder\AbstractRendererBuilder {
6+
7+
protected $form;
8+
9+
public function __construct($theme, $form) {
10+
parent::__construct($theme);
11+
$this->form = $form;
12+
$this->rowActive = FALSE;
13+
}
14+
15+
public function hasRow() {
16+
return $this->rowActive;
17+
}
18+
19+
public function startRow() {
20+
$this->rowActive = TRUE;
21+
return '<div class="form-row">';
22+
}
23+
24+
public function endRow() {
25+
$this->rowActive = FALSE;
26+
return '</div>';
27+
}
28+
29+
public function getRenderer($component) {
30+
$rc = $this->searchRendererInNamespace('WebApp\BootstrapTheme\GridForm', $component);
31+
if (($rc == NULL) && is_a($component, 'WebApp\Component\FormElement')) {
32+
$elemRenderer = $this->getComponentRenderer($component);
33+
if (is_a($component, 'WebApp\Component\FormCheck')) {
34+
$rc = $elemRenderer;
35+
} else {
36+
$rc = new FormGroupRenderer($this->theme, $component, $this, $elemRenderer);
37+
}
38+
} else if ($component->getAnnotation('grid-form/new-row', FALSE)) {
39+
if ($rc == NULL) $rc = $this->getComponentRenderer($component);
40+
$rc = new RowWrapper($this->theme, $component, $this, $rc);
41+
}
42+
return $rc;
43+
}
44+
45+
protected function getComponentRenderer($component) {
46+
$rc = $this->searchRendererInNamespace('WebApp\BootstrapTheme', $component);
47+
if ($rc == NULL) {
48+
$rc = $this->searchRendererInNamespace('WebApp\DefaultTheme', $component);
49+
}
50+
if ($rc == NULL) {
51+
$rc = new \WebApp\Renderer($this->theme, $component);
52+
}
53+
return $rc;
54+
}
55+
56+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace WebApp\BootstrapTheme\GridForm;
4+
5+
class RowWrapper extends \WebApp\Renderer {
6+
7+
public function __construct($theme, $component, $builder, $wrapped) {
8+
parent::__construct($theme, $component);
9+
$this->builder = $builder;
10+
$this->wrapped = $wrapped;
11+
}
12+
13+
public function startRow() {
14+
$rc = '';
15+
if ($this->component->getAnnotation('grid-form/new-row', FALSE) || !$this->builder->hasRow()) {
16+
if ($this->builder->hasRow()) {
17+
$rc .= '</div>';
18+
$rc = $this->builder->endRow();
19+
}
20+
$rc .= $this->builder->startRow();
21+
}
22+
return $rc;
23+
}
24+
25+
public function render() {
26+
// Ensure a row
27+
$rc = $this->startRow();
28+
$rc .= $this->wrapped->render();
29+
return $rc;
30+
}
31+
}

src/WebApp/BootstrapTheme/GridFormRenderer.php

Lines changed: 5 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -10,165 +10,14 @@ public function __construct($theme, $component) {
1010
parent::__construct($theme, $component, 'form');
1111
}
1212

13-
protected function getComponentSizeClasses($child) {
14-
$annotation = explode(' ', $this->searchAnnotation($child, 'grid-form/component-size', 'sm-12 md-8 lg-10'));
15-
return 'col-'.implode(' col-', $annotation);
16-
}
17-
18-
protected function searchAnnotation($child, $key, $default) {
19-
$rc = $child->getAnnotation($key);
20-
if ($rc == NULL) {
21-
$parent = $child->getParent();
22-
if ($parent != NULL) return $this->searchAnnotation($parent, $key, $default);
23-
return $default;
24-
}
25-
return $rc;
26-
}
27-
2813
public function render() {
29-
$rc = $this->renderStartTag($this->tagName);
30-
if ($this->component->hasFieldSets()) {
31-
$rc .= $this->renderFieldSets();
32-
}
33-
$rc .= $this->renderFormChildren($this->component->getChildren());
34-
35-
if ($this->hasRow) $rc .= '</div>';
36-
$rc .= $this->renderEndTag($this->tagName);
37-
return $rc;
38-
}
39-
40-
public function renderFieldSets() {
41-
$rc = '';
42-
43-
// Construct the components
44-
foreach ($this->component->getFieldSets() AS $fieldSet) {
45-
if ($fieldSet->isVisible()) {
46-
$rc .= '<div id="'.$fieldSet->getId().'" class="fieldset grid-fieldset">';
47-
$heading = new \WebApp\Component\Heading(NULL, 3, $fieldSet->getLabel());
48-
$rc .= $this->theme->renderComponent($heading);
49-
// Add the children
50-
$rc .= $this->renderFormChildren($fieldSet->getChildren());
51-
$rc .= '</div>';
52-
}
53-
}
54-
return $rc;
55-
56-
/*
57-
// Construct the components
58-
$tabSet = new \WebApp\Component\TabSet(NULL, $this->component->getId().'fieldsets');
59-
$tabSet->addClass('tabbed-fieldsets');
60-
foreach ($this->component->getFieldSets() AS $fieldSet) {
61-
if ($fieldSet->isVisible()) {
62-
$tab = $tabSet->createTab($fieldSet->getId(), $fieldSet->getLabel(), $fieldSet);
63-
$tab->addClass('p-4');
64-
}
65-
}
66-
67-
// Render them
68-
return $this->theme->renderComponent($tabSet);
69-
*/
70-
}
71-
72-
public function renderFormChildren($children) {
73-
$rc = '';
74-
foreach ($children AS $child) {
75-
// Field sets are rendered different
76-
if (!is_a($child, 'WebApp\\Component\\FieldSet')) {
77-
$rc .= $this->renderFormChild($child);
78-
}
79-
}
14+
$builder = new GridForm\GridFormRendererBuilder($this->theme, $this->component);
15+
$this->theme->pushRendererBuilder($builder);
16+
$rc = parent::render();
17+
$this->theme->popRendererBuilder();
18+
if ($builder->hasRow()) $rc .= $builder->endRow();
8019
return $rc;
8120
}
8221

83-
public function renderFormChild($child) {
84-
$rc = '';
85-
86-
if (is_a($child, 'WebApp\\Component\\FormElement') || is_a($child, 'WebApp\\Component\\I18nFormElement')) {
87-
if ($child->getAnnotation('grid-form/new-row', FALSE) || !$this->hasRow) {
88-
if ($this->hasRow) $rc .= '</div>';
89-
$rc .= '<div class="form-row">';
90-
$this->hasRow = TRUE;
91-
}
92-
93-
if (is_a($child, 'WebApp\\Component\\Checkbox')) {
94-
$rc .= $this->renderCheckbox($child);
95-
} else if (is_a($child, 'WebApp\\Component\\HiddenInput')) {
96-
$rc .= $this->theme->renderComponent($child);
97-
} else if (is_a($child, 'WebApp\\Component\\FileInput')) {
98-
$rc .= $this->renderFileInput($child);
99-
} else {
100-
$rc .= $this->renderGeneralFormChild($child);
101-
}
102-
} else if (is_a($child, 'WebApp\\Component\\Button') || is_a($child, 'WebApp\\Component\\Link')) {
103-
if ($this->hasRow) {
104-
$rc .= '</div>';
105-
$this->hasRow = FALSE;
106-
}
107-
$rc .= $this->theme->renderComponent($child);
108-
} else {
109-
$rc .= '<div class="form-row" id="form-row-'.$child->getId().'">';
110-
$rc .= $this->theme->renderComponent($child);
111-
$rc .= '</div>';
112-
}
113-
return $rc;
114-
}
115-
116-
public function renderGeneralFormChild($child) {
117-
$rc = '';
118-
119-
$error = $child->getError();
120-
$rc = '<div class="form-group '.$this->getComponentSizeClasses($child).($error != NULL ? ' has-error' : '').'" id="form-group-'.$child->getId().'">';
121-
$label = $child->getLabel();
122-
if ($label != NULL) {
123-
$rc .= '<label for="'.htmlentities($child->getId()).'">'.$label.'</label>';
124-
} else {
125-
$rc .= '<label for="'.htmlentities($child->getId()).'"></label>';
126-
}
127-
if ($error != NULL) {
128-
$child->addClass('is-invalid');
129-
$child->addAttribute('aria-describedby', 'validationFeedback-'.$child->getId());
130-
}
131-
$rc .= $this->theme->renderComponent($child);
132-
$help = $child->getHelp();
133-
if ($help != NULL) {
134-
$rc .= '<small class="form-text text-muted">'.$help.'</small>';
135-
}
136-
$error = $child->getError(); // Could have been rendered already
137-
if ($error != NULL) {
138-
$rc .= '<div id="validationFeedback-'.$child->getId().'" class="invalid-feedback">'.$error.'</div>';
139-
}
140-
$rc .= '</div>';
141-
142-
return $rc;
143-
}
144-
145-
public function renderCheckbox($child) {
146-
$child->addClass('form-check-input');
147-
$error = $child->getError();
148-
$rc = '<div class="form-group" id="form-group-'.$child->getId().'">'.
149-
'<div class="form-check">'.
150-
$this->theme->renderComponent($child);
151-
152-
$label = $child->getLabel();
153-
if ($label != NULL) {
154-
$rc .= ' &nbsp;<label for="'.htmlentities($child->getId()).'" class="form-check-label">'.$label.'</label>';
155-
}
156-
$rc .= '</div>'.
157-
'</div>';
158-
return $rc;
159-
}
160-
161-
public function renderFileInput($child) {
162-
$child->addClass('custom-file-input');
163-
$rc = '<div class="custom-file">'.
164-
$this->theme->renderComponent($child);
165-
$label = $child->getLabel();
166-
if ($label == NULL) $label = I18N::_('browse_file');
167-
if ($label != NULL) {
168-
$rc .= '<label for="'.htmlentities($child->getId()).'" class="custom-file-label">'.$label.'</label>';
169-
}
170-
$rc .= '</div>';
171-
return $rc;
172-
}
17322
}
17423

0 commit comments

Comments
 (0)