Two whole days as a Drupal developer I'm actively developing my first custom module (glorified form really.) Examining the node_example.module and other existing modules that come with Drupal have made this process pretty painless. However I'm now at the point of defining validation for my form elements and am surprised (and disappointed) to discover that the validation rules have to be redefined for each module. Is this possibly correct? I have multiple forms with 20+ elements that need validation. Hard coding the rules for each these just doesn't seem very efficient.

I already have a nice class written to handle just about every possible validation condition. For example

$validate = new FormValidator();
$validate->isEmpty("lastname", "Enter a Last Name.");
$validate->isDate("birthday_month", "birthday_day", "birthday_year", "Enter a valid Date of Birth.");

I then simply check for and output any errors:

if ($validate->isError())
{
// output the errors
$errors = $validate->getErrorList();
foreach ($errors as $error_entry)
{
echo $error_entry['msg']);
}
}

I'm wondering if something similair is built into Drupal or do you have to hard code the rules everytime as illustrated in node_example.module:

function node_example_validate(&$node) {
if ($node->quantity) {
if (!is_numeric($node->quantity)) {
form_set_error('quantity', t('The quantity must be a number.'));
}
}
else {
// Let an empty field mean "zero."
$node->quantity = 0;
}
}

Am I missing something here and making this harder than is? If my assumption is true (you have to recreate the rules for each module) then one of the very first things on my task list is to incorporate my class.

Any/all comments welcome.

Comments

gkokmdam’s picture

Hi Bacteria Man,

I'd love to use this validation code in my forms. (I'm writing a module for keeping track of child growth.) I also wondered why no validation was done centraly at all (specially the date-format matched against ones personal settings for date-format somehow)

I'd love to use your code so we can test it before it becomes readily available in Drupal. I'd love to add client-side checking. I do have some Javascript handy that does some checks on fields.

Could I have a peek at your full class, please?

wkr,
gkokmdam

johnhanley’s picture

Hi gkokmdam,

The class is a based on an article and the author refused my request to share it publicly. However send me your email address (via the propfile contact link) and I'll send it to you directly. I'll also include a snipet of code which demonstrates how to implement it in your module.

Regards,

gkokmdam’s picture

Hi,

thanks for the offer, but I would like to make my new module publicly available when it's mature enough. So, I think I will not be able to use it.

wkr,
gkokmdam

johnhanley’s picture

The class works great, but ideally form validation should be incorporated into Drupal.

coupet’s picture

Agree, what is the plan ?

Apache is bandwidth limited, PHP is CPU limited, and MySQL is memory limited.

johnhanley’s picture

Drupal simply needs to define a global methodology for defining reusable validation rules.

Again, 4.7 form API may already have this. I haven't spent enough time with it to know for sure.

My current approach with 4.6 works nicely and has a small footprintm. However, it may not be the most efficient way to handle it going forward.

I'm happy to participate in any discussions regarding validation.

coupet’s picture

Bacteria Man,

You are probably much closer to a solution to this issue than most others! I think you can create a project and describe the problem and suggest a solution. Then we can work and contribute from your base.

Apache is bandwidth limited, PHP is CPU limited, and MySQL is memory limited.

gte451f’s picture

HI there, have you made a progress or learned anything new regarding reusable form validation?

gkokmdam’s picture

Hi,

I'm working on my own version of form-validatation now. I might be able to extract that to some general routines that could make it into functions that could land in the form_* 'namespace' :-D If you are interested, please post details as to what you expect.

wkr,
Gerke

myriad’s picture

I've also just discovered this shocking news with the 4.7.0 beta 3 while making a new node type. I've done similiar things in my other websites and have a few validation rules put together. I'm wondering how easy it would be to implement an AJAX type of validation where, for example, once you move out a text field it instantly validates the user's input and changes the CSS to reflect it visually.

