API CHANGE Removed CustomRequiredFields, please use custom validation instead

BUGFIX Ensure validators still used in ModelAdmin forms
This commit is contained in:
Sean Harvey 2012-03-09 12:45:18 +13:00
parent 7eddf4298f
commit c59c717d78
3 changed files with 28 additions and 133 deletions

View File

@ -392,17 +392,22 @@ class ModelAdmin_CollectionController extends Controller {
* @return Form
*/
public function SearchForm() {
$context = singleton($this->modelClass)->getDefaultSearchContext();
$SNG_model = singleton($this->modelClass);
$context = $SNG_model->getDefaultSearchContext();
$fields = $context->getSearchFields();
$columnSelectionField = $this->ColumnSelectionField();
$fields->push($columnSelectionField);
$validator = ($SNG_model->hasMethod('getCMSValidator')) ? $SNG_model->getCMSValidator() : new RequiredFields();
$clearAction = new ResetFormAction('clearsearch', _t('ModelAdmin.CLEAR_SEARCH','Clear Search'));
$form = new Form($this, "SearchForm",
$fields,
new FieldList(
new FormAction('search', _t('MemberTableField.SEARCH', 'Search')),
$clearAction = new ResetFormAction('clearsearch', _t('ModelAdmin.CLEAR_SEARCH','Clear Search'))
)
$clearAction
),
$validator
);
//$form->setFormAction(Controller::join_links($this->Link(), "search"));
$form->setFormMethod('get');
@ -420,24 +425,28 @@ class ModelAdmin_CollectionController extends Controller {
*/
public function CreateForm() {
$modelName = $this->modelClass;
$SNG_model = singleton($modelName);
if($this->hasMethod('alternatePermissionCheck')) {
if(!$this->alternatePermissionCheck()) return false;
} else {
if(!singleton($modelName)->canCreate(Member::currentUser())) return false;
if(!$SNG_model->canCreate(Member::currentUser())) return false;
}
$buttonLabel = sprintf(_t('ModelAdmin.CREATEBUTTON', "Create '%s'", PR_MEDIUM, "Create a new instance from a model class"), singleton($modelName)->i18n_singular_name());
$buttonLabel = sprintf(_t('ModelAdmin.CREATEBUTTON', "Create '%s'", PR_MEDIUM, "Create a new instance from a model class"), $SNG_model->i18n_singular_name());
$validator = ($SNG_model->hasMethod('getCMSValidator')) ? $SNG_model->getCMSValidator() : new RequiredFields();
$createButton = FormAction::create('add', $buttonLabel)->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'accept');
$form = new Form($this, "CreateForm",
new FieldList(),
new FieldList(
$createButton = FormAction::create('add', $buttonLabel)
->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'accept')
)
);
new FieldList(),
new FieldList($createButton),
$validator
);
$createButton->dontEscape = true;
$form->setHTMLID("Form_CreateForm_" . $this->modelClass);
return $form;
}
@ -793,9 +802,8 @@ class ModelAdmin_CollectionController extends Controller {
$fields = $newRecord->getCMSFields();
}
$validator = ($newRecord->hasMethod('getCMSValidator')) ? $newRecord->getCMSValidator() : null;
if(!$validator) $validator = new RequiredFields();
$validator = ($newRecord->hasMethod('getCMSValidator')) ? $newRecord->getCMSValidator() : new RequiredFields();
$actions = new FieldList (
FormAction::create("doCreate", _t('ModelAdmin.ADDBUTTON', "Add"))
->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'accept')

View File

@ -80,6 +80,11 @@ Built-in client-side form validation using behaviour.js has been removed, and is
Server-side validation remains. Developers are encouraged to use custom Javascript validation on their
forms if requiring client-side validation.
These classes/files have been removed:
Validator.js
CustomRequiredFields.php
These functions are now deprecated and will throw a notice if used:
Validator::set_javascript_validation_handler()

View File

