Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

Form Questions

Form validation help


Reply

5 Posts   1859 Views

Avatar
redactuk

14 June 2010 at 1:30pm Community Member, 117 Posts

Not used forms much up until now. I've read a fair amount on these forums, but I'm still a bit confused as to how I can add my own validation for a custom field? What I'm trying to do is implement a very simply spam protector that I often use in html forums. It's not very secure admittedly, but it suffices for very low volume sites and looks less bulky than full-on captcha. Basically it outputs random string that user re-enters to validate. Here's what I have so far:

   function contactUsForm() {
   
$ranstr = chr(mt_rand(65,90)) . chr(mt_rand(65,90)) . chr(mt_rand(65,90)) . chr(mt_rand(65,90)) . chr(mt_rand(65,90)) . chr(mt_rand(65,90));
      
      // Create fields
      $fields = new FieldSet(
      new TextField('Name'),
      new TextField('Email'),
      new TextField('Phone'),      
      new TextareaField('Message'),
      new TextField('SpamProtect', 'Enter first 3 letters of the following: ' . chunk_split($ranstr,1,' ') )   
      );
   
      // Create actions
         $actions = new FieldSet(
         new FormAction('doContactUs', 'Send')
      );
   
      //valididate fields
      $validator = new RequiredFields('Name', 'Email', 'Message', 'SpamProtect');
      
      return new Form($this, 'contactUsForm', $fields, $actions, $validator);
   
   }

Now adding my custom field to the validator above requires a value to be entered but of course does not do any checking. So I'm presuming I need to code a custom validator rule just for this custom field, but I'm slightly confused as to where I do this?

Any help appreciated!

Avatar
Willr

14 June 2010 at 2:59pm (Last edited: 14 June 2010 3:00pm), Forum Moderator, 5511 Posts

You would need to either do the validation in the doContactForm method or write your own form field type with a custom validate function.

Avatar
redactuk

15 June 2010 at 5:08am (Last edited: 15 June 2010 5:08am), Community Member, 117 Posts

or write your own form field type with a custom validate function.

Is there any documentation as to how I might best go about this?

Avatar
Willr

15 June 2010 at 10:58am Forum Moderator, 5511 Posts

No documentation on this specifically. Subclassing and overridding the validate function would look something like

<?php

class MySimpleCaptcha extends TextField {

private $captcha = "";

function setCaptcha($value) { $this->captcha = $value; };

function validate() {
return ($this->value == $this->captcha);
}

}

Then in your form you would have something like

$value = chunk_split($ranstr,1,' ');
$captcha = new MySimpleCaptcha('SpamProtect', 'Enter the following '. $value);
$captcha->setCaptcha($value);

That may work (I haven't tested) I think that 1 thing that might happen is that the captcha is regenerated on submit (so will always be wrong) so you may have to save the value in a Session variable. http://doc.silverstripe.org/sessions

Avatar
redactuk

16 June 2010 at 5:17pm (Last edited: 16 June 2010 5:23pm), Community Member, 117 Posts

Thanks willr but I really could not see how to integrate that with other form fields.

Having read article on SBits about using jQuery validator I decided to go down this route:

class ContactPage_Controller extends Page_Controller {

   function init() {
      parent::init();
      
      // Disables default form Prototype Javascript validation
   Validator::set_javascript_validation_handler('none');

      // Include jQuery validator files (using the hosted versions)
      Requirements::javascript("http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js");
      Requirements::javascript("http://ajax.microsoft.com/ajax/jquery.validate/1.5.5/jquery.validate.min.js");

      // Set up validations, including custom method to test captcha value against value stored in hidden field
      Requirements::customScript('
         jQuery(document).ready(function() {
            jQuery.validator.addMethod("captcha", function(value, element) {
               var correct = $("#Form_ContactForm_ranstr").val();
               return value == correct.substr(0,3);
            }, "Your answer must match the question");
            jQuery("#Form_ContactForm").validate({
               rules: {
                  Name: {
                     required: true
                  },
                  Email: {
                     required: true,
                     email: true
                  },
                  Message: {
                     required: true,
                     minlength: 1
                  },
                  SpamProtect: {
                     captcha: true
                  }
               },
               messages: {
                  Name: "Please enter your name",
                  Email: "Please enter your email address",
                  Message: "Please enter your message to me!"
               }
            });
         });
      ');
      
   }
   
   function ContactForm() {
      
      // Generate captch string
$ranstr = chr(mt_rand(65,90)) . chr(mt_rand(65,90)) . chr(mt_rand(65,90)) . chr(mt_rand(65,90)) . chr(mt_rand(65,90)) . chr(mt_rand(65,90));

      // Create form fields
      $fields = new FieldSet(
      new TextField('Name'),
      new TextField('Email'),
      new TextField('Phone'),      
      new TextareaField('Message'),
      new TextField('SpamProtect', 'Enter first 3 letters of the following: ' . chunk_split($ranstr,1,' ') ),
      new HiddenField('ranstr','', $ranstr)
      );
   
      // Create form actions
      $actions = new FieldSet(
      new FormAction('SendContactForm', 'Send')
      );

      return new Form($this, 'ContactForm', $fields, $actions);
   
   }

I still had issue though (as you pointed out) of how to store the generated string. Even though I could easily write it to session variable I could not see how to fetch the session variable in my jQuery addMethod. For now I've simply written it to hidden field and then use that in my jQuery addMethod. Not great as it makes even less secure, but it's pretty insecure captcha option anyway :)