diff --git a/src/Forms/CurrencyField.php b/src/Forms/CurrencyField.php index 3588ec2c8..5ed51df93 100644 --- a/src/Forms/CurrencyField.php +++ b/src/Forms/CurrencyField.php @@ -62,4 +62,10 @@ class CurrencyField extends TextField { } return true; } + + public function getSchemaValidation() { + $rules = parent::getSchemaValidation(); + $rules['currency'] = true; + return $rules; + } } diff --git a/src/Forms/DateField.php b/src/Forms/DateField.php index 972874fb8..5312d4eca 100644 --- a/src/Forms/DateField.php +++ b/src/Forms/DateField.php @@ -474,4 +474,10 @@ class DateField extends TextField { return $this->config; } } + + public function getSchemaValidation() { + $rules = parent::getSchemaValidation(); + $rules['date'] = true; + return $rules; + } } diff --git a/src/Forms/EmailField.php b/src/Forms/EmailField.php index a5b1f285b..d399b9612 100644 --- a/src/Forms/EmailField.php +++ b/src/Forms/EmailField.php @@ -55,4 +55,10 @@ class EmailField extends TextField { return true; } + + public function getSchemaValidation() { + $rules = parent::getSchemaValidation(); + $rules['email'] = true; + return $rules; + } } diff --git a/src/Forms/FormField.php b/src/Forms/FormField.php index 5082fcb50..9d6b46195 100644 --- a/src/Forms/FormField.php +++ b/src/Forms/FormField.php @@ -1459,6 +1459,7 @@ class FormField extends RequestHandler { 'readOnly' => $this->isReadonly(), 'disabled' => $this->isDisabled(), 'customValidationMessage' => $this->getCustomValidationMessage(), + 'validation' => $this->getSchemaValidation(), 'attributes' => [], 'data' => [], ]; @@ -1520,4 +1521,18 @@ class FormField extends RequestHandler { return $state; } + /** + * Return list of validation rules. Each rule is a key value pair. + * The key is the rule name. The value is any information the frontend + * validation handler can understand, or just `true` to enable. + * + * @return array + */ + public function getSchemaValidation() { + if ($this->Required()) { + return [ 'required' => true ]; + } + return []; + } + } diff --git a/src/Forms/NumericField.php b/src/Forms/NumericField.php index 7362cf924..474d61e0f 100644 --- a/src/Forms/NumericField.php +++ b/src/Forms/NumericField.php @@ -118,6 +118,12 @@ class NumericField extends TextField { return false; } + public function getSchemaValidation() { + $rules = parent::getSchemaValidation(); + $rules['numeric'] = true; + return $rules; + } + /** * Extracts the number value from the localised string value. * diff --git a/src/Forms/TextField.php b/src/Forms/TextField.php index 011999d9a..5a8e23285 100644 --- a/src/Forms/TextField.php +++ b/src/Forms/TextField.php @@ -108,4 +108,12 @@ class TextField extends FormField { return true; } + public function getSchemaValidation() { + $rules = parent::getSchemaValidation(); + if ($this->getMaxLength()) { + $rules['max'] = $this->getMaxLength(); + } + return $rules; + } + } diff --git a/tests/forms/FormSchemaTest.php b/tests/forms/FormSchemaTest.php index 38f6d4820..b51525d63 100644 --- a/tests/forms/FormSchemaTest.php +++ b/tests/forms/FormSchemaTest.php @@ -1,5 +1,8 @@ false, 'customValidationMessage' => '', 'attributes' => [], - 'data' => [] + 'data' => [], + 'validation' => [], ], ], 'actions' => [] @@ -199,6 +203,7 @@ class FormSchemaTest extends SapphireTest { 'customValidationMessage' => '', 'attributes' => [], 'data' => [], + 'validation' => [], ], [ 'id' => 'Form_TestForm_SecurityID', @@ -216,7 +221,8 @@ class FormSchemaTest extends SapphireTest { 'disabled' => false, 'customValidationMessage' => '', 'attributes' => [], - 'data' => [] + 'data' => [], + 'validation' => [], ], ], 'actions' => [ @@ -241,6 +247,7 @@ class FormSchemaTest extends SapphireTest { 'data' => [ 'icon' => 'save', ], + 'validation' => [], ], [ 'id' => 'Form_TestForm_action_cancel', @@ -263,6 +270,7 @@ class FormSchemaTest extends SapphireTest { 'data' => [ 'icon' => null ], + 'validation' => [], ], [ 'id' => 'Form_TestForm_Moreoptions', @@ -286,6 +294,7 @@ class FormSchemaTest extends SapphireTest { 'tag' => 'div', 'legend' => null, ], + 'validation' => [], 'children' => [ [ 'id' => 'Form_TestForm_action_publish', @@ -308,6 +317,7 @@ class FormSchemaTest extends SapphireTest { 'data' => [ 'icon' => null, ], + 'validation' => [], ], [ 'id' => 'Form_TestForm_action_archive', @@ -330,6 +340,7 @@ class FormSchemaTest extends SapphireTest { 'data' => [ 'icon' => null, ], + 'validation' => [], ], ] ] @@ -359,4 +370,166 @@ class FormSchemaTest extends SapphireTest { ); } + + public function testSchemaValidation() { + $form = new Form( + new Controller(), + 'TestForm', + new FieldList( + TextField::create("Name") + ->setMaxLength(40), + new DateField("Date"), + new NumericField("Number"), + new CurrencyField("Money") + ), + new FieldList(), + new RequiredFields('Name') + ); + $formSchema = new FormSchema(); + $schema = $formSchema->getSchema($form); + $expected = [ + 'name' => 'TestForm', + 'id' => 'Form_TestForm', + 'action' => 'Controller/TestForm', + 'method' => 'POST', + 'attributes' => + [ + 'id' => 'Form_TestForm', + 'action' => 'Controller/TestForm', + 'method' => 'POST', + 'enctype' => 'application/x-www-form-urlencoded', + 'target' => null, + 'class' => '', + ], + 'data' => + [], + 'fields' => + [ + [ + 'name' => 'Name', + 'id' => 'Form_TestForm_Name', + 'type' => 'Text', + 'component' => null, + 'holderId' => 'Form_TestForm_Name_Holder', + 'title' => 'Name', + 'source' => null, + 'extraClass' => 'text', + 'description' => null, + 'rightTitle' => null, + 'leftTitle' => null, + 'readOnly' => false, + 'disabled' => false, + 'customValidationMessage' => '', + 'validation' => + [ + 'required' => true, + 'max' => 40, + ], + 'attributes' => + [], + 'data' => + [], + ], + [ + 'name' => 'Date', + 'id' => 'Form_TestForm_Date', + 'type' => 'Date', + 'component' => null, + 'holderId' => 'Form_TestForm_Date_Holder', + 'title' => 'Date', + 'source' => null, + 'extraClass' => 'date text', + 'description' => null, + 'rightTitle' => null, + 'leftTitle' => null, + 'readOnly' => false, + 'disabled' => false, + 'customValidationMessage' => '', + 'validation' => + [ + 'date' => true, + ], + 'attributes' => + [], + 'data' => + [], + ], + [ + 'name' => 'Number', + 'id' => 'Form_TestForm_Number', + 'type' => 'Decimal', + 'component' => null, + 'holderId' => 'Form_TestForm_Number_Holder', + 'title' => 'Number', + 'source' => null, + 'extraClass' => 'numeric text', + 'description' => null, + 'rightTitle' => null, + 'leftTitle' => null, + 'readOnly' => false, + 'disabled' => false, + 'customValidationMessage' => '', + 'validation' => + [ + 'numeric' => true, + ], + 'attributes' => + [], + 'data' => + [], + ], + [ + 'name' => 'Money', + 'id' => 'Form_TestForm_Money', + 'type' => 'Text', + 'component' => null, + 'holderId' => 'Form_TestForm_Money_Holder', + 'title' => 'Money', + 'source' => null, + 'extraClass' => 'currency text', + 'description' => null, + 'rightTitle' => null, + 'leftTitle' => null, + 'readOnly' => false, + 'disabled' => false, + 'customValidationMessage' => '', + 'validation' => + [ + 'currency' => true, + ], + 'attributes' => + [], + 'data' => + [], + ], + [ + 'name' => 'SecurityID', + 'id' => 'Form_TestForm_SecurityID', + 'type' => 'Hidden', + 'component' => null, + 'holderId' => 'Form_TestForm_SecurityID_Holder', + 'title' => 'Security ID', + 'source' => null, + 'extraClass' => 'hidden', + 'description' => null, + 'rightTitle' => null, + 'leftTitle' => null, + 'readOnly' => false, + 'disabled' => false, + 'customValidationMessage' => '', + 'validation' => + [], + 'attributes' => + [], + 'data' => + [], + ], + ], + 'actions' => + [], + ]; + + $this->assertInternalType('array', $schema); + $this->assertJsonStringEqualsJsonString(json_encode($expected), json_encode($schema)); + } }