4

I'm building a contact form in SilverStripe.

When testing validation, if I leave the required fields blank and hit submit, those input fields will be added a .holder-required class. Even if I reload the page, they won't disappear. (actually the error messages *** is required will stay there after reload too. I just stopped the messages from showing).

I've searched the whole project folder, but there's no file that even has holder-required in it.

Where does the .holder-required class come from?

3dgoo
  • 15,716
  • 6
  • 46
  • 58
DimSum
  • 352
  • 2
  • 4
  • 17

1 Answers1

5

The reason why you couldn't find holder-required is because it technically doesn't exist in the SilverStripe codebase, it actually is a class that is concatenated together from two strings.

In a FormField, there is a function called "extraClass" which adds these classes to the field.

Below is the snippet of code from the FormField class:

public function extraClass() {
    $classes = array();

    $classes[] = $this->Type();

    if($this->extraClasses) {
        $classes = array_merge(
            $classes,
            array_values($this->extraClasses)
        );
    }

    if(!$this->Title()) {
        $classes[] = 'nolabel';
    }

    // Allow custom styling of any element in the container based on validation errors,
    // e.g. red borders on input tags.
    //
    // CSS class needs to be different from the one rendered through {@link FieldHolder()}.
    if($this->Message()) {
        $classes[] .= 'holder-' . $this->MessageType();
    }

    return implode(' ', $classes);
}

What this tells us is that for a message that appears for a field, it will append holder-{Whatever_Your_Message_Type_Is} as an extra class.


The reason why $this->Message() would still be set after a page reload is that the error information is actually saved to the session for that form.

Below is a snippet from the Form class which is what calls the FormField::setError(), the function that sets the message property on the form field.

public function setupFormErrors() {
    $errorInfo = Session::get("FormInfo.{$this->FormName()}");

    if(isset($errorInfo['errors']) && is_array($errorInfo['errors'])) {
        foreach($errorInfo['errors'] as $error) {
            $field = $this->fields->dataFieldByName($error['fieldName']);

            if(!$field) {
                $errorInfo['message'] = $error['message'];
                $errorInfo['type'] = $error['messageType'];
            } else {
                $field->setError($error['message'], $error['messageType']);
            }
        }

        // load data in from previous submission upon error
        if(isset($errorInfo['data'])) $this->loadDataFrom($errorInfo['data']);
    }

    if(isset($errorInfo['message']) && isset($errorInfo['type'])) {
        $this->setMessage($errorInfo['message'], $errorInfo['type']);
    }

    return $this;
}

I've had a bit more of a browse of the Form code, it should be clearing the errors after it is rendering the form. There are two functions part of the form class, clearMessage and resetValidation.

The function clearMessage is called when rendering the form template through forTemplate. I do not see any usage of the resetValidation function throughout the SilverStripe CMS or Framework codebases.

You may need to potentially call one or the other in your code if under your circumstances the message is not clearing.

Turnerj
  • 4,258
  • 5
  • 35
  • 52
  • Thanks you so much!!! Do you know why the $Message variable won't be cleared even if I reload the page or clear the cache? this is keeping the error message and the .holder-required in the form unless I clear the cache and reopen the browser. – DimSum Sep 15 '15 at 13:21
  • I've expanded on my answer, basically the message is set from the session. While it is meant to clear itself, you may need to either clear the session itself (my answer covers how to) or you may need to clear your own cookies. It could be a bug in your specific SS version, are you using the latest SS 3.1 build (3.1.14)? – Turnerj Sep 15 '15 at 22:43
  • Thanks for the additional answer @Turnerj ! Sorry I only saw your reply today. yep I'm using the latest SS 3.1 build. I found that only after deleting the website's cookie and refresh would those messages be gone. I used validation.js instead, and ignored all the .holder-required classes... but it was not a perfect solution because the .holder-required classes are still there. I'll try the resetValidation function some time. – DimSum Oct 02 '15 at 14:00