Feature requests in PEAR bug tracker

All the open feature requests that accumulated over the years for HTML_QuickForm package were moved to HTML_QuickForm2 package. Read the requests

Justin Patrin for FormBuilder

  • Tree structure for group grouping, moving elements, and more customization
  • Separation of QuickForm code and HTML code to support multiple backends (note that this means finding a way to deal with multiple “submit” types)
    • HTML
    • XHTML
    • XUL
    • WML
    • XFORMS
    • GTK
  • Allow a form to be added as a sub-form of the current one (see SubForm element in current FormBuilder).
  • Allow a form to be appended to the current form (the iterator over elements may be enough)

Bertrand : General ideas

  • A default submit action set via javascript with onSubmit or any other way.
  • Ability to add custom js in a defined container (ie. a variable)
  • Validation : some elements should have intrinsic validation.

For example, selects should be able to check whether the submitted value is part of the proposed options. Same thing with radios or checkboxes.

  • Ability to check if the form was submitted twice (disable submit button or check with hidden or sessions)
Some new ideas for the API related to building forms and adding elements.

Here is a link to an interesting implementation using the Reflection API for delegation: http://www.phptr.com/articles/article.asp?p=346958&seqNum=5&rl=1

Here are some examples of what could be proposed:

$form->addSelect('name', array('label' => 'My select', 'options' => $options), array('style' => 'color:red'));
 
$form->addSelect('name')->setLabel('My select')->loadOptions($options);
 
 
$form['name']; // --> getElementsByName() returns iterator with array access
 
foreach ($form['name'] as $element) {
    // do something with $element
}
 
$form['name'][0]->loadOptions($options);
 
$form['nonexist']; // --> returns empty array()

Klaus: More general ideas

  • (X)HTML indentation should be fixed.

Adam: Brain Dump

This is just a general brain dump of ideas, whether they are a good fit for QuickForm or not I don't know. I'm not thinking of backward compatibility, just about what might be cool.

  • What if QuickForm was split into two pieces: one would be a model form class that would be extended to add getters and setters for the values in your form, for example:
class MyForm extends HTML_QuickFormModel {
 public function getFirstName() ...
 public function setFirstName() ...
 public function getLastName() ...
 public function setLastName() ...
}

Then the engine would take the incoming request and create/populate the model based on form name and value names. I have been using Struts (Java MVC framework) for a few years now and this is how they handle form data.

This is a good idea, the only problem I see is performance as function calls in PHP are slow. The model object could also expose a __call() method that would return the requested object property.

  • Validation rules could be registered on the form model but implemetion of validation would be done by the engine (server-side) or the renderer (client-side)

I don't get what you mean here.

  • My personal view on development has changed a lot since we wrote QuickForm originally. I have seen a huge benefit to keeping display logic and other logic (business, controller …) separate. I would like to see maybe some QuickForm template functions for smarty so you can create your form model, the engine would populate it then the Smarty functions could display it. The otherside of that, if you wanted all objects and no templates: create form model, the engine populates it then the model is passed to a renderer that would display it.

Did you have a look at the HTML_QuickForm_Renderer classes. It implements a visitor pattern. It has renderers for Smarty, HTML_Template_IT/Sigma, HTML_Template_Flexy, HTML, Savant… It can deal with static and dynamic type of layouts.

  • I like the idea of some kind of element self-registry. Where if you include/require an element class then it automatically registers itself as an element type in QuickForm. This could be done having a public regsiterElementType function on the engine and then element classes would contain a static block (code outside of the class delcaration) that would register the class in the engine. It would clean up the eingine code and make custom elements easy. Same goes for validation rules.

We are already using this. For example, in advmultiselect, you can find this code:

if (class_exists('HTML_QuickForm')) {
    HTML_QuickForm::registerElementType('advmultiselect', 
                 'HTML/QuickForm/advmultiselect.php', 'HTML_QuickForm_advmultiselect');
}

You're right, my bad. That has been there since the beginning. I don't know what I was thinking. :-)

Justin Adie: feature requests

some of these are reflections of earlier requests. in which case pls consider them endorsements:

1. inbuilt handling of form resubmissions (back button, refresh etc) through use of a session key replicated in a hidden element. this also acts as a deterrent against form-spoofing.

Moving the discussion to a separate Bad Ideas page

2. enhance the validation at a form level: e.g. the value of a select element must actually be a permitted value (actually there is no reason why this should be a form level rule).