I think the most common validation types would be:

    name checking (the one in user.module for checking new user names looks pretty good)
    email (also in user.module)
    URL (also in user.module but no auto checking for schema [http://])
    alphanumeric
    integer (with min/max range)
    date (with min/max range)

And just a side thought, maybe it would be possible to include a new

    '#validate_type ' => array('int', 'min' => 13, 'max' => 150)

that could automagically run AJAX to the forms api.

Any more thoughts or ideas? I'll start looking into this.

fool2’s picture

How's this for a thought, integrating ajax even deeper. I'd like to have cross-field actions with ajax... almost like an ajax hook for each field.

So for instance, if a user selects one value that corresponds to a unique value in a database, the rest of the info will be loaded into the rest of the form.

An example of this would be entering a zipcode and having city and state info show up automatically.

myriad’s picture

yeah, I've seen this done before with other websites. I'm just a noob to Drupal, so it'll take me some time to figure the small things out.

If we put our heads together I'm sure we can figure something out. I'm sure there is a need for something like this.

fool2’s picture

I have gotten a form jump with refresh to (sort of) work but am looking to ajax it.

to add the onchange to the select you just put it in the form declaration as an attribute.

'#attributes' => array('onchange' => 'dosomething'),

so what I really don't have is the javascript method that pulls the data and puts it into the select form.

I'd wanna make it work sort of like autocomplete in the sense that you have a menu hook that returns the data in a simple format (simpler than xml) I like the bar format of the autocomplete.

Marc Bijl’s picture

Hi!

For a new site I use form_mail.module and forms.module to create several different mail / contact forms, that can be used by anyone (it's not necessary to log in as a user) and that will be sent to different addresses (depending on the form).

The forms are created by using the required php code at a static pages. At submission of any form, I'd like to validate some fields. Think about fields that are required, or fields that contain an e-mail address.

What is the best way to achieve this: how should I validate each form?

Thanks for replies!
Marc

___________________
discover new oceans
lose sight of the shore

johnhanley’s picture

Marc,

Which version of Drupal are you using? I believe the new 4.7 form API has better validation built into it. (I'm still using 4.6--too much effort to upgrade at this point.)

If you're using 4.6, I recommend using an extensible valdiation class and integrating it with hook_validation (assuming your validating node data.)

Any errors need to be added with form_set_error. Drupal will handle displaying the error messages and prevent the form from being submitted.

Good luck.

Marc Bijl’s picture

Hi Bacteria Man,

Thanks for the quick reply; it seems you're a guy with a lot of knowledge about this!

I'm using Drupal 4.6 indeed, so I like to follow your instructions. However, I'm not a real programmer (do know something about xhtml, do know something about php, but I'm more a designer than a technician :I ).

Can you please explain:

  • What is an extensible validation class? Can I probably find some documention somewhere?
  • How do I integrate this with hook_validation? In which file can this be found and what do I have to code?
  • Where can form_set_error be found? How should error messages be added and how does it integrate with above?

Looking forward to your reply, thanks for your effort!

___________________
discover new oceans
lose sight of the shore

johnhanley’s picture

Hi Marc,

An "extensible validation class" simply means a PHP class that's written in such a way that makes it easy to customize (i.e. "extend".)

I found such a class and modified it to integrate nicely with Drupal. Unfortunately I am not able to publicly share it because the original author forbid me to do so. However, write me directly and I will provide it to you. It might not suit your needs, but it's good for illustration.

So at the top of my custom module I include the class:

// form validation class
include_once('includes/validator.inc');

Then in hook_validation I create an instance of the class:

function hook_validate(&$node) {
  $edit = object2array($node);

  // create a new instance of validation class
  // and assign data source
  $validate = new FormValidator();
  $validate->setDataSource($edit);

You then simply define your rules and let Drupal know about any errors:

$validate->isEmpty("firstname", "Enter a First Name.");
$validate->isEmpty("lastname", "Enter a Last Name.");

if ($validate->isError()) {
  $errors = $validate->getErrorList();
  foreach ($errors as $error) {
    // let Drupal know about the error
    form_set_error($error['field'], t($error['msg']));
  }
} 

Ideally something like this should be built into Drupal, but this is the next best thing.

John