This is a collection of PHP snippets that you can use to add custom validation to your Webforms. In any validation script, you may use the Drupal function form_set_error() to prevent the form from submitting and display a message to the user. It is also important to note that in Webform, you cannot change the $form_values or $form_state variables that are available to you in the additional validation code (you can, but it won't be saved). If needing to change these values, change them in the Additional Submission code instead.

This snippets are only intended for use with the Webform 2.x module. They will not work with CCK or other modules. For information on additional PHP processing in Webform 3.x, see http://drupal.org/node/754580 and http://drupal.org/project/webform_php.

To use any of these snippets:

  1. Visit the permissions page (admin/user/access in D5 or admin/user/permissions in D6) and ensure the current user has the "use PHP for additional processing" permission.
  2. Create or edit a new Webform
  3. Under the "Webform advanced settings", enter the snippet, including the <?php ?> tags.

The code will need to be updated slightly to work with your form. Wherever you see a field key, such as $form_values['submitted']['name_of_field'] you'll need to update the name of the field with the field key from your form. This field key is automatically assigned to fields (usually an all lowercase, no spaces version of the field label), but you can edit the key manually by editing an individual field and in the field configuration form change the Field Key value in the Advanced fieldset.
Please note that the examples assume you are not using fieldsets to group your fields in the form. If this is not the case, you must change you code accordingly, using for example $form_values['submitted']['name_of_fieldset']['name_of_field'] or form_set_error('submitted][name_of_fieldset][name_of_field', t('Error message.'));

Webform validation module (D6)

If you don't wish to add custom validation code to your webform directly or are looking for a better user interface to validate your webform components, check out the Webform Validation module.
This module comes with a set of default validation rules you can apply to your webform components, as well as the option to define your own validation rules in a custom module through the module's hooks.
See the Advanced webform validation with Webform Validation module handbook page for more information

Comments

AaronChristian’s picture

ian.d.rossi

In case you were still having troubles with this, you have a single quotation mark (apostrophe) in your form_set_error's t(); text output string that is not allowed. It is actually breaking your code and you can even see exactly where the text turns from Blue to Red on your post.

<?php
form_set_error('submitted][11', t('Oops! The email addresses you entered don't match. Please enter them one more time to make sure they match.'));
?>

What you need to do is escape the ' mark with a backslash so php can read it as being a quotation mark in a string field. So instead of ' you need \' ....

<?php
form_set_error('submitted][11', t('Oops! The email addresses you entered don\'t match. Please enter them one more time to make sure they match.'));
?>

That should return the form_set_error(); event callback correctly.

Good luck, hope it's not too late of a reply.

ian.d.rossi’s picture

Aaron, thanks a bunch for that tip. I did manage to get it working, but I'm facing a new issue, and if anyone can help that would be great!

I'm trying to run additional php code in the additional validation section of a webform. The reason why I'm doing this is because part of the validation of the some of the fields involves reaching out to the another server to validate the form input and then getting a response. So I'm trying to get that response and then send form errors if possible to prompt the user to correct the fields.

Is this possible? Or is validation code only allowed in the additional validation section.

m.e.’s picture

I'm also having problems with validation. I may not be understanding the syntax correctly ...

My form has a grid with suggested donation amounts. I have assigned a variable set_amount for this grid. The last radio button has a value "Other" instead of a dollar amount. If "Other" is selected, a textfield below the grid must contain a valid numeric amount. But right now, when I test with "Other" and leave the textfield blank or enter non-numeric values, I don't get an error message. If anyone can help me figure out why, I'd appreciate it. (I'm a little confused about submitted_tree and submitted, too, which may have some bearing on the problem.)

<?php 
$typed_amount = str_replace(',', '', $form_values['submitted']['typed_amount']);
$set_amount = $form_values['submitted']['set_amount'];
//check for a valid custom donation amount if Other* radio button was chosen
if ($set_amount == 'Other*' && !(is_numeric($typed_amount))) {
  form_set_error('submitted][typed_amount', t('Please enter a valid numeric donation amount.'));
}
?>
petrovichby’s picture

One correction.
The fieldset example variable

$form_values['submitted']['name_of_fieldset']['name_of_field']

should be read (at least in 6.x) as

$form_values['submitted_tree']['name_of_fieldset']['name_of_field'].

jfinkel’s picture

As I understand it, all these validation routines are server-side. That is, they are PHP code that is executed on the server when the form is submitted. Normally, I do not even like to submit the form until I have validated the input on the client (using Javascript). With the use of AJAX, even validation that requires data from the server can be performed without posting the entire form.

Question: How do I hook in client-side validation (written in Javascript). I know I can brute-force it with jQuery by hooking a function to the submit button's click event. Is there a different technique that could be considered to be a Best Practice?

Thanks in advance,
Joel

Jelle_S’s picture

There's a module for that! ;-)

Clientside Validation

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."

pcave’s picture

Anyone got any examples of how to run additional validation on a multi-page webform?

Andy Dorman’s picture

I managed to get my added validation working in a multi-page environment. It is pretty easy as long as you have at least one field on each page that MUST be filled in before the basic validation will let you go to the next page.

I have a 2-page form and ALL my added validation applies to the second page. At first when I tried to go to the second page, my added validation code fired and I could not get to the second page to correct the errors. You see the problem. :-)

Here is what I started with in my added validation to prevent non-text chars in the form name fields.


$alnum = "/[^a-zA-Z0-9 ,\-.]/";
$alonly = "/[^a-zA-Z\-']/";

$fname = $form_values['submitted_tree']['contact_information']['first_name'];
$mi = $form_values['submitted_tree']['contact_information']['middle_name'];
$lname = $form_values['submitted_tree']['contact_information']['last_name'];

if ( (strlen(trim($fname)) > 0 && preg_match($alonly, $fname)) || (strlen(trim($mi)) > 0 && preg_match($alonly, $mi))  || (strlen(trim($lname)) > 0 && preg_match($alonly, $lname)) ) {
    form_set_error('submitted][first_name', t("Your name contains invalid characters. Only letters, - or ' are allowed."));
}

To fix my problem and ONLY do these checks on the second page, I changed the added validation code to ONLY run when the first_name field, required for the second page, is filled in.


// do the page 2 checks ONLY after the first_name field is filled in
if ($fname = $form_values['submitted_tree']['contact_information']['first_name']) {

  $alnum = "/[^a-zA-Z0-9 ,\-.]/";
  $alonly = "/[^a-zA-Z\-']/";

  $mi = $form_values['submitted_tree']['contact_information']['middle_name'];
  $lname = $form_values['submitted_tree']['contact_information']['last_name'];

  if ( (strlen(trim($fname)) > 0 && preg_match($alonly, $fname)) || (strlen(trim($mi)) > 0 && preg_match($alonly, $mi))  || (strlen(trim($lname)) > 0 && preg_match($alonly, $lname)) ) {
    form_set_error('submitted][first_name', t("Your name contains invalid characters. Only letters, - or ' are allowed."));
  }
}

This should work for any number of pages as long as each one has a required field that MUST be filled in. Just check that that field is filled in before running the block of your code that validates the fields on that page.

stevethewebguy’s picture

This is the way!! Multistep webform without depending on a NULL value from a text box on another page, which helped me for a while, thanks bro.

//deed-a-dee-daa! set page nums!
$_page_num = $form_state['values']['details']['page_num'];
$_page_count = $form_state['values']['details']['page_count'];

/**
* first laugh at the old rule & flip it the birds...
* if ($form_values['submitted_tree']['first_name'] != NULL) 
* heha... I could barely quit flippin off the screen there for a minute, this was KILLING me!
* ok, now cross your fingers that you're using the same versions as me:
* webforms 6.x-3.2, Webform Validation 6.x-1.2, Webform PHP 6.x-3.x-dev
*/
if($_page_num == 2)
{
$area = $form_values['submitted_tree']['phone_number']['infophone1'];
$phone = $form_values['submitted_tree']['phone_number']['infoareacode1'];
if (($area == NULL) AND ($phone == NULL))
{
form_set_error('submitted][phone_number][infoareacode1', t(' '));
form_set_error('submitted][phone_number][infophone1', t('Area Code and Phone Number are required.'));
}

elseif ((!is_numeric($phone)) OR ($phone == NULL))
{
form_set_error('submitted][phone_number][infoareacode1', t('Area code must be three numbers: 000'));
}

elseif (!preg_match('/[0-9]{3}-[0-9]{4}/', $area))
{
form_set_error('submitted][phone_number][infophone1', t('Required phone number format: 111-2222'));
}

$altphone = $form_values['submitted_tree']['alternate_number']['infophone2'];
$altarea = $form_values['submitted_tree']['alternate_number']['infoareacode2'];
if (($altphone != NULL) OR ($altarea != NULL))
{
if ((!is_numeric($altarea)) OR ($altarea == NULL))
{
form_set_error('submitted][alternate_number][infoareacode2', t('Area code must be three numbers: 000'));
}
elseif ((!preg_match('/[0-9]{3}-[0-9]{4}/', $altphone)) OR ($altphone == NULL))
{
form_set_error('submitted][phone_number][infophone2', t('Required phone number format: 111-2222'));
}
}
}
//enjoy!

You can also use those for showing what page you are on in the form (I added the around all my rules for the second page validation in the if statement above, the page code went in one of the templates, webform-form.tpl.php I belive it is, you can copy it out of the module folder into your theme root to override it and add step numbers).

This put's the page number on whatever step of the webform (I have this in webform-form.tpl.php, in my theme root):

  print '<p id="steps">Step ' . $form['details']['page_num']['#value'] . ' of ' . $form['details']['page_count']['#value'] . '</p>';
petrnek’s picture

I needed to make conditions for displaying some fields, depending on profile settings. here is my quick and dirty solution:

Add markup field, and add php code as follows. Component webform-component-zelenina has to be included as another item of the form.

global $user;

if ($user->profile_zelenina =='1')
print "";
else
print '
<style type="text/css">
div#webform-component-zelenina { display: none; } 
</style>
';


dshearon’s picture

Is it possible to validate entered data doesn't already exist in the database?

For example, I have a webform where the user enters a serial number and internal ID along with other information. I would like the form to check if either of these values already exist in the database.

reglogge’s picture

I suddenly received large amounts of spammy submissions to my contact form that I created with webform module. In the content-textarea of the submitted form I found lots of links to random urls. Here's how I fought back successfully without using Captcha module:

I used webform's additional validation feature (found under the "advanced settings") and added the following code there:

<?php
$message = $form_values['submitted_tree']['message'];
$findme   = 'http://';
$pos = strpos($message, $findme);  
  if (!$pos === false) {
    form_set_error('', t('Links are not allowed in the message. Please remove the part http:// from your links.'));
  }
?> 

This effectively blocked spambots from submitting messages containing "hot" links like <a href="http://www.casino.org">WIN BIG</a> but still allows genuine visitors to send me links written as www.drupal.org.

You need to adjust the $message-variable to your specific form of course.

Also the validation does not fire when the $findme-string is at the very beginning of the message (which is not an issue here since a "hot" link would always have to begin with <a href=") or something like this.

MsG’s picture

My validation is working, it gets the error class. But the defined eror text isn't shown anywhere on the page and isn't in the source code.

<?php
// Grab variables.
$telefoon = $form_values['submitted_tree']['telefoon'];

// Check for values.
if ($telefoon == "Telefoon" || $telefoon == "")
{
  form_set_error('submitted][telefoon', t('Error message.'));
  echo "<h1>something</h1>";
}
?>

Tried everything, without the 't' thingy, with " " instead of ' '. I do see the <h1> echo but I don't see the text Error Message.

_vid’s picture

Hi MsG,

[edit]
I think I replicated your error. but it only happens for me when I've tested for the same error above.
For example:

if(strlen($form_values['submitted_tree']['reviewing_supervisor']['review_supervisor_95']!==9)){
	form_set_error('submitted][reviewing_supervisor][review_supervisor_95', t("Error: Supervisor ID is the wrong number of digits."));
	echo "you must have fallen asleep while typing!";
} 
if(strlen($form_values['submitted_tree']['reviewing_supervisor']['review_supervisor_95']!==9)){
	form_set_error('submitted][reviewing_supervisor][review_supervisor_95', t("Error2: Supervisor ID is too short or too long."));
	echo "I'm checking for this error twice!";
} 

In this case I only see one error message (the first one) but I see both echo statements.

andtokyo’s picture

thank you reglogge

selinav’s picture

How to apply the red border like in the standard validation?

Andy Dorman’s picture

I know I will be embarrassed when someone tells me where it is...
I just upgraded to webform 6.x-3.0-beta5 from 6.x-2.9. But when I went to update my Additional Validation and Additional Submission code to match the new form component names I could not find either code block in the admin forms?

I looked in node/2/webform/configure at the Advanced Settings fieldset and the code fields are gone.

Also looked in admin/settings/webform in the Advanced options fieldset and they are not there either.

I looked at the database and the code is still there in webform.additional_validate & additional_submit. But I can not easily edit it. And when I looked for usage of the additional_ values in the new webform module code, I did not find any beyond the module install code.

I have been searching for several hours now for any devel notes about what has been done to replace or move these blocks but no luck so far. Sure would appreciate someone telling me where these two crucial code blocks got to with the latest version.

Thanks,

Andy Dorman’s picture

OK. I found webform_php module. And thank you to the webform team that added it.

FWIW, let me summarize what my extra validation and submit code does. I do not believe I am alone in these requirements (that was why I posted most of my work back to the community). And I certainly tried the Webform Validation module before I dropped back to write my own code.

Additional_Validate: (I see some of these are in webform_validate and will be removing them from my own code if I can)
- In certain text fields use a regex to limit characters to alphanumeric or digits only
- look for certain terms in a text field and tell the user those terms go in a different field
- email address fields must match
- do not allow duplicate entries, duplicates being defined by several fields
- require several fields inside a fieldset to be completed IF an earlier field value was set
- for a multi-page form, validate fields in the second (or subsequent) page ONLY when a required field from the second page has been filled in.

Additional_Submit:
- take all the form fields and format them a very specific key-value string to be Curled to a remote URL
- based on certain form values, format the Curl differently and send to a different URL
- evaluate the response from the Curls and set a special field in the webform_data

There is just no way a standard module could easily handle the above requirements. And expecting someone to write a new module to handle unique requirements for every form seems a little unwieldy.

So I really want to thank the webform team for allowing us to continue to handle our unique needs without writing a new module. :-)

h3nr1ke’s picture

Hi guys,

if i have 3 or 4 functions to validate a form, and the first one is the main one.

If this fail I dont want to execute the other validation functions.

How can I do this?

thanks...

coder.td’s picture

After searching high and low on details for adding custom PHP code to a Webform that runs on submission, I finally figured it out.
I wrote this short howto that explains the steps involved in writing a module, hooking it into Webform's submission event model, and adding custom Javascript validation for form fields.

The howto is here:
http://docs.quantact.com/drupal-webform-custom-php-code

rubyji’s picture

Does anyone have a snippet for validating that the user submitting the form is an authenticated user? I would think this would be pretty simple, but I'm not a PHP person.

Thanks in advance for any suggestions!

bossmac’s picture

Hi
have you solved this issue?

crossmedia’s picture

If you have complex multi step forms and form components within the fieldsets and you want to apply validation using form_alter() and form_validate hooks, the below code might be helpful for you.


function modulename_form_alter(&$form, &$form_state, $form_id){
  if($form_id=='webform_client_form_13'){
    $form['#validate'][] = 'modulename_form_validate';
  }
 }

function modulename_form_validate($form, $form_state){
 if($form_state['values']['submitted']['page_2']=='Page 2'){ //error should be display on this step (page) of form only
  $val = $form_state['values']['submitted']['fieldset_name']['fieldname']['array if any']; // get value of the field
   if($val=='your check condition'){ // put your condition
 form_set_error('submitted][fieldset][fieldname][array if any', t('error message goes here'),FALSE); // display error and highlight
}
}
}

The above custom module will validate form field and display error message and highlight the offend field as well, please let me know if you need anything else from our side.

bossmac’s picture

Hi..

It's possible for a webform to redirect to login page if user is not log in after the user click the submit button, then save the data and back to form after authenticated?

thanks.