All the open feature requests that accumulated over the years for HTML_QuickForm package were moved to HTML_QuickForm2 package. Read the requests
For example, selects should be able to check whether the submitted value is part of the proposed options. Same thing with radios or checkboxes.
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()
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.
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.
I don't get what you mean here.
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.
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.
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.
Here are some ideas and comments based on my everyday work with QuickForm:
Thanks for a push in the right direction here! I created a separate page for discussing the changes to the values API — Alexey Borzov 2006-10-19 02:24
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.
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)