<?php
+use \PFF\HtmlBuilder\Tag as Tag;
+
class IPF_Admin_App extends IPF_Application
{
public function __construct()
public static function renderForm($form)
{
- return $form->htmlOutput(
- '<div class="form-row"><div>%2$s %1$s%3$s%4$s</div></div>',
- '<div>%s</div>',
- '</div>',
- '<p class="help">%s</p>',
- true,
- '<div class="form-group-title">%s</div>',
- false);
+ return $form->renderLayout(new IPF_Admin_Form_Layout, false);
+ }
+}
+
+class IPF_Admin_Form_Layout extends IPF_Form_LayoutAdapter
+{
+ public function startForm($form)
+ {
+ $errors = $this->commonErrors($form);
+ return $this->errors($errors) .
+ $this->hiddenWidgets($form);
+ }
+
+ public function startGroup($label)
+ {
+ if ($label)
+ return Tag::div(array('class' => 'form-group-title'), $label)->html();
+ else
+ return '';
+ }
+
+ public function field($boundField, $label)
+ {
+ if ($boundField->help_text) {
+ $help_text = Tag::p(array('class' => 'help'))
+ ->raw($boundField->help_text);
+ } else {
+ $help_text = '';
+ }
+
+ return $this->errors($boundField->errors) .
+ Tag::div(array('class' => 'form-row'),
+ Tag::div()
+ ->raw($label)
+ ->raw(' ')
+ ->raw($boundField->render_w())
+ ->append($help_text));
+ }
+
+ private function errors($errors)
+ {
+ if (!count($errors))
+ return '';
+
+ $ul = Tag::ul(array('class' => 'errorlist'));
+ foreach ($errors as $err)
+ $ul->append(Tag::li(null, $err));
+ return Tag::div(null, $ul);
}
}
<?php
+use \PFF\HtmlBuilder\Tag as Tag;
+
abstract class IPF_Form implements Iterator
{
public $fields = array();
return '';
}
- public function render_top_errors()
+ public function hiddenFields()
{
- $top_errors = (isset($this->errors['__all__'])) ? $this->errors['__all__'] : array();
- array_walk($top_errors, 'IPF_Form_htmlspecialcharsArray');
- return new IPF_Template_SafeString(IPF_Form::renderErrorsAsHTML($top_errors), true);
+ $hidden = array();
+ foreach ($this->fields as $name => $field)
+ if ($field->widget->is_hidden)
+ $hidden[] = $name;
+ return $hidden;
}
- public function get_top_errors()
+ public function render_top_errors($raw=false)
{
- return (isset($this->errors['__all__'])) ? $this->errors['__all__'] : array();
+ $errors = IPF_Form::renderErrorsAsHTML($this->get_top_errors());
+ if ($raw)
+ return $errors;
+ else
+ return new IPF_Template_SafeString($errors, true);
}
-
- public function htmlOutput($normal_row, $error_row, $row_ender,
- $help_text_html, $errors_on_separate_row, $group_title=null,
- $extra_js=true)
+
+ public function get_top_errors()
{
- $top_errors = (isset($this->errors['__all__'])) ? $this->errors['__all__'] : array();
- array_walk($top_errors, 'IPF_Form_htmlspecialcharsArray');
- $output = array();
- $hidden_fields = array();
+ return \PFF\Arr::get($this->errors, '__all__', array());
+ }
+ public function renderLayout($layout, $raw=false)
+ {
foreach ($this->field_groups as $field_group) {
if (!$field_group['fields'])
throw new IPF_Exception('Empty field group.');
);
}
- if (count($groups)) {
- $render_group_title = $group_title ? true : false;
- } else {
+ if (!count($groups)) {
$groups = array(array('fields' => $this->fields));
- $render_group_title = false;
}
+ $output = $layout->startForm($this);
foreach ($groups as $group) {
- if ($render_group_title && isset($group['label']))
- $output[] = sprintf($group_title, $group['label']);
+ $groupLabel = \PFF\Arr::get($group, 'label', '');
+ $output .= $layout->startGroup($groupLabel);
foreach ($group['fields'] as $name=>$field) {
$bf = new IPF_Form_BoundField($this, $field, $name);
- $bf_errors = $bf->errors;
- array_walk($bf_errors, 'IPF_Form_htmlspecialcharsArray');
- if ($field->widget->is_hidden) {
- foreach ($bf_errors as $_e) {
- $top_errors[] = sprintf(__('(Hidden field %1$s) %2$s'),
- $name, $_e);
- }
- $hidden_fields[] = $bf; // Not rendered
- } else {
- if ($errors_on_separate_row and count($bf_errors)) {
- $output[] = sprintf($error_row, IPF_Form::renderErrorsAsHTML($bf_errors));
- }
+
+ if (!$field->widget->is_hidden) {
+
if (strlen($bf->label) > 0) {
$label = htmlspecialchars($bf->label, ENT_COMPAT, 'UTF-8');
if ($this->label_suffix) {
$label_attrs = array('class'=>'required');
else
$label_attrs = array();
- $label = $bf->labelTag($label,$label_attrs);
+ $label = $bf->labelTagRaw($label, $label_attrs);
} else {
$label = '';
}
- if ($bf->help_text) {
- // $bf->help_text can contains HTML and is not
- // escaped.
- $help_text = sprintf($help_text_html, $bf->help_text);
- } else {
- $help_text = '';
- }
- $errors = '';
- if (!$errors_on_separate_row and count($bf_errors)) {
- $errors = IPF_Form::renderErrorsAsHTML($bf_errors);
- }
- $output[] = sprintf($normal_row, $errors, $label,
- $bf->render_w(), $help_text);
+
+ $output .= $layout->field($bf, $label);
}
}
+ $output .= $layout->endGroup($groupLabel);
}
- if (count($top_errors)) {
- $errors = sprintf($error_row, IPF_Form::renderErrorsAsHTML($top_errors));
- array_unshift($output, $errors);
- }
- if (count($hidden_fields)) {
- $_tmp = '';
- foreach ($hidden_fields as $hd) {
- $_tmp .= $hd->render_w();
- }
- if (count($output)) {
- $last_row = array_pop($output);
- $last_row = substr($last_row, 0, -strlen($row_ender)).$_tmp
- .$row_ender;
- $output[] = $last_row;
- } else {
- $output[] = $_tmp;
- }
- }
+ $output .= $layout->endForm($this);
- if ($extra_js)
- $output = array_merge($output, $this->extra_js());
+ if (!$raw)
+ $output = new IPF_Template_SafeString($output, true);
- return new IPF_Template_SafeString($this->before_render . implode("\n", $output) . $this->after_render, true);
+ return $output;
}
public function extra_js()
return array_unique($extra_js);
}
- public function render_p()
+ public function render_p($raw=false)
{
- return $this->htmlOutput('<p>%1$s%2$s %3$s%4$s</p>', '%s', '</p>', ' %s', true);
+ return $form->renderLayout(new IPF_Form_ParagraphLayout, $raw);
}
- public function render_ul()
+ public function render_ul($raw=false)
{
- return $this->htmlOutput('<li>%1$s%2$s %3$s%4$s</li>', '<li>%s</li>', '</li>', ' %s', false);
+ return $form->renderLayout(new IPF_Form_ListLayout, $raw);
}
- public function render_table()
+ public function render_table($raw=false)
{
- return $this->htmlOutput(
- '<tr><th>%2$s</th><td>%1$s%3$s%4$s</td></tr>',
- '<tr><td colspan="2">%s</td></tr>',
- '</td></tr>',
- '<br /><span class="helptext">%s</span>',
- false);
+ return $form->renderLayout(new IPF_Form_TableLayout, $raw);
}
- public function render_admin()
+ public function render_admin($raw=false)
{
- return $this->htmlOutput(
- '<div class="form-row"><div>%2$s %1$s%3$s%4$s</div></div>',
- '<div>%s</div>',
- '</div>',
- '<p class="help">%s</p>',
- true,
- '<div class="form-group-title">%s</div>');
+ return $form->renderLayout(new IPF_Admin_Form_Layout, $raw);
}
function __get($prop)
public static function renderErrorsAsHTML($errors)
{
- if (count($errors)==0)
+ if (!count($errors))
return '';
- $tmp = array();
- foreach ($errors as $err) {
- $tmp[] = '<li>'.$err.'</li>';
- }
- return '<ul class="errorlist">'.implode("\n", $tmp).'</ul>';
+ $ul = Tag::ul(array('class' => 'errorlist'));
+ foreach ($errors as $err)
+ $ul->append(Tag::li(null, $err));
+ return $ul;
}
}
<?php
+use \PFF\HtmlBuilder\Tag as Tag;
+
class IPF_Form_BoundField
{
public $form = null;
return $widget->render($this->html_name, $this->value(), $attrs);
}
- public function labelTag($contents=null, $attrs=array())
+ public function labelTag($contents=null, $attrs=array(), $raw=false)
{
- $contents = ($contents) ? $contents : htmlspecialchars($this->label);
+ $label = Tag::label($attrs);
+
+ if ($contents)
+ $label->raw($contents);
+ else
+ $label->append($this->label);
+
$widget = $this->field->widget;
$id = (isset($widget->attrs['id'])) ? $widget->attrs['id'] : $this->autoId();
- $_tmp = array();
- $class_found = false;
- foreach ($attrs as $attr=>$val) {
- $_tmp[] = $attr.'="'.$val.'"';
- if ($attr=='class')
- $class_found = true;
- }
- if ( (!$class_found) && ($this->field->required==1))
- $_tmp[] = 'class="req"';
- if (count($_tmp)) {
- $attrs = ' '.implode(' ', $_tmp);
- } else {
- $attrs = '';
- }
- return new IPF_Template_SafeString(sprintf('<label for="%s"%s>%s</label>',
- $widget->idForLabel($id), $attrs, $contents), true);
+
+ $label->attr('for', $widget->idForLabel($id));
+
+ if ($this->field->required)
+ $label->addClass('req');
+
+ if ($raw)
+ return $label;
+ else
+ return new IPF_Template_SafeString($label, true);
}
public function autoId()
return '';
}
- public function fieldErrors()
+ public function fieldErrors($raw=false)
{
- return new IPF_Template_SafeString(IPF_Form::renderErrorsAsHTML($this->errors), true);
+ $errors = IPF_Form::renderErrorsAsHTML($this->errors);
+ if ($raw)
+ return $errors;
+ else
+ return new IPF_Template_SafeString($errors, true);
}
public function __get($prop)
--- /dev/null
+<?php
+
+/* informal interface IPF_Form_Layout
+{
+ public function startForm($form);
+ public function startGroup($label);
+ public function field($boundField, $label);
+ public function endGroup($label);
+ public function endForm($form);
+}*/
+
+
+abstract class IPF_Form_LayoutAdapter /*implements informal interface IPF_Form_Layout*/
+{
+ public function startForm($form) { return ''; }
+ public function startGroup($label) { return ''; }
+ public abstract function field($boundField, $label);
+ public function endGroup($label) { return ''; }
+ public function endForm($form) { return ''; }
+
+ protected function commonErrors($form)
+ {
+ $commonErrors = $form->get_top_errors();
+ foreach ($form->hiddenFields() as $field_name)
+ foreach (\PFF\Arr::get($form->errors, $field_name, array()) as $error)
+ $commonErrors[] = sprintf(__('(Hidden field %1$s) %2$s'), $field_name, $error);
+ return $commonErrors;
+ }
+
+ protected function hiddenWidgets($form)
+ {
+ $hiddenWidgets = '';
+ foreach ($form->hiddenFields() as $field_name)
+ $hiddenWidgets .= $form->field($field_name)->render_w();
+ return $hiddenWidgets;
+ }
+
+ private $deferred = '';
+
+ protected function defer($code)
+ {
+ $this->deferred .= $code;
+ }
+
+ protected function takeDeferred()
+ {
+ $deferred = $this->deferred;
+ $this->deferred = '';
+ return $deferred;
+ }
+
+ protected function errorList($errors)
+ {
+ if (!count($errors))
+ return '';
+
+ $ul = Tag::ul(array('class' => 'errorlist'));
+ foreach ($errors as $err)
+ $ul->append(Tag::li(null, $err));
+ return $ul;
+ }
+}
+
+
+class IPF_Form_ParagraphLayout extends IPF_Form_LayoutAdapter
+{
+ public function startForm($form)
+ {
+ $o = $this->hiddenWidgets($form) . $form->extra_js();
+
+ $errors = $this->commonErrors($form);
+ if (count($errors))
+ $o .= $this->errorList($errors);
+
+ return $o;
+ }
+
+ public function field($boundField, $label)
+ {
+ return
+ $this->errorList($boundField->errors) .
+ Tag::p()
+ ->raw($label)
+ ->raw(' ')
+ ->raw($boundField->render_w())
+ ->raw(' ')
+ ->raw($boundField->help_text);
+ }
+}
+
+
+class IPF_Form_ListLayout extends IPF_Form_LayoutAdapter
+{
+ public function startForm($form)
+ {
+ $this->defer($this->hiddenWidgets($form) . $form->extra_js());
+
+ $errors = $this->commonErrors($form);
+ if (count($errors))
+ return Tag::li()
+ ->raw($this->errorList($errors))
+ ->raw($this->takeDeferred());
+ else
+ return '';
+ }
+
+ public function field($boundField, $label)
+ {
+ if ($boundField->help_text)
+ $help_text = '<br /><span class="helptext">'.$boundField->help_text.'</span>';
+ else
+ $help_text = '';
+
+ return Tag::li()
+ ->raw($this->takeDeferred())
+ ->raw($this->errorList($boundField->errors))
+ ->raw($label)
+ ->raw(' ')
+ ->raw($boundField->render_w())
+ ->raw($help_text);
+ }
+
+ public function endForm($form)
+ {
+ $deferred = $this->deferred();
+ if ($deferred)
+ return Tag::li()->raw($deferred);
+ else
+ return '';
+ }
+}
+
+
+class IPF_Form_TableLayout extends IPF_Form_LayoutAdapter
+{
+ public function startForm($form)
+ {
+ $this->defer($this->hiddenWidgets($form) . $form->extra_js());
+
+ $errors = $this->commonErrors($form);
+ if (count($errors))
+ return Tag::tr(null,
+ Tag::td()->attr('colspan', 2)
+ ->raw($this->errorList($errors))
+ ->raw($this->deferred()));
+ else
+ return '';
+ }
+
+ public function field($boundField, $label)
+ {
+ if ($boundField->help_text)
+ $help_text = '<br /><span class="helptext">'.$boundField->help_text.'</span>';
+ else
+ $help_text = '';
+
+ return Tag::tr(null,
+ Tag::th()
+ ->raw($label),
+ Tag::td()
+ ->raw($this->takeDeferred())
+ ->raw($this->errorList($boundField->errors))
+ ->raw($boundField->render_w())
+ ->raw($help_text));
+ }
+
+ public function endForm($form)
+ {
+ $deferred = $this->takeDeferred();
+ if ($deferred)
+ return Tag::tr(null,
+ Tag::td()
+ ->raw($deferred));
+ else
+ return '';
+ }
+}
+