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.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Form Questions /

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Form validation help


Go to End


5 Posts   2676 Views

Avatar
redactuk

Community Member, 117 Posts

14 June 2010 at 1:30pm

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

Forum Moderator, 5523 Posts

14 June 2010 at 2:59pm

Edited: 14/06/2010 3:00pm

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

Community Member, 117 Posts

15 June 2010 at 5:08am

Edited: 15/06/2010 5:08am

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

Forum Moderator, 5523 Posts

15 June 2010 at 10:58am

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

Community Member, 117 Posts

16 June 2010 at 5:17pm

Edited: 16/06/2010 5:23pm

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 :)