From e429137bb8b2ee0736be97e82d2e7709fd95ec93 Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Tue, 21 Apr 2009 03:44:13 +0000 Subject: [PATCH] ENHANCEMENT: moved validation of user defined forms to jquery based using the validate plugin. MINOR: moved submitted field infomation to its own folder --- code/UserDefinedForm.php | 118 ++++++++++++++---- code/editor/EditableDateField.php | 26 +++- code/editor/EditableEmailField.php | 27 ++-- code/editor/EditableFormField.php | 30 ++++- code/editor/EditableFormHeading.php | 30 ++++- code/editor/EditableTextField.php | 16 +++ .../SubmittedFileField.php | 0 .../{editor => submissions}/SubmittedForm.php | 0 .../SubmittedFormField.php | 0 .../SubmittedFormReportField.php | 0 10 files changed, 202 insertions(+), 45 deletions(-) rename code/{editor => submissions}/SubmittedFileField.php (100%) rename code/{editor => submissions}/SubmittedForm.php (100%) rename code/{editor => submissions}/SubmittedFormField.php (100%) rename code/{editor => submissions}/SubmittedFormReportField.php (100%) diff --git a/code/UserDefinedForm.php b/code/UserDefinedForm.php index ee5e991..262f02d 100755 --- a/code/UserDefinedForm.php +++ b/code/UserDefinedForm.php @@ -227,9 +227,18 @@ class UserDefinedForm extends Page { class UserDefinedForm_Controller extends Page_Controller { - function init() { - Requirements::javascript(THIRDPARTY_DIR . '/prototype.js'); - Requirements::javascript(THIRDPARTY_DIR . '/behaviour.js'); + /** + * Load all the custom jquery needed to run the custom + * validation + */ + public function init() { + // block prototype validation + Validator::set_javascript_validation_handler('none'); + + // load the jquery + Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js'); + Requirements::javascript(THIRDPARTY_DIR . '/jquery/plugins/validate/jquery.validate.min.js'); + parent::init(); } @@ -241,10 +250,10 @@ class UserDefinedForm_Controller extends Page_Controller { * @return Array */ public function index() { - if($this->Content && $this->Form()) { + if($this->Content && $form = $this->Form()) { $hasLocation = stristr($this->Content, '$UserDefinedForm'); if($hasLocation) { - $content = str_ireplace('$UserDefinedForm', $this->Form()->forTemplate(), $this->Content); + $content = str_ireplace('$UserDefinedForm', $form->forTemplate(), $this->Content); return array( 'Content' => $content, 'Form' => "" @@ -268,31 +277,45 @@ class UserDefinedForm_Controller extends Page_Controller { * * @return Form */ - function Form() { - // Build fields + public function Form() { $fields = new FieldSet(); - $required = array(); - - if(!$this->SubmitButtonText) { - $this->SubmitButtonText = _t('UserDefinedForm.SUBMITBUTTON', 'Submit'); - } - foreach($this->Fields() as $field) { - $fieldToAdd = $field->getFormField(); - if($field->CustomErrorMessage) { - $fieldToAdd->setCustomValidationMessage($field->CustomErrorMessage); - } - - $fields->push($fieldToAdd); - if($field->Required) { - $required[] = $field->Name; - } - } + $fieldValidation = array(); + $fieldValidationRules = array(); - if(!isset($_SERVER['HTTP_REFERER'])) { - $_SERVER['HTTP_REFERER'] = ""; + $this->SubmitButtonText = ($this->SubmitButtonText) ? $this->SubmitButtonText : _t('UserDefinedForm.SUBMITBUTTON', 'Submit'); + + if($this->Fields()) { + foreach($this->Fields() as $field) { + $fieldToAdd = $field->getFormField(); + $fieldValidationOptions = array(); + + // Set the Error Messages + $errorMessage = sprintf(_t('Form.FIELDISREQUIRED').'.', strip_tags("'". ($field->Title ? $field->Title : $field->Name) . "'")); + $errorMessage = ($field->CustomErrorMessage) ? $field->CustomErrorMessage : $errorMessage; + $fieldToAdd->setCustomValidationMessage($errorMessage); + + // Is this field required + if($field->Required) { + $fieldValidation[$field->Name] = $errorMessage; + $fieldValidationOptions['required'] = true; + } + + // Add field to the form + $fields->push($fieldToAdd); + + // Ask our form field for some more information on hour it should be validated + $fieldValidationOptions = array_merge($fieldValidationOptions, $field->getValidation()); + + // Check if we have need to update the global validation + if($fieldValidationOptions) { + $fieldValidationRules[$field->Name] = $fieldValidationOptions; + } + } } $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''; + + // Keep track of the referer $fields->push( new HiddenField( "Referrer", "", $referer ) ); // Build actions @@ -304,13 +327,54 @@ class UserDefinedForm_Controller extends Page_Controller { if($this->ShowClearButton) { $actions->push(new ResetFormAction("clearForm")); } - - $form = new Form( $this, "Form", $fields, $actions, new RequiredFields($required)); + // return the form + $form = new Form( $this, "Form", $fields, $actions, new RequiredFields(array_keys($fieldValidation))); $form->loadDataFrom($this->failover); + + $FormName = $form->FormName(); + + $rules = $this->array2json($fieldValidationRules); + $messages = $this->array2json($fieldValidation); + + // set the custom script for this form + Requirements::customScript(<< $value) + if(is_array( $value )) { + $result[] = "$key:" . $this->array2json($value); + } else { + $value = (is_bool($value)) ? $value : "\"$value\""; + $result[] = "$key:$value \n"; + } + return (isset($result)) ? "{\n".implode( ', ', $result ) ."} \n": ''; + } + /** * Process the form that is submitted through the site * diff --git a/code/editor/EditableDateField.php b/code/editor/EditableDateField.php index b982fe1..4e9e8af 100755 --- a/code/editor/EditableDateField.php +++ b/code/editor/EditableDateField.php @@ -7,7 +7,9 @@ * @package userforms */ class EditableDateField extends EditableFormField { + static $singular_name = 'Date field'; + static $plural_name = 'Date fields'; function DefaultField() { @@ -30,8 +32,28 @@ class EditableDateField extends EditableFormField { parent::populateFromPostData( $data ); } - function getFormField() { - return new CalendarDateField( $this->Name, $this->Title, $this->getField('Default') ); + /** + * Return the form field. + * + * @todo Make a jQuery safe form field. The current CalendarDropDown + * breaks on the front end. + */ + public function getFormField() { + return new TextField( $this->Name, $this->Title, $this->Default); + } + + /** + * Return the validation information related to this field. This is + * interrupted as a JSON object for validate plugin and used in the + * PHP. + * + * @see http://docs.jquery.com/Plugins/Validation/Methods + * @return Array + */ + public function getValidation() { + return array( + 'date' => true + ); } } ?> \ No newline at end of file diff --git a/code/editor/EditableEmailField.php b/code/editor/EditableEmailField.php index cf96398..68823b8 100755 --- a/code/editor/EditableEmailField.php +++ b/code/editor/EditableEmailField.php @@ -16,9 +16,8 @@ class EditableEmailField extends EditableFormField { static $plural_name = 'Email fields'; function populateFromPostData( $data ) { - $this->SendCopy = !empty( $data['SendCopy'] ) ? "1" : "0"; - - parent::populateFromPostData( $data ); + $this->SendCopy = !empty($data['SendCopy']) ? "1" : "0"; + parent::populateFromPostData($data); } function ExtraOptions() { @@ -28,10 +27,10 @@ class EditableEmailField extends EditableFormField { new CheckboxField( $baseName . "[SendCopy]", _t('EditableEmailField.SENDCOPY', 'Send copy of submission to this address'), $this->SendCopy ) ); - foreach( parent::ExtraOptions() as $extraField ) - $extraFields->push( $extraField ); + foreach(parent::ExtraOptions() as $extraField) + $extraFields->push($extraField); - if( $this->readonly ) + if($this->readonly) $extraFields = $extraFields->makeReadonly(); return $extraFields; @@ -42,7 +41,7 @@ class EditableEmailField extends EditableFormField { } function getFilterField() { - return $this->createField( true ); + return $this->createField(true); } function DefaultField() { @@ -50,5 +49,19 @@ class EditableEmailField extends EditableFormField { return '
'; } + + /** + * Return the validation information related to this field. This is + * interrupted as a JSON object for validate plugin and used in the + * PHP. + * + * @see http://docs.jquery.com/Plugins/Validation/Methods + * @return Array + */ + public function getValidation() { + return array( + 'email' => true + ); + } } ?> \ No newline at end of file diff --git a/code/editor/EditableFormField.php b/code/editor/EditableFormField.php index 1c053c0..aad083f 100755 --- a/code/editor/EditableFormField.php +++ b/code/editor/EditableFormField.php @@ -177,13 +177,23 @@ class EditableFormField extends DataObject { } /** - * Return a FormField to appear on the front end + * Return a FormField to appear on the front end. Implement on + * your subclass + * + * @return FormField */ - function getFormField() { + public function getFormField() { + user_error("Please implement a getFormField() on your EditableFormClass "+ $this->ClassName, E_USER_ERROR); } - function getFilterField() { - + /** + * Return the form field to appear on the filter form + * in the cms view + * + * @return FormField + */ + public function getFilterField() { + user_error("Please implement a getFilterField() on your EditableFormClass "+ $this->ClassName, E_USER_ERROR); } /** @@ -242,5 +252,17 @@ class EditableFormField extends DataObject { function CustomParameter() { return $this->CustomParameter; } + + /** + * Return the validation information related to this field. This is + * interrupted as a JSON object for validate plugin and used in the + * PHP. + * + * @see http://docs.jquery.com/Plugins/Validation/Methods + * @return Array + */ + public function getValidation() { + return array(); + } } ?> \ No newline at end of file diff --git a/code/editor/EditableFormHeading.php b/code/editor/EditableFormHeading.php index 8055d2e..c7eb145 100755 --- a/code/editor/EditableFormHeading.php +++ b/code/editor/EditableFormHeading.php @@ -6,22 +6,42 @@ */ class EditableFormHeading extends EditableFormField { + static $db = array( + 'Level' => 'Varchar(1)' + ); + static $singular_name = 'Form heading'; static $plural_name = 'Form headings'; + function populateFromPostData($data) { + $this->Level = (isset($data['Level'])) ? $data['Level'] : 2; + + parent::populateFromPostData($data); + } + + function ExtraOptions() { + $levels = array('1','2','3','4','5','6'); + $default = ($this->Level) ? $this->Level : 2; + $extraFields = new FieldSet( + new DropdownField("Fields[$this->ID][Level]", _t('EditableFormHeading.LEVEL', 'Select Heading Level'), $levels, $default) + ); + + if($this->readonly) { + $extraFields = $extraFields->makeReadonly(); + } + return $extraFields; + } + function getFormField() { - $labelField = new LabelField('FormHeadingLabel',$this->Title); + $labelField = new HeaderField('FormHeadingLabel',$this->Title, $this->Level); $labelField->addExtraClass('FormHeading'); + return $labelField; } function showInReports() { return false; } - - function showExtraOptions() { - return false; - } } ?> \ No newline at end of file diff --git a/code/editor/EditableTextField.php b/code/editor/EditableTextField.php index 65e1db6..e2c359f 100755 --- a/code/editor/EditableTextField.php +++ b/code/editor/EditableTextField.php @@ -94,5 +94,21 @@ class EditableTextField extends EditableFormField { return '
'; } } + + /** + * Return the validation information related to this field. This is + * interrupted as a JSON object for validate plugin and used in the + * PHP. + * + * @see http://docs.jquery.com/Plugins/Validation/Methods + * @return Array + */ + public function getValidation() { + $options = array(); + if($this->MinLength) $options['minlength'] = $this->MinLength; + if($this->MaxLength) $options['maxlength'] = $this->MinLength; + + return $options; + } } ?> \ No newline at end of file diff --git a/code/editor/SubmittedFileField.php b/code/submissions/SubmittedFileField.php similarity index 100% rename from code/editor/SubmittedFileField.php rename to code/submissions/SubmittedFileField.php diff --git a/code/editor/SubmittedForm.php b/code/submissions/SubmittedForm.php similarity index 100% rename from code/editor/SubmittedForm.php rename to code/submissions/SubmittedForm.php diff --git a/code/editor/SubmittedFormField.php b/code/submissions/SubmittedFormField.php similarity index 100% rename from code/editor/SubmittedFormField.php rename to code/submissions/SubmittedFormField.php diff --git a/code/editor/SubmittedFormReportField.php b/code/submissions/SubmittedFormReportField.php similarity index 100% rename from code/editor/SubmittedFormReportField.php rename to code/submissions/SubmittedFormReportField.php