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 /

Custom validation of the form fields on the server side


Go to End
Reply


12 Posts   5671 Views

Avatar
mauzer_tim

Community Member, 11 Posts

21 February 2010 at 1:43am

Hello,

I need to develop a custom form which fileds must be checked on the server side and if they are not correct I need to display a message above the form (or near the field, depending on the situation) with error message. I've spent my last 2 hours trying to figure out how to do that very simple task and strangely I've never found this information. All the tutorials contain only samples of the primitive validation on non-empty values.

Avatar
mauzer_tim

Community Member, 11 Posts

21 February 2010 at 6:43pm

No answer for a day :( It's strange, as I cannot believe it that no one on this forum haven't had a deal with such basic thing as custom validation of the forms. I'll try to describe what I found out for this time and what is still obscure for me.

With cut and try method I found that I have to use Form->sessionMessage method to display a message on the form. So the code of my "submit" handlers looks like this:

class SupportForm extends Form {
....
public function submit($data, $form) {
$this->sessionMessage("You entered either an incorrect license key or your registration name", "bad");
Director::redirectBack();
}
....
}

However after the submission and displaying the form with error message all field values are cleared. What should I do to leave them displaying?

I tried to examine the code of Form.php file of the Saphire framework but I haven't found a clear way how to make server-side validation. Moreover after I disabled JavaScript in my browser I found that the Form after submission doesn't display error messages below the fields but it clears all the field values. Does it means that there is no real server side validation & saving field values in the Saphire?

Avatar
banal

Community Member, 901 Posts

22 February 2010 at 1:25am

Hi

I never used custom validation, but from my understanding, SilverStripe puts the validation into the field and not in custom Validator classes (as for example ZendFramework does).

You should probably create a custom field-class, eg. LicenseKeyField extends Textfield and implement a validate method there. For inspiration, have a look at the DateField class in sapphire/forms/DateField.php.

Avatar
mauzer_tim

Community Member, 11 Posts

22 February 2010 at 2:16am

Banal, thanks for the response.

I think this is not a good idea as it'll require quite much coding (suppose the form has 15 fields), moreover in my case (and many others) it's required to check values of 2 fields at the same time (license key and user name).

Avatar
banal

Community Member, 901 Posts

22 February 2010 at 5:22am

Not sure about your exact needs, but I don't think you'll need 15 different types of form fields? Usually TextField is just fine, and you can use the RequiredFields validator for simple required fields.

As for your LicenseKey Field. The Field itself could access the form data and see if the name and key values match. Here's a very simple example (complete class listing):

<?php
class LicenseKeyField extends TextField
{
   function validate($validator){
      if(!empty ($this->value)){
         // get the Username field from the form. Of course this would be nicer
         // if it wasn't hardcoded...
         $other = $this->getForm()->dataFieldByName('Username');
         $val = $other->value;
         
         // check the license key against a given pattern. Here we say that
         // only a value matching <Username> <dash> and four digits is a valid key
         if(!preg_match("/$val\-\d{4}/", $this->value)){
            $validator->validationError(
               $this->name,
               "This is not a valid license key",
               "validation",
               false
            );
            return false;
         }
      }
      return true;
   }
}

So in your form you'll have a TextField "Username" and a LicenseKeyField. The LicenseKeyField would also include the Username field for it's validation. So if you have entered "Mauzer" in username, a valid License key would be "Mauzer-1234"

Here's a simple form setup for testing. If the form gets complicated, it's probably better to create a custom class for your form (eg. RegisterForm extends Form).

<?php
class FormPage extends Page
{

}
class FormPage_Controller extends Page_Controller
{
   function RegisterForm() {
      $fields = new FieldSet(
         new TextField('Company'),
         new TextField('Username'),
         new LicenseKeyField('LicenseKey')
      );
      
      $actions = new FieldSet(
         new FormAction('submit', 'Submit')
      );
      $validator = new RequiredFields('Company', 'Username', 'LicenseKey');
      $form = new Form($this, 'RegisterForm', $fields, $actions, $validator);
      return $form;
   }
   
   function submit($data, $form){
      // do something with the data...
      return array();
   }
}

Avatar
Willr

Forum Moderator, 5513 Posts

22 February 2010 at 12:51pm

However after the submission and displaying the form with error message all field values are cleared. What should I do to leave them displaying?

...
$this->sessionMessage("You entered either an incorrect license key or your registration name", "bad");
Director::redirectBack();


I think you will need to add a return after the redirectBack() like return Director::redirectBack(). You should also use $form->addErrorMessage() to add an error message to the form. Lots of modules use custom validation on forms eg Forum. Have alook at the doRegister function in ForumMemberProfile.php for an example

Avatar
Ben_W

Community Member, 80 Posts

26 February 2010 at 12:46pm

In your function submit($data, $form) put in following line. of course you need a appropriate session variable name.
Session::set("EmailUsFormData", $data);

Then in the page which this form is going to be display, inside its controller, add following. Again you need substitute the form name and so on. But you get the idea.

function FirstEmailUsForm(){
      $form = new EmailUsForm($this, 'FirstEmailUsForm');
      
      if(Session::get("EmailUsFormData")) {
         $previous_value = Session::get("EmailUsFormData");
         Session::clear("EmailUsFormData");
         $form->loadDataFrom($previous_value);
         //echo 'old';
      } else {
         $default = array(
                     'FirstName' => '',
                     'LastName' => '',
                     'Company' => '',
                     'Email' => '',
                     'Street' => '',
                     'Suburb' => '',
                     'State' => '',
                     'Country' => '',
                     'PostCode' => '',
                     'Phone' => '',
                     'ContactMeBy' => '',
                     'During' => '',
                     'Message' => '',
         );
         $form->loadDataFrom($default);
         //echo 'new';
      }
      
      return $form;
   }

Avatar
BenWu

Community Member, 90 Posts

13 March 2013 at 12:09pm

Edited: 13/03/2013 12:10pm

Hello Willr,

I don't think what you suggested work. I got the same problem here: after redirectback, the form is clear although the error msg is displayed.

I have to extends the RequiredfieldClass and add it back to the form

class MemberProfileValidator extends RequiredFields {
public function php (){
}
}


and then

$validator = new MyRequiredFields('Amount','Terms');
return new Form($this, 'bidForm', $fl, $actions, $validator);

Go to Top