This is covered in Bertrand's ideas above (intrinsic validation) and IIRC in feature requests on PEAR website.

3. allow internal groupings for formatting purposes without the overhead of creating groups and managing group validation rules. e.g. i use fieldsets and legends a lot (table-less forms: always). currently we have to insert static html in the right places. a qf element that takes the first and last elements within the fieldset as arguments, together with a legend would be great

i notice that this has now in the course of implemetation in the Tableless renderer published on PEAR. i think my idea of a first/last element is neater than the proposed implementation but i understand the need for xhtml 1.1 compliance which militates an alternative method.

> 4. an alternative to the three select datepicker. how about a customisable js cal-datepicker element within the standard package?

Positive, but not within the standard package. :)

5. another element request: → drag'n'drop list boxes instead of checkboxes. when you have a list of more than 10 items a checkbox list just takes up too much real estate and multi-select boxes are way too clunky.

Is it the same thing as current advmultiselect element or something different?

from an html viewpoint: yes. something similar. but i think the button to transfer from one list to the other is better handled with drag'n'drop. No?

6. checkboxes just return 1 if checked. why? i know that advcheckboxes have a different behaviour but still…

7. how about a method
$form->setCSSClass($array);

that assigns class attributes to all elements, arguments passed by an array with keys either being element types or element names. an explicitly declared name will override the generic type for that element. i know this can be done through the attributes argument in each element (and again, this should take precedence).

No such methods will be added, I think. It will be quite easy to iterate over the elements and perform whatever operations you desire.

sure it can be done but is not the point of this package to abstract as much form handling code as possible/reasonable?

8. for the autocomplete element: quite often i find myself needing the same data in several boxes in a form (e.g. a country field for three different address types). how about adding some intelligence into the renderer so that the js data is not repeated three times?

9. i use hidden fields to store foreign key data in forms. i've always been worried by form-spoofing so have started using sessions instead. but i'd like the setConstants() function to override what is actually submitted by the user (or is parsed out as the result of a call to exportValues()). If this is architecturally a problem then how about another method like setConstants()/setDefaults() that provides for persistence?

I'd like to remove setConstants() altogether. Sessions should be used for passing info that is not expected to be changed, all other stuff needs to be validated.

shame !

gregmac: I think this is a bad idea. Sessions work across multiple windows, for example. So if you click 'open in new tab' for edit links (especially editing multiple items that use the same form), you run into problems with the constants only being set for one form, or telling you that you can't submit the form because something else has been edited, etc. All of it contributes to a bad user experience and an inflexible library. This could be worked around by maintaining a unique ID in the form (although this is also subject to end-user manipulation), but I think the easier solution – if all you're trying to prevent is the end-user from being able to mess around with the constants themselves – is to add a check value to the form. For example, have the md5 of all the constant fields, concatenated with a “secret key” of some sort unique to the server (user-specified key/ip address/httphost), added into the form. If any of the form constants are changed, when the form is submitted the check value won't match, and you can block the end-user appropriately.

Markus Ernst: Intuitive API for elements and groups

Here are some ideas and comments based on my everyday work with QuickForm:

  • A common argument list for element constructors (as mentioned at the ideas page) seems to be highly desirable to me. Specially for checkbox and radio elements the current situation is very confusing:
    • The distinction between “label” and “additional text” (which is actually used as the label) does not seem to make sense.
    • While the value for a radio element is set with an argument, for the checkbox it needs to be set after element creation via updateAttributes().
  • The idea of a special select element with a setting to be output as a group of checkboxes, radio buttons, or a HTML select element, looks good to me; also the idea of a radio button group built like a single element with an array of options. Whatever way, I suggest that the element name(s) are composed useable by default:
    • For single-choice elements/groups (non-multiple select, radiobutton group): name without brackets
    • For multi-choice elements/groups (multiple select, checkbox group): name[] with brackets
  • Comment regarding setValue() / getValue() methods: The value attribute is consistent regarding the processing of form submissions, but it is not regarding form creation. In text kind of elements the value reflects a user input resp. a default setting, but in select, radio and checkbox elements it reflects a possible choice, while the user input resp. default setting is reflected in the selected/checked attributes. To avoid confusion I suggest:
    • A setValue() method that sets the value attribute in all kinds of elements that have one (could also be dropped and handled via the $attributes parameter)
    • A setDefault() method that sets or unsets
      • the value attribute for textfields
      • the inner text for textareas
      • the checked attribute for checkboxes and radiobuttons
      • the selected attribute to the option containing the passed string as it's value for select elements

