[cvs] [Wiki] changed: Project/HordeForm

Chuck Hagenbuch chuck at horde.org
Tue Jul 8 17:57:22 UTC 2008


chuck  Tue, 08 Jul 2008 13:57:22 -0400

Modified page: http://wiki.horde.org/Project/HordeForm
New Revision:  17.5
Change log:  add my horde_form notes

@@ -1,4 +1,6 @@
+[[toc]]
+
  + Horde_Form rewrite/Horde_Field:: Proposal

  This page is a proposal for the implementation of new package to  
replace Horde_Form_Type:: and Horde_Form_Variable::.

@@ -90,4 +92,846 @@
  In Horde, we can make sure the storage driver returns the internal  
form, so we seal off the database representation into the  
database-specific driver, which is really nice.  We currently do have  
a problem with the other types of values, though.  We should probably  
always use PEAR Date:: representations because we certainly don't want  
different fields for UNIX timestamp and more useful date formats.

  -- JasonFelice

+
+++ Unsorted Notes
+
+http://www.lukew.com/resources/articles/PSactions.asp
+http://jeffhowden.com/code/css/forms/
+http://www.frevvo.com/frevvo/web/home
+http://www.smashingmagazine.com/2006/11/11/css-based-forms-modern-solutions/
+http://www.formassembly.com/form-garden.php
+http://www.jamiehoover.com/?channel=journal&item=11
+http://code.google.com/p/repetitionmodel/
+http://www.nyphp.org/phundamentals/spoofed_submission.php
+http://svn.rubyonrails.org/rails/trunk/actionpack/lib/action_view/helpers/form_helper.rb
+http://ajaxian.com/archives/ajform-and-rejax-reloaded
+
+Horde_Form - change tabs and tab javascript to use HTML structure from YUI:
+http://developer.yahoo.com/yui/tabview/
+
+Also use this for Prefs?
+
+Also consider Ext tabs:
+http://www.yui-ext.com/deploy/ext-1.0-alpha3/docs/
+
+Additional tabs notes:
+http://developer.yahoo.com/ypatterns/pattern.php?pattern=moduletabs
+
+avoid serialized form data, send a checksum for it (checksum in  
session of course)
+
+Horde_View and Horde_Form and sub-views
+
+don't need to create new view objects!
+just call $this->render() with the sub page name!
+view variables will be maintained
+
+
+
+I just discovered a hole in a white list validation technique I bored from a
+PHP security book ‹ no, not Chris¹ book.
+
+Beware in_array($_POST/GET[Œinput¹], $whitelist)
+
+Type matters. All input is string type and PHP will try to force type
+matching.
+
+So the input string Œsecurityhole¹ will match the int number 0.
+
+
+
+horde_form overloading:
+
+$form->Enum($name, $desc, $note, ... (any other params are type  
config options - use func_get_args/func_num_args if needed - not  
needed, have __call $args
+
+$form->optionalEnum - non required
+$form->requiredEnum - required
+which is default?
+
+expected variables - track in the form, not the Variables object
+need a simplified Variables object for incubator Horde_Form
+ - remove foo[bar] syntax in favor of $vars->foo->bar ?
+ - remove expected variables, getExists, etc.
+ - could just be an ArrayObject?
+
+Look at what should be in Type and what in Variable
+simplify validate() methods (rename from isValid?)
+
+
+
+http://blog.astrumfutura.com/archives/281-Complex-Web-Pages-with-the-Zend-Framework.html
+
+
+Horde_Form rewrite notes:
+
+multienum (and checkboxes if any?) get consolidated to Set
+
+enum, radio buttons -> enum
+
+
+
+Horde_Form
+1 class/file for autoload
+__autoload file (all types?)
+Horde_Form_Variable_View ?
+rename Variable to Field?
+keep type separate but make basic api as clean and small as possible
+Horde_Form_Type -> standard constructor for all types instead of factory
+
+no singletons!
+
+horde_form_type_* -> replace about() methods with doc introspection
+http://us2.php.net/reflection
+
+form descriptions - xml, db, php (the list of addVariable() calls)
+
+
+TODO
+
+Actions for buttons (not currently possible)
+
+I know this sounds really dumb but I cant seem to find a solution for
+it. How do I attach an action (Horde_Form_Action) to a submit button
+in a form that is generated via the Horde_Form class? My objective is
+to call a custom javascript function when the user clicks the submit
+button on the form.
+
+
+
+
+
+
+
+i am currently in the need of a form-library to process form-data  
without the ever going
+hassle of boring input sanitization and validation. i read thru the  
Zend-Form proposal
+and it seems that its going to be a *big* form-creation quick-form pendant.
+
+i coded a component to do filtering and validation only and  
transporting values and
+errors over session-namespaces to redirect between processing<->view.
+
+the usage is like this:
+
+// FORM-PROCESSING
+$F = new Form('edit');
+
+// common form-data
+$F->register('type')->isTableKey('mediatype', 'mediatype_id');
+$F->register('collection')->isBool();
+$F->register('parts')->isOptional()->isArray()->isTableKey('media',  
'media_id');
+$F->register('lang')->isTableKey('locale', 'locale_id');
+$F->register('country')->isTableKey('locale', 'locale_id');
+$F->register('title')->isString();
+$F->register('origtitle')->isString();
+$F->register('comment')->isString();
+$F->register('rating')->isInt(0, 5);
+
+// optional checklists (kind of <select multiple>)
+$F->register('genres')->isOptional()->isArray()->isTableKey('genre',  
'genre_id');
+                 
$F->register('genres_new')->isOptional()->isArray()->isString();
+$F->register('persons')->isOptional()
+                        ->isArray()
+                        ->isTableKey('person', 'person_id')
+                        ->requires('person_roles');
+$F->register('person_roles')->isOptional()
+                                ->isArray()
+                                ->isString();
+
+$F->register('persons_new')->isOptional()
+                                ->isArray()
+                                ->isString()
+                                ->requires('person_roles_new');
+
+$F->register('person_roles_new')->isOptional()
+                                ->isArray()
+                                ->isString();
+[...]
+
+// working with Zend-Validators, -Filters and Function-Delegates
+
+function fooDelegate($elementName, $elementValue, $formData) {
+  return true;
+}
+
+$F->register('foo')->validate(new Zend_Validate_xxx())
+                   ->filter(new Zend_Filter_yyy())
+                   ->delegate('fooDelegate');
+
+
+try {
+  $this->db->beginTransaction();
+  $F->validate($_POST);
+
+  $title = $F->value('title');
+  ...
+
+  if (($persons= $F->value('persons')) {
+    foreach ($persons as $personID) {
+      ...
+    }
+  }
+
+  //or
+  $persons = $F->value('persons', array());
+  foreach ($persons as $personID) {
+    ...
+  }
+
+} catch (FormException $e) {
+    $this->db->rollBack();
+    print_r($F->getErrors());
+    $this->redirect('back to edit-form-view');
+}
+
+
+// VIEW
+$F = new Form('edit');
+if ($F->hasErrors())
+  print_r($F->getErrors());
+
+if (!($title = $F->value('title')))
+  $title = '<populate from db>';
+
+<input type=text value=$title />
+
+
+
+
+API discussion:
+
+
+
+We are in the middle of a discussion Alexey and I about QuickForm2  
API for elements
+creation and I would like your opinion as well.
+At this point, nothing is immutable since we aren't even talking  
about alpha stage, so
+your preferences as users and developers is interesting.
+
+To summarize, Alexey would be in favor of this:
+
+$form->addElement('button', 'aButton', 'Click me please');
+$form->addElement('select', 'aSelect', array('1' => 'option 1', '2'  
=> 'option 2'));
+
+While I would be in favor of this:
+
+$form->addElement('button', 'aButton')->setContent('Click me please');
+$form->addElement('select', 'aSelect')->setOptions(array('1' =>  
'option 1', '2' =>
+'option 2'));
+
+This is an example for adding a button to a form. The API can get  
more complex for Date
+elements and other javascript aided elements.
+
+My opinion is that we shouldn't mix configuration parameters for  
elements with other kind
+of data they might need.
+
+The other point we are discussing is about the extra parameter in  
element creation. I
+suggest we always use an array, even when there is only one extra  
parameter. Alexey
+suggests that we use a scalar if there is only one extra  parameter.  
For example, for a
+given "Year" element which would only accept one configuration  
parameter 'startYear',
+Alexey would use:
+
+$form->addElement('year', 'aYear', '2007');
+
+While I would use:
+
+$form->addElement('year', 'aYear', array('startYear' => '2007'));
+
+So my way is more verbose and less writable, but is also more  
readable and extensible.
+
+Given these examples, are there any opinions or preferences in favor  
of one or the other
+proposed API ?
+Thanks in advance,
+
+
+
+
+
+[Show Quoted Text - 12 lines]
+We are in the middle of a discussion Alexey and I about QuickForm2
+API for elements creation and I would like your opinion as well.
+At this point, nothing is immutable since we aren't even talking
+about alpha stage, so your preferences as users and developers is
+interesting.
+
+To summarize, Alexey would be in favor of this:
+
+$form->addElement('button', 'aButton', 'Click me please');
+$form->addElement('select', 'aSelect', array('1' => 'option 1', '2'
+=> 'option 2'));
+
+This is the old (and IMO sometimes confusing) style which is (at least
+in the current QF) not consistent through the various elements.
+While I would be in favor of this:
+
+$form->addElement('button', 'aButton')->setContent('Click me please');
+$form->addElement('select', 'aSelect')->setOptions(array('1' =>
+'option 1', '2' => 'option 2'));
+
+This style is more "OO-ish" (*g*) and should also be more consistent in
+usage.
+
++1, therefore
+
+[...]
+
+[Show Quoted Text - 13 lines]
+The other point we are discussing is about the extra parameter in
+element creation. I suggest we always use an array, even when there
+is only one extra parameter. Alexey suggests that we use a scalar if
+there is only one extra  parameter. For example, for a given "Year"
+element which would only accept one configuration parameter
+'startYear', Alexey would use:
+
+$form->addElement('year', 'aYear', '2007');
+
+While I would use:
+
+$form->addElement('year', 'aYear', array('startYear' => '2007'));
+
++1 for this last style because it avoids confusion, too, and especially
+also because sometimes later such elements might get a second, third,
+... option.
+
+
+
+
+
+What's really being discussed is the following, will we make the  
"additional data"
+parameter that has different semantics from element to element always  
an array, so the
+first pair of calls above turns into
+
+$form->addElement('button', 'aButton', array('content' => 'Click me  
please'));
+$form->addElement('select', 'aSelect', array('options' => array('1'  
=> 'option 1', '2' =>
+'option 2')));
+
+even though the elements in question will never need any additional  
data other than
+'content' and 'options'.
+
+
+
+
+
+My vote would be for always an array --- even in cases where an
+element will only need one piece of scalar data.
+
+As many have already pointed out, changing from scalars to array based
+on the individual element leads to confusion about which elements
+require which parameter format --- I would even be against the
+flexibility of allowing both ways because I think it leads to more
+complicated documentation and more room for coding errors.
+
+
+
+
+
+
+I've honestly found the addElement() API to be difficult to work with in
+the past, so simplifying it would be a welcome change.
+
+However, I don't think "addElement" needs to exist in Quickform2.  Have
+you considered an API similar to the following?
+
+<?php
+
+$form = new HTML_Quickform2;
+$form['action'] = '/path/to/action.php';
+$form['method'] = 'post';
+// or
+$form['attrs'] = array('action' => '/path/to/action.php', 'method' =>
+'post');
+
+$g = $form->group['mygroup'];
+$g->text = array('name' => 'aText', 'size' => 50, 'default' => 'whatever');
+$g->select = array('name' => 'aSelect', 'options' => array(...));
+
+// or
+$g->text(array('name' => 'aText', 'size' => 50))
+          ->validate['regex'] =  '/\w+/';
+$g->select(array('name' => 'aSelect', 'options' => array())
+$select = $g->select['aSelect']; // or $form->select['aSelect'];
+$select->options['another'] = 1;
+$select->validate['custom'] = 'is_numeric';
+?>
+
+Compare this to:
+
+<?php
+
+$form = new HTML_Quickform2('/path/to/action.php', 'method' => 'post');
+$form->addGroup('mygroup');
+$form->addElement('text', 'aText', array('size' => 50, 'default' =>
+'whatever', 'group' => 'mygroup')
+    ->validate('regex', '/\w+/');
+$sel = $form->addElement('select', 'aSelect', array(...));
+$sel->addOption('another', 1);
+$sel->validate('custom', 'is_numeric');
+?>
+
+In the second example, my eyes are drawn to a bunch of "add*" and it
+appears that the important information ('text', 'select') is secondary.
+ It takes me a while to figure out what is actually being done.  The
+first example has no superfluous information, but simply sets up the
+form in a straightforward, no-nonsense manner.
+
+In other words, I've always dreamed of having a simplexml-like API for
+accessing/creating forms.  I hate translating what I want to do into
+method APIs.  Think of this as bringing the REST model to forms
+creation, whereas everything has been XML-RPC based up to this point :).
+
+Another feature request I've had that may be possible is to integrate
+some kind of forms creation cache, so that the form need only be created
+programmatically once, and then it can on subsequent requests be quickly
+recreated from a disk or database cache, skipping all the expensive
+method calls, but this is a separate question than the one you asked,
+let me know if you'd like a feature request opened on this.
+
+If you do decide to go with the other API format, I am in favor of more
+explicit options (associative array/fluent).  I hate relying on Zend IDE
+to do auto-completion, it makes debugging far more difficult to do with
+just a simple text editor and eyeballs.
+
+
+
+
+
+
+As an addendum to my last message, I just thought of an even clearer
+interface:
+
+<?php
+
+$form = new HTML_Quickform2;
+
+$g = $form->group['mygroup'];
+
+$g->text['aText'] = array('size' => 50);
+$g->select['aSelect'] = array('size' => 5', 'options' => array(...));
+
+?>
+
+By using ArrayAccess offsetSet() you can put the element name in
+brackets.  This way, the same procedure (array access) is used to both
+set and to retrieve elements.  This could also be used to modify values
+later if necessary, for the same element, something that I've found
+exceedingly difficult to do in the current QF.  Consider the following:
+
+<?php
+
+$form = new HTML_Quickform2;
+
+$form->text['mytext'] = array('default' => 'whatever');
+unset($form->text['mytext']);
+
+?>
+
+Simple and easy.
+
+
+
+
+
+Le 16 avr. 07 ? 18:31, Gregory Beaver a Ècrit :
+
+> $g->text(array('name' => 'aText', 'size' => 50))
+>           ->validate['regex'] =  '/\w+/';
+> $g->select(array('name' => 'aSelect', 'options' => array())
+> $select = $g->select['aSelect']; // or $form->select['aSelect'];
+> $select->options['another'] = 1;
+> $select->validate['custom'] = 'is_numeric';
+
+I like this as well. We have designed what I would call a low-level
+API for QuickForm. Built on top of that, it will be easier to add
+syntactic sugar like this at a later time.
+It's a bit like what jQuery and Prototype did to javascript DOM. PHP5
+allows this, we should indeed use it to our advantage IMO (I need to
+convince Alexey though :) ).
+
+> Another feature request I've had that may be possible is to integrate
+> some kind of forms creation cache, so that the form need only be
+> created
+> programmatically once, and then it can on subsequent requests be
+> quickly
+> recreated from a disk or database cache, skipping all the expensive
+> method calls, but this is a separate question than the one you asked,
+> let me know if you'd like a feature request opened on this.
+
+At the moment, I have no idea how to do that, any ideas would be
+welcome.
+The good news is that QuickForm2 should be faster than current
+QuickForm :)
+
+
+
+Another feature request I've had that may be possible is to integrate
+some kind of forms creation cache, so that the form need only be created
+programmatically once, and then it can on subsequent requests be quickly
+recreated from a disk or database cache, skipping all the expensive
+method calls, but this is a separate question than the one you asked,
+let me know if you'd like a feature request opened on this.
+
+At the moment, I have no idea how to do that, any ideas would be welcome.
+The good news is that QuickForm2 should be faster than current QuickForm :)
+
+Hi Bertrand,
+
+I would store element validation information in a simple array, and then
+use the renderer to render a PHP-based template (a la Savant) that will
+allow setting default values, so that the display process is basically:
+
+<?php
+$form->prepareCache();
+include $form->getCacheFile();
+?>
+
+Validation would work as it currently does.  You'd end up with something
+like:
+
+<?php
+
+$form = new HTML_Quickform2;
+$form['name'] = 'whatever';
+if ($form->submitted && $form->valid) {
+}
+if ($form->cached) {
+    $form->displayCache();
+} else {
+   // set up the form
+}
+?>
+
+Things like validation errors can be handled with placeholders as well
+(an if() in the template that skips the error HTML).
+
+
+
+To summarize, Alexey would be in favor of this:
+
+$form->addElement('button', 'aButton', 'Click me please');
+$form->addElement('select', 'aSelect', array('1' => 'option 1', '2'
+=> 'option 2'));
+Well, this has worked in the past and isn't too hard to grasp if the
+documentation makes it clear how this works (the current docs are a
+bit confusing in this regard). Having the additional parameters be the
+constructor args for the element is a fine option. However, it's
+always confusing to have lots of parameters to a method and I know I
+never remember which is which.
+$form->addElement('year', 'aYear', '2007');
+
+While I would use:
+
+$form->addElement('year', 'aYear', array('startYear' => '2007'));
+
+So my way is more verbose and less writable, but is also more
+readable and extensible.
+Extensability is a good thing. Readability is a good thing. I'd vote
+for an assoc array over variable numbers of arguments.
+Well, people aren't yet familiar with the new QF2 API and Bertrand  
didn't bother to give
+the full picture, so here goes:
+
+We no longer have variable number of parameters to elements'  
constructors, since neither
+Bertrand nor myself were able to remember all the parameter lists,  
and we actually
+*wrote* the abomination. Every constructor is now defined as:
+public function __construct($name, $data, $label, $attributes) { ... }
+
+Now, this what this $data thing means changes from element to element  
because the
+elements have different needs. What's *really* being discussed here  
is the fact that
+Bertrand wants to make $data *always* an associative array, thus
+
+$form->addElement('button', 'aButton', array('content' => 'Click me  
please'));
+$form->addElement('select', 'aSelect', array('options' => array('1'  
=> 'option 1', '2' =>
+'option 2')));
+
+while I suggest deciding on it on a per-element basis, thus
+$form->addElement('button', 'aButton', 'Click me please');
+$form->addElement('select', 'aSelect', array('1' => 'option 1', '2'  
=> 'option 2'));
+
+but most certainly
+$form->addElement('year', 'aYear', array('startYear' => '2007'));
+
+since that hypothetical 'year' element *may* earn additional  
parameters in the future
+which is highly unlikely in case of Buttons and Selects.
+
+
+
+
+I've honestly found the addElement() API to be difficult to work with in
+the past, so simplifying it would be a welcome change.
+
+However, I don't think "addElement" needs to exist in Quickform2.  Have
+you considered an API similar to the following?
+
+<?php
+
+$form = new HTML_Quickform2;
+$form['action'] = '/path/to/action.php';
+$form['method'] = 'post';
+// or
+$form['attrs'] = array('action' => '/path/to/action.php', 'method' =>
+'post');
+
+$g = $form->group['mygroup'];
+$g->text = array('name' => 'aText', 'size' => 50, 'default' => 'whatever');
+$g->select = array('name' => 'aSelect', 'options' => array(...));
+
+// or
+$g->text(array('name' => 'aText', 'size' => 50))
+         ->validate['regex'] =  '/\w+/';
+$g->select(array('name' => 'aSelect', 'options' => array())
+$select = $g->select['aSelect']; // or $form->select['aSelect'];
+$select->options['another'] = 1;
+$select->validate['custom'] = 'is_numeric';
+?>
+With all due respect, SimpleXML API which you seem to use as  
inspiration here uses
+addAttribute() and addChild() methods for adding attributes and child  
nodes, it doesn't
+work as shown above. ;)
+
+We considered something like that, but decided to go with DOM-like  
API for now.
+
+
+
+I assume it is more consistent to always use an array and provide  
additional setters for
+all possible keys, so every element can be added in both ways:
+
+$form->addElement('button', 'aButton', array('content' => 'Click me',  
'attributes' =>
+array('onClick' => 'alert("Clicked!")')));
+
+or:
+
+$clickbutton = $form->addElement('button', 'aButton');
+$clickbutton->setContent('Click me');
+$clickbutton->setAttributes('onClick' => 'alert("Clicked!")');
+
+Like this, every public property can actually be set on element construction.
+
+
+Anyway I see an other point I want to strongly advise to rethink: It  
looks like the QF2
+API will still be quite near to the HTML syntax of every single  
element, which is
+actually not consistent across the elements and their natures. I  
gather this assumption
+from the "options" property of the select element (besides:  
setOptions() also confuses as
+this method has a totally different meaning in many other PEAR classes).
+
+If you put your focus at interchangability of elements, you find 2  
different kinds of
+lists, which can both have 2 different forms:
+
+1. List with only one element selectable:
+- Select element with size=1 (or no size attribute)
+- Radiobutton group
+
+2. List with multiple selectable elements:
+- Select element with size > 1
+- Checkbox group
+
+IMO those should be treated identically, for example:
+
+$ctry = $form->addElement('select', 'country');
+$ctry->setList(array('CH' => 'Switzerland', 'FR' => 'France'));
+$ctry->setContent('CH');
+
+If you later decide to change it to a radiogroup, you just have to  
change the line:
+$ctry = $form->addElement('radiogroup', 'country');
+
+Also note that I suggest to use setContent() to define the  
preselected option rather than
+something like $option->setSelected() (which could be left as an  
alternative). It looks
+consistent to me to set the preselected value with the same method  
for all kinds of
+elements/groups, regardless of the way it looks in the generated  
HTML. So setContent() in
+a select box will result in setting the selected attribute, while it  
will set a value
+attribute if applied on a text field.
+
+
+
+
+I would even make it:
+
+$clickbutton =
+   $form->addElement('button', 'aButton')->setContent('Click
+me')->setAttributes('onClick' => 'alert("Clicked!")');
+
+On 4/17/07, Christoph Schiessl <c.schiessl at gmx.net> wrote:
+
+[Show Quoted Text - 58 lines]
+On Apr 17, 2007, at 9:58 AM, Markus Ernst wrote:
+Alexey Borzov schrieb:
+[...]
+What's really being discussed is the following, will we make the
+"additional data" parameter that has different semantics from
+element to element always an array, so the first pair of calls
+above turns into
+$form->addElement('button', 'aButton', array('content' => 'Click
+me please'));
+$form->addElement('select', 'aSelect', array('options' => array
+('1' => 'option 1', '2' => 'option 2')));
+even though the elements in question will never need any
+additional data other than 'content' and 'options'.
+I assume it is more consistent to always use an array and provide
+additional setters for all possible keys, so every element can be
+added in both ways:
+
+$form->addElement('button', 'aButton', array('content' => 'Click
+me', 'attributes' => array('onClick' => 'alert("Clicked!")')));
+I don't like the idea of using arrays for the additional parameters.
+Element creation has always been a problem for me in QF1, because
+there were to many possible combinations of parameters to remember
+all of them.
+or:
+
+$clickbutton = $form->addElement('button', 'aButton');
+$clickbutton->setContent('Click me');
+$clickbutton->setAttributes('onClick' => 'alert("Clicked!")');
+
+Like this, every public property can actually be set on element
+construction.
+Looks nice. I think that would be easier to use (and to remember).
+Also note that I suggest to use setContent() to define the
+preselected option rather than something like $option->setSelected
+() (which could be left as an alternative). It looks consistent to
+me to set the preselected value with the same method for all kinds
+of elements/groups, regardless of the way it looks in the generated
+HTML. So setContent() in a select box will result in setting the
+selected attribute, while it will set a value attribute if applied
+on a text field.
+Fully agree on that one.
+--
+Markus
+
+
+I cannot say I support setting variables and properties with arrays,
+it also have been the biggest thing that kept me away from QF for a
+long time.
+
+
+Bertrand Mansion wrote:
+Hi all,
+
+We are in the middle of a discussion Alexey and I about QuickForm2 API
+for elements creation and I would like your opinion as well.
+At this point, nothing is immutable since we aren't even talking about
+alpha stage, so your preferences as users and developers is interesting.
+
+To summarize, Alexey would be in favor of this:
+
+$form->addElement('button', 'aButton', 'Click me please');
+$form->addElement('select', 'aSelect', array('1' => 'option 1', '2' =>
+'option 2'));
+
+While I would be in favor of this:
+
+$form->addElement('button', 'aButton')->setContent('Click me please');
+$form->addElement('select', 'aSelect')->setOptions(array('1' => 'option
+1', '2' => 'option 2'));
+
+This is an example for adding a button to a form. The API can get more
+complex for Date elements and other javascript aided elements.
+
+My opinion is that we shouldn't mix configuration parameters for
+elements with other kind of data they might need.
+
+The other point we are discussing is about the extra parameter in
+element creation. I suggest we always use an array, even when there is
+only one extra parameter. Alexey suggests that we use a scalar if there
+is only one extra  parameter. For example, for a given "Year" element
+which would only accept one configuration parameter 'startYear', Alexey
+would use:
+
+$form->addElement('year', 'aYear', '2007');
+
+While I would use:
+
+$form->addElement('year', 'aYear', array('startYear' => '2007'));
+
+So my way is more verbose and less writable, but is also more readable
+and extensible.
+
+Given these examples, are there any opinions or preferences in favor of
+one or the other proposed API ?
+Hi Bertrand,
+
+I've honestly found the addElement() API to be difficult to work with in
+the past, so simplifying it would be a welcome change.
+
+However, I don't think "addElement" needs to exist in Quickform2.  Have
+you considered an API similar to the following?
+
+<?php
+
+$form = new HTML_Quickform2;
+$form['action'] = '/path/to/action.php';
+$form['method'] = 'post';
+// or
+$form['attrs'] = array('action' => '/path/to/action.php', 'method' =>
+'post');
+
+$g = $form->group['mygroup'];
+$g->text = array('name' => 'aText', 'size' => 50, 'default' => 'whatever');
+$g->select = array('name' => 'aSelect', 'options' => array(...));
+
+// or
+$g->text(array('name' => 'aText', 'size' => 50))
+         ->validate['regex'] =  '/\w+/';
+$g->select(array('name' => 'aSelect', 'options' => array())
+$select = $g->select['aSelect']; // or $form->select['aSelect'];
+$select->options['another'] = 1;
+$select->validate['custom'] = 'is_numeric';
+?>
+
+Compare this to:
+
+<?php
+
+$form = new HTML_Quickform2('/path/to/action.php', 'method' => 'post');
+$form->addGroup('mygroup');
+$form->addElement('text', 'aText', array('size' => 50, 'default' =>
+'whatever', 'group' => 'mygroup')
+   ->validate('regex', '/\w+/');
+$sel = $form->addElement('select', 'aSelect', array(...));
+$sel->addOption('another', 1);
+$sel->validate('custom', 'is_numeric');
+?>
+
+In the second example, my eyes are drawn to a bunch of "add*" and it
+appears that the important information ('text', 'select') is secondary.
+It takes me a while to figure out what is actually being done.  The
+first example has no superfluous information, but simply sets up the
+form in a straightforward, no-nonsense manner.
+
+In other words, I've always dreamed of having a simplexml-like API for
+accessing/creating forms.  I hate translating what I want to do into
+method APIs.  Think of this as bringing the REST model to forms
+creation, whereas everything has been XML-RPC based up to this point :).
+Using AAs for creating forms is absolutely the way to go. A huge +1
+for Greg's suggestions. It is exactly because of the reasons Greg
+mentions. The form creation and the actual display of the form should
+be separated completely.
+Another feature request I've had that may be possible is to integrate
+some kind of forms creation cache, so that the form need only be created
+programmatically once, and then it can on subsequent requests be quickly
+recreated from a disk or database cache, skipping all the expensive
+method calls, but this is a separate question than the one you asked,
+let me know if you'd like a feature request opened on this.
+This is *exactly* what Solar[1] does. You can load[2] forms (or
+rather, form "hints", which are just AAs) from SQL table objects and
+from XML files and hand them to your "view". This is *made* for MVC.
+
+This complicated API that you suggest seems a really bad idea to me.
+
+Anyways, just my $0.02
+
+[1] http://solarphp.com
+[2] http://solarphp.com/class/Solar_Form/load()
+
+
+
+
+
+I don't find any current implementations of forms to have a true cache.
+ The problem here is that a form is always changing.  It must respond to
+user input, display errors, and so on.  However, the logic of how the
+form is constructed is completely static.  Since the only thing we
+really need to be able to do is proper validation of form fields, and
+then to fill in a few placeholders (default value, error messages if
+any), this data can be cached as html, saving the need to construct a
+huge tree of objects.
+
+For high-volume sites, this could provide a large gain in
+requests/second, whereas building the form from an array is no different
+from building it with method calls - except you have the added step of
+parsing the array.
+
+Separating logic from view is irrelevant to my suggestion.  Quickform  
1.x used renderers to do this, I suppose Quickform2 will have some  
facility as well.


More information about the cvs mailing list