anewt-developers team mailing list archive
-
anewt-developers team
-
Mailing list archive
-
Message #00236
[Branch ~sander-sinaasappel/anewt/anewt.new.cxs] Rev 1491: [form] Merged subform support from a private project.
------------------------------------------------------------
revno: 1491
committer: Sander van Schouwenburg <sander@xxxxxxxxxxxxx>
branch nick: anewt.new.cxs
timestamp: Thu 2010-02-25 20:43:58 +0100
message:
[form] Merged subform support from a private project.
See also bug #527946
added:
form/controls/form.lib.php
modified:
form/controls/base.lib.php
form/controls/button.lib.php
form/controls/choice.lib.php
form/controls/main.lib.php
form/controls/text.lib.php
form/form.lib.php
form/form.test.php
form/renderer/base.lib.php
form/renderer/default.lib.php
--
lp:~sander-sinaasappel/anewt/anewt.new.cxs
https://code.launchpad.net/~sander-sinaasappel/anewt/anewt.new.cxs
Your team Anewt developers is subscribed to branch lp:~sander-sinaasappel/anewt/anewt.new.cxs.
To unsubscribe from this branch go to https://code.launchpad.net/~sander-sinaasappel/anewt/anewt.new.cxs/+edit-subscription.
=== modified file 'form/controls/base.lib.php'
--- form/controls/base.lib.php 2009-07-20 15:48:26 +0000
+++ form/controls/base.lib.php 2010-02-25 19:43:58 +0000
@@ -159,12 +159,43 @@
$id = $this->_get('id');
if (is_null($id))
- $id = $this->get('name');
+ {
+ $name_parts = $this->get('name-parts');
+ $id = join('-', $name_parts);
+ }
return $id;
}
/**
+ * Returns a list of name parts. Mostly, this is an array with all
+ * the prefixes from the form, followed by the name of this contro.
+ */
+ function get_name_parts() {
+ if (isset($this->_form)) {
+ $parts = $this->_form->get('prefix');
+ } else {
+ $parts = array();
+ }
+ $parts[] = $this->get('name');
+
+ return $parts;
+ }
+
+ /**
+ * Returns the rendered name as html. This is the name with an optional prefix.
+ */
+ function get_rendered_name() {
+ $parts = $this->get('name-parts');
+
+ $name = array_shift($parts);
+ foreach ($parts as $part)
+ $name .= sprintf('[%s]', $part);
+
+ return $name;
+ }
+
+ /**
* \private
*
* Make the control reference its containing form.
=== modified file 'form/controls/button.lib.php'
--- form/controls/button.lib.php 2009-07-20 15:50:43 +0000
+++ form/controls/button.lib.php 2010-02-25 19:43:58 +0000
@@ -70,7 +70,7 @@
);
if ($this->_get('render-name'))
- $attr['name'] = $this->get('name');
+ $attr['name'] = $this->get('rendered-name');
$label = $this->get('label');
if (!is_null($label))
=== modified file 'form/controls/choice.lib.php'
--- form/controls/choice.lib.php 2010-01-04 13:03:15 +0000
+++ form/controls/choice.lib.php 2010-02-25 19:43:58 +0000
@@ -58,7 +58,7 @@
{
$id = $this->get('id');
$attr = array(
- 'name' => $this->get('name'),
+ 'name' => $this->get('rendered-name'),
'id' => $id,
'type' => 'checkbox',
);
@@ -515,7 +515,7 @@
function build_widget()
{
- $name = $this->get('name');
+ $name = $this->get('rendered-name');
$id = $this->get('id');
$multiple = $this->_get('multiple');
@@ -764,7 +764,7 @@
$input_attr = array(
'type' => 'checkbox',
- 'name' => sprintf('%s[]', $this->_choice_control->_get('name')),
+ 'name' => sprintf('%s[]', $this->_choice_control->get('rendered-name')),
'value' => $value,
);
@@ -798,7 +798,7 @@
$input_attr = array(
'type' => 'radio',
- 'name' => $this->_choice_control->_get('name'),
+ 'name' => $this->_choice_control->get('rendered-name'),
'value' => $value,
);
=== added file 'form/controls/form.lib.php'
--- form/controls/form.lib.php 1970-01-01 00:00:00 +0000
+++ form/controls/form.lib.php 2010-02-25 19:43:58 +0000
@@ -0,0 +1,104 @@
+<?php
+
+/*
+ * Anewt, Almost No Effort Web Toolkit, form module
+ *
+ * This code is copyrighted and distributed under the terms of the GNU LGPL.
+ * See the README file for more information.
+ */
+
+
+/**
+ * Controls containing a subform.
+ *
+ * This control can render a subform. The #build_widget() will render the entire
+ * form without the <form> tags. Its controls will render with prefixed names
+ * such that name clashes between controls of multiple subforms are avoided.
+ * Of course, the name of this control must be unique in the main form.
+ *
+ * To do normal processing within this form, it is necessary that #process()
+ * be called in the \c process() of the main form.
+ */
+class AnewtFormControlSubform extends AnewtFormControl
+{
+ protected $_subform; /**< The subform */
+
+ /**
+ * Create a new subform control
+ *
+ * \param $name
+ * The name of this control.
+ * \param $form
+ * The subform
+ * \param $renderer
+ * A renderer for the form.
+ */
+ function __construct($name, $subform, $renderer = null)
+ {
+ parent::__construct($name);
+ $this->seed(array(
+ 'renderer' => $renderer,
+ 'class' => null,
+ ));
+ assert('$subform instanceof AnewtForm');
+ $this->_subform = $subform;
+ }
+
+ function set_prefix()
+ {
+ $prefix = $this->get('name-parts');
+ $this->_subform->set('prefix', $prefix);
+ }
+
+ function build_widget()
+ {
+ $renderer = $this->get('renderer');
+
+ $this->set_prefix();
+
+ if (is_null($renderer)) {
+ $renderer = new AnewtFormRendererDefault();
+ $renderer->set_form($this->_subform);
+ $this->set('renderer', $renderer);
+ }
+
+ $attr = array(
+ 'class' => 'form-subform',
+ 'id' => $this->get('id'),
+ );
+
+ $div = new AnewtXHTMLDiv(null, $attr);
+
+ $class = $this->_get('class');
+ if (!is_null($class))
+ $div->add_class($class);
+
+ $div->append_child($renderer->render_hidden_controls());
+ $div->append_child($renderer->render_base());
+
+ return $div;
+ }
+
+ function process() {
+ return $this->_subform->process();
+ }
+
+ function is_valid()
+ {
+ return $this->_subform->is_valid();
+ }
+
+ function get_value() {
+ return $this->_subform->get_control_values();
+ }
+
+ function set_value($value) {
+ $this->_subform->fill($value);
+ }
+
+ function get_subform() {
+ return $this->_subform;
+ }
+}
+
+?>
=== modified file 'form/controls/main.lib.php'
--- form/controls/main.lib.php 2008-09-11 16:55:47 +0000
+++ form/controls/main.lib.php 2010-02-25 19:43:58 +0000
@@ -13,5 +13,6 @@
anewt_include('form/controls/button');
anewt_include('form/controls/choice');
anewt_include('form/controls/fileupload');
+anewt_include('form/controls/form');
?>
=== modified file 'form/controls/text.lib.php'
--- form/controls/text.lib.php 2009-07-20 15:48:47 +0000
+++ form/controls/text.lib.php 2010-02-25 19:43:58 +0000
@@ -67,7 +67,7 @@
/* XML tag attributes used both for single line and multiline */
$attr = array(
- 'name' => $this->get('name'),
+ 'name' => $this->get('rendered-name'),
'id' => $this->get('id'),
);
if ($this->get('extra_attributes')) {
@@ -350,6 +350,7 @@
$name = sprintf("%s[%s]", $this->get('name'), $key);
$id = sprintf("%s-%s", $this->get('id'), $key);
$c = new AnewtFormControlHidden($name);
+ $c->_set_form($this->_form);
$c->set('value', $item);
$c->set('id', $id);
@@ -358,7 +359,7 @@
return ax_fragment($widget_list);
} else {
$attr = array(
- 'name' => $this->get('name'),
+ 'name' => $this->get('rendered-name'),
'id' => $this->get('id'),
'value' => (string) $this->get('value'),
'type' => 'hidden',
=== modified file 'form/form.lib.php'
--- form/form.lib.php 2009-07-20 15:55:38 +0000
+++ form/form.lib.php 2010-02-25 19:43:58 +0000
@@ -74,6 +74,8 @@
'method' => ANEWT_FORM_METHOD_POST,
'action' => Request::relative_url(),
+ 'prefix' => array(),
+
'description' => null,
'error' => null,
));
@@ -237,12 +239,18 @@
{
$form_method = $this->_get('method');
if (Request::is_get() && $form_method == ANEWT_FORM_METHOD_GET) {
- return $this->fill($_GET);
+ $values = $_GET;
}
elseif (Request::is_post() && $form_method == ANEWT_FORM_METHOD_POST) {
- return $this->fill($_POST);
- }
- return false;
+ $values = $_POST;
+ }
+ else {
+ return false;
+ }
+ foreach ($this->get('prefix') as $part) {
+ $values = $values[$part];
+ }
+ return $this->fill($values);
}
/**
@@ -481,6 +489,7 @@
$control_name = $fieldset->_children[$key]->get('name');
assert('!array_key_exists($control_name, $this->_controls_by_name); // control names must be unique');
$this->_controls_by_name[$control_name] = $fieldset->_children[$key];
+ $this->_controls_by_name[$control_name]->_set_form($this);
}
}
}
@@ -551,6 +560,20 @@
}
/**
+ * Set's the prefix or list of prefixes for this control.
+ */
+ function set_prefix($prefix) {
+ if (is_string($prefix))
+ $prefix = array($prefix);
+ elseif (is_null($prefix))
+ $prefix = array();
+
+ assert('is_array($prefix)');
+
+ $this->_set('prefix', $prefix);
+ }
+
+ /**
* \protected
*
* Return all children on this form as a list.
=== modified file 'form/form.test.php'
--- form/form.test.php 2009-04-07 08:05:57 +0000
+++ form/form.test.php 2010-02-25 19:43:58 +0000
@@ -416,6 +416,12 @@
$this->add_hidden_control('hidden2', 'another && ÅèkÅ1t');
+ /* Subform */
+
+ $subform = new TestSubForm();
+ $subform_control = new AnewtFormControlSubform('mysubform', $subform);
+ $this->add_control($subform_control);
+
/* Buttons */
$button_fieldset = new AnewtFormFieldset('buttons');
@@ -448,6 +454,34 @@
}
}
+class TestSubForm extends AnewtForm {
+ function __construct() {
+ parent::__construct();
+
+ $number = new AnewtFormControlText('number');
+ $number->set('label', 'A number');
+ $number->set('value', '45');
+ $number->add_validator(new AnewtValidatorInteger(), 'This must be a number');
+ $this->add_control($number);
+
+ $subform = new TestSubSubForm();
+ $subform_control = new AnewtFormControlSubform('mysubform', $subform);
+ $this->add_control($subform_control);
+ }
+}
+
+class TestSubSubForm extends AnewtForm {
+ function __construct() {
+ parent::__construct();
+
+ $subnumber = new AnewtFormControlText('subnumber');
+ $subnumber->set('label', 'A subnumber');
+ $subnumber->set('value', '13');
+ $subnumber->add_validator(new AnewtValidatorInteger(), 'This must be a number');
+ $this->add_control($subnumber);
+ }
+}
+
/* Show a page and test the form */
=== modified file 'form/renderer/base.lib.php'
--- form/renderer/base.lib.php 2009-05-05 17:06:25 +0000
+++ form/renderer/base.lib.php 2010-02-25 19:43:58 +0000
@@ -91,17 +91,34 @@
$form = new AnewtXHTMLForm(null, $attributes);
+ $form->append_child($this->render_hidden_controls());
+
+ return $form;
+ }
+
+ /**
+ * Renders the hidden controls.
+ */
+ function render_hidden_controls() {
+
+ $fragment = new AnewtXHTMLFragment();
+
/* The HTML DTD does not allow <input> elements as direct childs of
* a <form> element. Use a <fieldset> that is completely hidden from
* view instead. */
- $hidden_controls_fieldset = new AnewtXHTMLFieldset();
- $hidden_controls_fieldset->set_attribute('style', 'display: none;');
- foreach ($this->_form->_hidden_controls() as $hidden_control)
- $hidden_controls_fieldset->append_child($hidden_control->build_widget());
-
- $form->append_child($hidden_controls_fieldset);
-
- return $form;
+ $hidden_controls = $this->_form->_hidden_controls();
+ if ($hidden_controls)
+ {
+ $hidden_controls_fieldset = new AnewtXHTMLFieldset();
+ $hidden_controls_fieldset->set_attribute('style', 'display: none;');
+
+ foreach ($hidden_controls as $hidden_control)
+ $hidden_controls_fieldset->append_child($hidden_control->build_widget());
+
+ $fragment->append_child($hidden_controls_fieldset);
+ }
+
+ return $fragment;
}
/**
=== modified file 'form/renderer/default.lib.php'
--- form/renderer/default.lib.php 2009-07-20 15:56:32 +0000
+++ form/renderer/default.lib.php 2010-02-25 19:43:58 +0000
@@ -49,8 +49,20 @@
{
$f = $this->build_form_element();
- $f->append_child($this->_build_error_node($this->_form));
- $f->append_child($this->_build_description_node($this->_form));
+ $f->append_child($this->render_base());
+
+ return $f;
+ }
+
+ /**
+ * Render the form except for the <form> tags.
+ */
+ function render_base()
+ {
+ $r = array();
+
+ $r[] = $this->_build_error_node($this->_form);
+ $r[] = $this->_build_description_node($this->_form);
/* Add all form children */
@@ -61,10 +73,9 @@
if ($children[$key] instanceof AnewtFormControlHidden)
continue;
- $f->append_child($this->_build_child_node($children[$key]));
+ $r[] = $this->_build_child_node($children[$key]);
}
-
- return $f;
+ return ax_fragment($r);
}
/**