Thanks for a push in the right direction here! I created a separate page for discussing the changes to the values APIAlexey Borzov 2006-10-19 02:24

  • For both applying labels in a template, and DOM access, it would be nice to have a predictable ID for each element, instead of a random one. I also found it handy to modify the static renderer to provide {formname_elementname_id} and {formname_elementname_labelclass} variables (the latter containing for example “error” if there is an error in the element, allowing to style the error label with CSS). Anyway for this last point I can't say if it matches public needs or more my own ones.

Sylvain Beucler

  • Sample default values below a text field, to better explain the user what is expected from him (example - this is quixote-based)
  • A way to easily edit a series of similar entries, presented as a table - think spreadsheet. You would edit, for example, a series of lines each containing 4 fields (name, surname, tel, email) representing a phone book, instead of editing each entry alone. On submission, the PHP script would receive a 2D-array containing each entry: [0 ⇒ [name⇒John, surname⇒Smith, tel⇒007, email⇒me@me.net], 1 ⇒ [name⇒…]]. Possibly in combination with Structures_DataGrid to produce an edit form mapping to an existing database table.

LukeNukem

As much as I like QuickForm, I do like Propel as one of the best object-relational mappers I've seen for PHP (and I'm through a lot to find something vaguely simliar to SQLObject and Class::DBI). I'd like to have some sort of interface that allows me to get validated form data from QuickForm and pass it directly to Propel, and vice versa. At the moment, I use a decorator pattern for Propels BaseObject class and it, well, sort of works in pracitce, but it's nothing but a dirty hack. Before, I've tried a facade pattern on HTML_QuickForm, but it didn't perform and was dirty as well.

I'd rather request the HTML_QuickForm project to work with the Propel people in order to provide some interface between the two object models. Preferrably, I'd like QuickForm::setFromPropel(<propelInstance>) and Propel::setFromQuickform(<quickformInstance>) in iterator or, rather, associative arrays. I'm not sure whether this is possible, and it could be a heavy task concerning to checkbox, file upload, radio button and other HTML form fields, but it may well be worth the effort. I'm not sure whether there should be an extension to QuickForm, Propel, both or none of these two projects (none in case a third project should be started). What i'm pretty sure about is that HTML_QuickForm and Propel could make a perfect team.

Stephen Beattie: Minor Additions

Been using HTML_QuickForm2 for the first time over the past couple of days. It's a truly great bit of code (and a huge improvement over HTML_QuickForm) but I ran into a couple of snagging points.

I had to use HTML_QuickForm2_Factory::registerRule() and create a custom rule class to get the functionality I needed from within the scope of my extended form class. In itself perhaps not a bad solution but using the Node::createRule() function I couldn't see how to pass in the scope of my class to enable the callback rule to use a method within the class itself. I'd like the callback rule to accept an array for the function name to facilitate this sort of encapsulation. As it stands it only seems to work with standalone functions. This could get a bit messy and I feel like having a separate rule class for each callback is overkill. Could we do something like this ?
// Code inside a class - $this is a reference to the current class and checkPassword is a method within it.
$oldPassword->createRule( 'callback', 'Wrong password', array( $this, 'checkPassword' ) );

I don't quite understand your problem here… The callback rule will accept array($object, 'methodName') as a callback. On the other hand, if you are already creating classes, why don't you create subclasses of HTML_QuickForm2_Rule and use them instead? — Alexey Borzov 2007-12-09 19:13

On another note, could the auto-generated ids for elements use an underscore '_' as opposed to a hyphen '-'? (Ref. Line 180 Node.php). I've been using the element ids from the form in some generated javascript and as the hyphens are interpreted as minus signs this is problematic.

Bertrand: I don't see a problem with hyphens, please file a bug report if it doesn't work correctly. Ultimately, using underscores or hyphens could become a configuration option using constants. A final request. It's probably too early to be thinking of javascript client side validation but my friend made some progress following server-side validation architecture in javascript for his Symfony PokaYoke plugin. Perhaps a similar approach could be taken for HTML_QuickForm2 in creating matching rules in Javascript thereby making it easy to generate the necessary client code as it will conform to a similar API. Perhaps use JQuery for this(example)

 
feature_requests.txt · Last modified: 2008/06/03 19:42 (external edit)