I figured out why I'll never be happy w/ php forms libraries

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

User avatar
VirtuosiMedia
Forum Contributor
Posts: 133
Joined: Thu Jun 12, 2008 6:16 pm

Re: I figured out why I'll never be happy w/ php forms libraries

Post by VirtuosiMedia »

I've read through this thread because I'm looking at creating my own form class. I haven't written the class yet, but I'm starting by trying to figure out the way I would want to write the form. Some of the things that I would want my class to be able to do are: remember entered information if validation fails (I call it 'sticky'), custom error messages for each type of validation along with the ability to display where the error messages are displayed, control positioning, etc. for every element by assigning classes or ids, labels, server validation for each element, JavaScript validation (optional) that matches the server side and is generated automatically, and I want to only have to enter the properties that I need. What I came up with was an almost JSON format. This is my first take, but tell me what you think:

Code: Select all

 
 
$form = new Form('post', 'self');
$form->errorDisplay('belowInput');
$form->text(array(
            'name'=>'username',
            'class'=>'formElement',
            'length'=>40,
            'label'=>array(
                        'text'=>'Username',
                        'align'=>'left',
                        'class'=>'formLabel'),
            'validate'=>array(
                        'empty'=>'A username is required',
                        'alpha'=>'Please enter only alphabetic characters'),
            'sticky'=>TRUE,
            'javascriptValidate'=>TRUE));
