phpformsvalidationsilverstripe

Compare two fields to see if they match


I'm trying to think of the best way to approach validating two emails fields for a form: I have an email field and a retype email field, and I want to compare them to see if they match. If not then display an error message saying so until the user enters in their email correctly for both fields.

I know there can be custom fields classes made to allow for custom validation but I'm using 2 separate fields, not one, and I'm not sure a custom class will work in this case since I'm not validating just one field.

I followed the example found here which involves adding custom validation to the form's submit function: https://docs.silverstripe.org/en/3/developer_guides/forms/validation/

However, I don't want to redirect anywhere -- I want to stay on the form.

I'd like to make this as simple as possible if I can help it.

Here is what I have so far. Other than the issue I mentioned, everything else works fine:

public function DemoForm() {
    $fieldsArr = array();

    $firstName = new TextField('first_name', 'First Name');
    $firstName->setAttribute('placeholder', 'First Name');

    array_push($fieldsArr, $firstName);

    $lastName = new TextField('last_name', 'Last Name');
    $lastName->setAttribute('placeholder', 'Last Name');

    array_push($fieldsArr,$lastName);

    $companytName = new TextField('company_name', 'Company Name');
    $companytName->setAttribute('placeholder', 'Company Name');

    array_push($fieldsArr,$companytName);

    $email = new EmailField('email', 'Email');
    $email->setAttribute('placeholder', 'Email');

    array_push($fieldsArr, $email);


    $retypeemail = new EmailField('retype_email', 'Retype Email');
    $retypeemail->setAttribute('placeholder', 'Retype Email');

    array_push($fieldsArr, $retypeemail);

    $fields = new FieldList($fieldsArr);

    $actions = new FieldList(
        new FormAction('submit', 'Submit')
    );

    $validator = new RequiredFields('first_name', 'last_name', 'email', "retype_email");

    return new Form($this, 'DemoForm', $fields, $actions, $validator);

}


public function submit($data, $form) {
    if($data['email'] != $data['retype_email']){
        $form->addErrorMessage('Email', 'The emails do not match.', 'bad');
        return $this->redirectBack();
    }
    else{
        $demoRequest = new DemoFormSubmission();

        $demoRequest->FirstName = $data['first_name'];
        $demoRequest->LastName = $data['last_name'];
        $demoRequest->EmailAddress =$data['email'];
        $demoRequest->CompanyName = $data['company_name'];

        $demoRequest->write();

        $email = new Email();

        $email->setTo('sara.dejaneiro@innismaggiore.com');
        $email->setFrom($data['email']);
        $email->setSubject("Demo request submission");

        $messageBody = "
        <p><strong>First Name:</strong> {$data['first_name']}</p>
        <p><strong>Last Name:</strong> {$data['last_name']}</p>
        <p><strong>Email: </strong> {$data['email']}</p>
        <p><strong>Company Name:</strong> {$data['company_name']}</p>

    ";
        $email->setBody($messageBody);
        $email->send();

        return $this->redirect("demo-request-submission-thank-you-page");
    }
}

Solution

  • Given your reply to my comment, I think you would probably be best to either:

    1. Create your own form field that extends CompositeField and then add a custom validate function (as per https://docs.silverstripe.org/en/3/developer_guides/forms/validation/#form-validation)

    2. Creating a custom validator, by extending RequiredFields (https://github.com/silverstripe/silverstripe-framework/blob/3.6.2/forms/RequiredFields.php) and then overloading the PHP method (https://github.com/silverstripe/silverstripe-framework/blob/3.6.2/forms/RequiredFields.php#L82).

    Number 2 might be the less fiddly approach. You can write your own custom logic and then if the validation fails simply return "false" and then SilverStripe will cancel form submission and return the user to the form with their data still in the form fields.