@ -1,118 +0,0 @@
<?php
/**
* CustomRequiredFields allow you to create your own validation on forms, while still having the ability to have required fields (as used in [RequiredFields](http://api.silverstripe.org/current/sapphire/form/RequiredFields.html)).
*
* The constructor of CustomRequiredFields takes an array. Each array element is one of two things - either the name of a field that is required, or an array containing two items, 'js' and 'php'. These items are functions called to validate in javascript or php respectively.
*
* Some useful javascript:
* 1. _CURRENT_FORM is the current form
* 2. _CURRENT_FORM.elements is an array of the fields
* 3. validationError(element, message, type) will create a validation error
* 4. clearErrorMessage(element) will clear the validation error
* 5. require('FieldName') create a required field ($this->requireField('FieldName') is the php equivalent)
*
* An example for creating required fields only if payment type is CreditCard:
*
* <code>
* new CustomRequiredFields(
* array(
* "PaymentMethod",
* array(
* "js" => "
* for( var i = 0; i <= this.elements.PaymentMethod.length -1; i++){
* if(this.elements.PaymentMethod[i].value == 'CC' && this.elements.PaymentMethod[i].checked == true){
* require('CardHolderName');
* require('CreditCardNumber');
* require('DateExpiry');
* }
* }
*
* ",
* "php" => 'if($data[PaymentMethod] == "CC") {
* $this->requireField($field,"$field is required","required");
* $this->requireField("CardHolderName", $data);
* $this->requireField("CreditCardNumber", $data);
* $this->requireField("DateExpiry", $data);
* }',
* )
* )
* );
* </code>
*
* And example for confirming mobile number and email address:
*
* <code>
* $js = <<<JS
* if(_CURRENT_FORM.elements["MobileNumberConfirm"].value == _CURRENT_FORM.elements["MobileNumber"].value) {
* clearErrorMessage(_CURRENT_FORM.elements["MobileNumberConfirm"].parentNode);
* } else {
* validationError(_CURRENT_FORM.elements["MobileNumberConfirm"], "Mobile numbers do not match", "validation");
* }
* JS;
*
* $js2 = <<<JS2
* if(_CURRENT_FORM.elements["EmailConfirm"].value == _CURRENT_FORM.elements["Email"].value) {
* clearErrorMessage(_CURRENT_FORM.elements["EmailConfirm"].parentNode);
* } else {
* validationError(_CURRENT_FORM.elements["EmailConfirm"], "Email addresses do not match", "validation");
* }
* JS2;
*
* //create validator
* $validator=new CustomRequiredFields(array('FirstName', 'Surname', 'Email', 'MobileNumber', array('js' => $js, 'php' => 'return true;'), array('js' => $js2, 'php'=>'return true;')));
* </code>
*
* @package forms
* @subpackage validators
*/
class CustomRequiredFields extends RequiredFields{
protected $required;
/**
* Pass each field to be validated as a seperate argument
* @param $required array The list of required fields
*/
function __construct($required) {
$this->required = $required;
}
/**
* Creates the server side validation from form fields
* which is executed on form submission
*/
function php($data) {
$fields = $this->form->Fields();
$valid = true;
foreach($fields as $field) {
$valid = ($field->validate($this) && $valid);
}
if($this->required){
foreach($this->required as $key => $fieldName) {
if(is_string($fieldName)) $formField = $fields->dataFieldByName($fieldName);
if(is_array($fieldName) && isset($fieldName['php'])){
eval($fieldName['php']);
}else if($formField) {
// if an error is found, the form is returned.
if(!strlen($data[$fieldName]) || preg_match('/^\s*$/', $data[$fieldName])) {
$this->validationError(
$fieldName,
sprintf(_t('Form.FIELDISREQUIRED', "%s is required."),
$formField->Title()),
"required"
);
return false;
}
}
}
}
return $valid;
}
/**
* allows you too add more required fields to this object after construction.
*/
function appendRequiredFields($requiredFields){
$this->required = array_merge($this->required,$requiredFields->getRequired());
}
}