$form->password(array(
            'name'=>'password',
            'class'=>'formElement',
            'length'=>40,
            'label'=>array(
                        'text'=>'Password',
                        'align'=>'left',
                        'class'=>'formLabel'),
            'validate'=>array(
                        'empty'=>'A password is required',
                        'passwordStrict'=>'Your password must contain at least 1 uppercase letter, 1 number, and 1 character',
                        'min'=>array(6, 'Your password must be at least 6 characters long'),
                        'max'=>array(10, 'Your password length cannot exceed 10 characters'),
            'sticky'=>TRUE,
            'javascriptValidate'=>TRUE));   
$form->submit(array(
            'class'=>'registerButton'
            'value'=>'Register'));      
$form->createForm();
 
 
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Re: I figured out why I'll never be happy w/ php forms libraries

Post by Luke »

Hmm... I could deal with that interface. I'm not sure why, but I have this irrational fear of arrays of arrays of arrays. It just feels messy to me, but I'm not sure why. Arrays are PHP's bread and butter... so I need to get over it. And I still don't (and probably won't ever) like all-encompassing form solutions. For instance, Zend_Form does WAY too much stuff. I still haven't figured out exactly what would make me happy in a php form solution, but decorators are definitely NOT it. I hate Zend_Form's decorator, validator and filtering methodology. It is really confusing and overly complicated. I've tried about a billion form solutions for PHP and I just keep coming back to liking this type of solution (although it is generally more work, it just FEELS more clean and organized to me).

Rules and filters in the controller...

Code: Select all

<?php
        $model = new Q_Model_Contact;
        $input = new Q_Input($rawData);
        $input->setRequired($model->getRequiredFields());
        $filterchain= new Q_Input_FilterChain();
        $filterchain->addFilter(new Q_Input_Filter_StringTrim());
        $filterchain->addFilter(new Q_Input_Filter_Digits(), array('home_phone','cell_phone','business_phone','business_fax','business_zip'));
        $filterchain->addFilter(new Q_Input_Filter_Date('Y-m-d'), array('birth_date','join_date'));
        $input->addFilter($filterchain);
        
        $validatechain = new Q_Input_ValidateChain();
        $validatechain ->addValidator(new Q_Input_Validate_Email(), array('business_email','personal_email'));
        $validatechain ->addValidator(new Q_Input_Validate_USPhone(), array('home_phone','cell_phone','business_phone','business_fax'));
        $validatechain ->addValidator(new Q_Input_Validate_USZip(), array('home_zip','business_zip'));
        $validatechain ->addValidator(new Q_Input_Validate_USState(), array('home_state','business_state'));
        $validatechain ->addValidator(new Q_Input_Validate_Date(), array('birth_date','join_date'));
        $input->addValidator($validatechain );
And then the view would use helpers to render the form. It's still not the ideal solution and it requires a crap-load of work, but nothing else makes as much sense to me (oh and by the way I just kinda plopped the above out of my head, so forgive any errors in logic).
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Re: I figured out why I'll never be happy w/ php forms libraries

Post by Ollie Saunders »

Hmm... I could deal with that interface. I'm not sure why, but I have this irrational fear of arrays of arrays of arrays. It just feels messy to me, but I'm not sure why. Arrays are PHP's bread and butter... so I need to get over it.
I think I know why. It's because they are error prone. Unlike object and methods where if you reference something that doesn'tdoesn't exist you'll get an error, with arrays that won't happen, unless you work hard to build that functionality in at run time, which is probably a good idea but a bunch of work.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: I figured out why I'll never be happy w/ php forms libraries

Post by alex.barylski »

I think it's likely just because a object interface looks cleaner than nested arrays, it has more of an easy to follow flow and structure whereas an array element can literally be anything in the world because PHP arrays are generic containers.

How something appears is 50% of the battle in understanding it or feeling comfortable using it, so it's natural to be weary of arrays for this purpose.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Re: I figured out why I'll never be happy w/ php forms libraries

Post by Ollie Saunders »

Yes, if there are some objects and method calls you will like you understand some of the components of the library. Otherwise you're sending off this big nested message to some big boxed body of code that you have no idea how it functions (probably spaghetti code). The modularity of OO is comforting.
User avatar
VirtuosiMedia
Forum Contributor
Posts: 133
Joined: Thu Jun 12, 2008 6:16 pm

Re: I figured out why I'll never be happy w/ php forms libraries

Post by VirtuosiMedia »

Ollie Saunders wrote:
Hmm... I could deal with that interface. I'm not sure why, but I have this irrational fear of arrays of arrays of arrays. It just feels messy to me, but I'm not sure why. Arrays are PHP's bread and butter... so I need to get over it.
I think I know why. It's because they are error prone. Unlike object and methods where if you reference something that doesn'tdoesn't exist you'll get an error, with arrays that won't happen, unless you work hard to build that functionality in at run time, which is probably a good idea but a bunch of work.
I'm not all that crazy about multi-dimensional arrays either, but I've been working with the MooTools JavaScript framework a lot lately and it's influencing me somewhat as far as class structure. I'm not totally sure about how I feel about the object interface being cleaner...I guess it might depend a little on how you define cleaner. If a goal is less typing, a nested array format be cleaner because you don't have to type addValidator or addDecorator every time (though that isn't the worst thing in the world to have to do).

Error checking with arrays would be a lot more work, I agree. The thought of coding this class doesn't sound like a lot of fun to me, but once it's done and working, it could save a lot of time. A next step might be building forms using this class and a drag-drop form builder that spits out your form file, complete with validation, etc.

As for the spaghetti code problem, something like this could still rely on a lot of different classes and just serve as a high level wrapper that combines them. You would have two validator classes, one for PHP and one for JavaScript, a 'sticky' class, and maybe an AJAX class so that you can autosave, check for available usernames, etc.

I'm not saying that something like this would solve all problems for everyone, I'm just throwing it out there as an alternative format. I think it would probably save me some time, at least (once it's done). :wink:
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Re: I figured out why I'll never be happy w/ php forms libraries

Post by Luke »

Hey arborint, what's the word on A_Form? Any developments?
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: I figured out why I'll never be happy w/ php forms libraries

Post by Christopher »

We have an implementation where you can put the Filtering and Validation in the a Model class or the Controller. For the HTML, you can use templates or there is a form generation library. You can also just tell it the name of the form field helper class and it will load the helpers for you.

It all works (and there are some examples), but we really need someone like you who has a vision of what you want it to get it to a finished state. All the internal functionality should be there. I would be glad to show you what we have and make any changes you need to get the functionality and interface you are looking for.

As I recall from the examples you have shown, we would just need to add some methods to deal a group of fields at once rather than field by field, but that would be really easy to add (just loop through the field names and do the operation). I don't think it would take much work, if you can specify the interface.

I am glad to add and change the code for whatever you need, or let you hack the code yourself if you want SVN access. Let me know.
(#10850)
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Re: I figured out why I'll never be happy w/ php forms libraries

Post by Luke »

I do... my email address is below :)
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: I figured out why I'll never be happy w/ php forms libraries

Post by Christopher »

I added you as a member to the Google Code project. You are in the Project Skeleton group, so take a look a the "Form Manager" thread or let's just start a new thread.
(#10850)
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Re: I figured out why I'll never be happy w/ php forms libraries

Post by Luke »

sweet, I'll let you know how it goes
marcth
Forum Contributor
Posts: 142
Joined: Mon Aug 25, 2008 8:16 am

Re: I figured out why I'll never be happy w/ php forms libraries

Post by marcth »

VirtuosiMedia,

I just finished creating a PHP Form library called PHP Form Control (http://www.phpFormControl.com). It's an open-source, object-oriented form generator and validation solution. It does nearly everything you listed as requirements: it remembers what end-user entered if form validation fails; has custom error messages for each validation rule; and so on. The only thing it doesn't do is generate client side JavaScript--however, I included an example that shows how easy it is to make an AJAX call to validate the PHP form using the server-side PHP code.

Check the library out--it might be exactly what you need!

Marc.
User avatar
VirtuosiMedia
Forum Contributor
Posts: 133
Joined: Thu Jun 12, 2008 6:16 pm

Re: I figured out why I'll never be happy w/ php forms libraries

Post by VirtuosiMedia »

Okay, so I'm getting close on my array syntax for a form builder. Here's a syntax example of working code that will build the form and perform validations on each of the fields:

Code: Select all

 
<?php
$form = new VM_Form(array(), array('errorPosition'=>'beforeForm'));
$form->text('firstName', array(
    'attributes' => array('class'=>'input'),
    'label' => array(
        'innerHtml'=>'First name',
        'class'=>'label'
    ),  
    'validators' => array(
        'alpha'=>'Letters only',
        'required'
    )
));
$form->text('lastName', array(
    'attributes' => array('class'=>'input'),
    'label' => array(
        'innerHtml'=>'Last name',
        'class'=>'label'
    ),
    'validators' => array('alpha'),
    'minLength' => array(2)
));
$form->password('password', array(
    'attributes' => array('class'=>'input'),
    'label' => array(
        'innerHtml'=>'Password',
        'class'=>'label'
    ),
    'validators' => array('password'),
    'minLength' => array(6),
    'maxLength' => array(15)
));
$form->textarea('aboutMe', array(
    'attributes' => array('class'=>'input'),
    'label' => array(
        'innerHtml'=>'About Me',
        'class'=>'label'
    ),
    'validators' => array('required'),
    'minLength' => array(4)
));
$form->checkbox('agreeTerms', array(
    'attributes' => array('class'=>'checkbox'),
    'label' => array(
        'innerHtml'=>'I agree to the terms of service',
        'class'=>'label'
    ),
    'validators' => array('required'=>'You must agree to our terms of service to proceed'),
    'attributes' => array('value' => 'agree'),
    'labelPosition' => 'afterInput',    
));
$form->submit(array(
    'value'=>'Save',
    'class'=>'input'
));
$form->render();
?>
 
I should probably be done with a beta version either next week or the week after. I still have to make some modifications and add support for filters, but would anyone be interested in testing it out then? If so, I'll post the code and some instructions when it's a little more complete.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: I figured out why I'll never be happy w/ php forms libraries

Post by Christopher »

FYI - Ninja did his pass over the Skeleton validation and filtering classes. There were some nice changes and additions. They are completely OO using atomic Rule classes so infinitely extensible. I think he had great design input. The system really flattens the difficulty curve of complex forms.
(#10850)
User avatar
VirtuosiMedia
Forum Contributor
Posts: 133
Joined: Thu Jun 12, 2008 6:16 pm

Re: I figured out why I'll never be happy w/ php forms libraries

Post by VirtuosiMedia »

arborint wrote:FYI - Ninja did his pass over the Skeleton validation and filtering classes. There were some nice changes and additions. They are completely OO using atomic Rule classes so infinitely extensible. I think he had great design input. The system really flattens the difficulty curve of complex forms.
I took a quick look at it. I don't remember exactly what it looked like before, but it looked good. My basic validator and (soon to be) filter setup is similar and can allow for a syntax similar to yours, but my form creator is bit different with its array structure.

I took some of the advice from above and I'm having it throw exceptions if the arrays are malformed or non-existent. You can decide where you want your error lists: all the errors above the form, above each field, or below each field. It'll also add a CSS error class to to each label and input field on error and you can customize each error message or go with the default. You can also set as many HTML attributes for each label and input as you'd like. Label position (before or after the input) can be set for the entire form or for each form element. I think I have close to 50 different validators, but looking at your setup gave me a few ideas for three or four that I missed. It's still pretty rough and I know not everyone will like the array syntax, but I think that it'll save me, at least, a ton of time. I definitely wouldn't mind a couple pairs of eyes looking it over, though, if anyone is willing in a few days.
Post Reply