implement validation to tablefield,

fixed bug on validation of datefield, emailfield, numericefield.
make CMS validation enabled.

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@40755 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Normann Lou 2007-08-23 05:47:54 +00:00
parent 716d406754
commit 3bc0eaafbb
12 changed files with 219 additions and 41 deletions

View File

@ -119,12 +119,22 @@ class Controller extends ViewableData {
if($form){
$form->loadDataFrom($this->requestParams, true);
// disregard validation if a single field is called
if(!isset($_REQUEST['action_callfieldmethod'])) {
$valid = $form->beforeProcessing();
if(!$valid) {
$this->popCurrent();
return $this->response;
}
}else{
$fieldcaller = $form->dataFieldByName($requestParams['fieldName']);
if(is_a($fieldcaller, "TableListField")){
if($fieldcaller->hasMethod('php')){
$valid = $fieldcaller->php($requestParams);
if(!$valid) exit();
}
}
}
// If the action wasnt' set, choose the default on the form.

View File

@ -202,6 +202,18 @@ class DataObject extends Controller {
return ($this->record && $this->record['ID'] > 0);
}
public function isEmpty(){
$isEmpty = true;
if($this->record){
foreach($this->record as $k=>$v){
if($k != "ID"){
$isEmpty = $isEmpty && !$v;
}
}
}
return $isEmpty;
}
/**
* Get the user friendly singular name of this DataObject.
* If the name is not defined (by redefining $singular_name in the subclass),

View File

@ -164,6 +164,16 @@ class CompositeField extends FormField {
$result .= "</ul>";
return $result;
}
function validate($validator){
$valid = true;
foreach($this->children as $idx => $child){
$valid = ($child->validate($validator) && $valid);
}
return $valid;
}
}
?>

View File

@ -20,9 +20,9 @@ class DateField extends TextField {
return $field;
}
function jsValidation()
function jsValidation($formID = null)
{
$formID = $this->form->FormName();
if(!$formID)$formID = $this->form->FormName();
$jsFunc =<<<JS
Behaviour.register({
@ -42,10 +42,18 @@ Behaviour.register({
JS;
Requirements :: customScript($jsFunc, 'func_validateDate');
return "\$('$formID').validateDate('$this->name');";
// return "\$('$formID').validateDate('$this->name');";
return <<<JS
if(typeof fromAnOnBlur != 'undefined'){
if(fromAnOnBlur.name == '$this->name')
$('$formID').validateDate('$this->name');
}else{
$('$formID').validateDate('$this->name');
}
JS;
}
function validate()
function validate($validator)
{
if(!empty ($this->value) && !preg_match('/^[0-9]{1,2}\/[0-9]{1,2}\/[0-90-9]{2,4}$/', $this->value))
{

View File

@ -28,7 +28,15 @@ JS;
Requirements::customScript($jsFunc, 'func_validateEmailField');
return "\$('$formID').validateEmailField('$this->name');";
//return "\$('$formID').validateEmailField('$this->name');";
return <<<JS
if(typeof fromAnOnBlur != 'undefined'){
if(fromAnOnBlur.name == '$this->name')
$('$formID').validateEmailField('$this->name');
}else{
$('$formID').validateEmailField('$this->name');
}
JS;
}
function validate($validator){

View File

@ -317,6 +317,10 @@ class Form extends ViewableData {
return $this->class . '_' . str_replace('.','',$this->name);
}
function PureName(){
return $this->name;
}
/**
* Returns the field referenced by $_GET[fieldName].
* Used for embedding entire extra helper forms inside complex field types (such as ComplexTableField)

View File

@ -15,7 +15,7 @@ Behaviour.register({
el = _CURRENT_FORM.elements[fieldName];
if(!el || !el.value) return true;
if(el.value.match(/^([0-9]*$)/)) {
if(el.value.match(/^([0-9]+(\.[0-9]+)?$)/)) {
return true;
} else {
validationError(el, "'" + el.value + "' is not a number, only numbers can be accepted for this field","validation");
@ -28,7 +28,15 @@ JS;
Requirements::customScript($jsFunc, 'func_validateNumericField');
return "\$('$formID').validateNumericField('$this->name');";
//return "\$('$formID').validateNumericField('$this->name');";
return <<<JS
if(typeof fromAnOnBlur != 'undefined'){
if(fromAnOnBlur.name == '$this->name')
$('$formID').validateNumericField('$this->name');
}else{
$('$formID').validateNumericField('$this->name');
}
JS;
}
/** PHP Validation **/

View File

@ -64,7 +64,15 @@ class RequiredFields extends Validator{
if($this->required) {
foreach($this->required as $field) {
if($fields->dataFieldByName($field)) {
$js .= "\t\t\t\t\trequire('$field', false, $useLabels);\n";
//$js .= "\t\t\t\t\trequire('$field', false, $useLabels);\n";
$js .= <<<JS
if(typeof fromAnOnBlur != 'undefined'){\n
if(fromAnOnBlur.name == '$field')\n
require(fromAnOnBlur);\n
}else{
require('$field');
}
JS;
}
}
}

View File

@ -196,6 +196,7 @@ class TableField extends TableListField {
{
// TODO Needs to be attached to a form existing in the DOM-tree
$form = new Form($this, 'EditForm', $fieldset, new FieldSet());
$form->loadDataFrom($item);
$row = new TableField_Item($item, $this, $form, $this->fieldTypes);
$fields = array_merge($fields, $row->Fields()->toArray());
}
@ -205,6 +206,42 @@ class TableField extends TableListField {
return $fields;
}
function SubmittedFieldSet(&$sourceItems){
$fields = array ();
if($rows = $_POST[$this->name]){
if(count($rows)){
foreach($rows as $idx => $row){
if($idx == 'new'){
$newitems = ArrayLib::invert($row);
if(count($newitems)){
$sourceItems = new DataObjectSet();
foreach($newitems as $k => $newitem){
$fieldset = $this->FieldSetForRow();
if($fieldset){
$newitem[ID] = "new".$k;
foreach($newitem as $k => $v){
if(array_key_exists($k, $this->extraData)){
unset($newitem[$k]);
}
}
$sourceItem = new DataObject($newitem);
if(!$sourceItem->isEmpty()){
$sourceItems->push($sourceItem);
$form = new Form($this, "EditForm", $fieldset, new FieldSet());
$form->loadDataFrom($sourceItem);
$item = new TableField_Item($sourceItem, $this, $form, $this->fieldTypes);
$fields = array_merge($fields, $item->Fields()->toArray());
}
}
}
}
}
}
}
}
return $fields;
}
/**
* @return array
*/
@ -460,17 +497,33 @@ class TableField extends TableListField {
$js = "";
$fields = $this->FieldSet();
$fields = new FieldSet($fields);
// TODO doesn't automatically update validation when adding a row
foreach($fields as $field) {
//if the field type has some special specific specification for validation of itself
$js .= $field->jsValidation();
$js .= $field->jsValidation($this->form->class."_".$this->form->PureName());
}
// TODO Implement custom requiredFields
if($this->requiredFields) {
$items = $this->sourceItems();
if($this->requiredFields&&$items->count()) {
foreach ($this->requiredFields as $field) {
if($fields->dataFieldByName($field)) {
/*if($fields->dataFieldByName($field)) {
$js .= "\t\t\t\t\trequire('$field');\n";
}*/
foreach($items as $item){
$cellName = $this->Name().'['.$item->ID.']['.$field.']';
$js .= "\n";
if($fields->dataFieldByName($cellName)) {
$js .= <<<JS
if(typeof fromAnOnBlur != 'undefined'){
if(fromAnOnBlur.name == '$cellName')
require(fromAnOnBlur);
}else{
require('$cellName');
}
JS;
}
}
}
}
@ -480,32 +533,49 @@ class TableField extends TableListField {
function php($data) {
$valid = true;
if($items = $this->sourceItems()) {
foreach($items as $item) {
// Load the data in to a temporary form (for correct field types)
$fieldset = $this->FieldSetForRow();
if ($fieldset)
{
$form = new Form(null, null, $fieldset, new FieldSet());
$row = new TableField_Item($item, $this, $form, $this->fieldTypes);
$fields = array_merge($fields, $row->Fields()->toArray());
}
}
}
$fields = new FieldSet($fields);
foreach($fields as $field) {
$valid = ($field->validate($this) && $valid);
}
if($this->requiredFields) {
foreach($this->requiredFields as $field) {
if($fields->dataFieldByName($field) && !$data[$field]) {
$this->validationError($field,'"' . strip_tags($field) . '" is required',"required");
}
}
}
if($data['methodName'] != 'delete'){
$fields = $this->FieldSet();
$fields = new FieldSet($fields);
}else{
return $valid;
}
}
function validate($validator){
$valid = true;
$fields = $this->SubmittedFieldSet($sourceItemsNew);
$fields = new FieldSet($fields);
foreach($fields as $field){
$valid = $field->validate($validator)&&$valid;
}
//debug::show($this->form->Message());
if($this->requiredFields&&$sourceItemsNew&&$sourceItemsNew->count()) {
foreach ($this->requiredFields as $field) {
foreach($sourceItemsNew as $item){
$cellName = $this->Name().'['.$item->ID.']['.$field.']';
$cName = $this->Name().'[new]['.$field.'][]';
if($fieldObj = $fields->dataFieldByName($cellName)) {
if(!trim($fieldObj->value)){
$title = $fieldObj->Title();
$errorMessage .= "In $this->name '$title' is required.<br />";
}
}
}
}
}
if($errorMessage){
$messageType .= "validation";
$message .= "<br />".$errorMessage;
$validator->validationError($this->name, $message, $messageType);
}
return $valid;
}
function setRequiredFields($fields) {
@ -634,7 +704,6 @@ class TableField_Item extends TableListField_Item {
$field = new $fieldType($combinedFieldName,$fieldTitle);
} else {
$field = eval("return new " . $fieldType . ";");
}
$field->setExtraClass('col'.$i);
$this->fields[] = $field;

View File

@ -39,6 +39,24 @@ abstract class Validator extends Object {
);
}
function showError(){
debug::show($this->errors);
}
function getCombinedError(){
if($this->errors) {
foreach($this->errors as $error){
$ret['message'] .= $error['message']."<br />";
$ret['messageType'] .= $error['messageType']."<br />";
}
return $ret;
}
}
function getError(){
return $this->errors;
}
function requireField($fieldName, $data) {
if(!$data[$fieldName]) $this->validationError($fieldName, "$fieldName is required", "required");
}

View File

@ -30,9 +30,17 @@ function findIndexOf(group,index){
}
function clearErrorMessage(holderDiv){
$$('span.message', holderDiv).each(function(el) {
Element.hide(el);
});
//merged by nlou 23/08/2007, r#40674
if(holderDiv.tagName == 'TD'){//for tablefield.
$$('span.message', holderDiv).each(function(el){
Element.hide(el);
}
);
}else{
$$('span.message', holderDiv.parentNode).each(function(el) {
Element.hide(el);
});
}
}
function clearAllErrorMessages(){
@ -75,6 +83,13 @@ function require(fieldName,cachedError) {
// Sets up radio and checkbox validation
if(el.type == 'checkbox' || el.type == 'radio' ){
var set = el.checked;
}//merged by nlou 23/08/2007, r#40674
else if(el.type == 'select-one'){
if(el.value == ''||el.value == '0'){
var set = '';
}else{
var set = el.value;
}
}else{
var set = el.value;
}
@ -168,6 +183,9 @@ function findParentLabel(el){
return findParentLabel(el.parentNode);
}
}
}//merged by nlou 23/08/2007, r#40674
else if(el.className.indexOf('tablecolumn') != -1){
return el.className.substring(0, el.className.indexOf('tablecolumn')-1);
}else{
return findParentLabel(el.parentNode);
}

View File

@ -1,5 +1,10 @@
<div id="$id" class="$Classes">
<% include TableListField_PageControls %>
<% if Message %>
<p id="{$id}_error" class="message $MessageType">$Message</p>
<% else %>
<p id="{$id}_error" class="message $MessageType" style="display: none"></p>
<% end_if %>
<table class="data">
<thead>
<tr>
@ -36,7 +41,7 @@
<% control Items %>
<tr id="record-$Parent.id-$ID" class="row<% if HighlightClasses %> $HighlightClasses<% end_if %>">
<% control Fields %>
<td class="$FieldClass $ExtraClass">$Field</td>
<td class="$FieldClass $ExtraClass $ClassName $Title tablecolumn">$Field</td>
<% end_control %>
<td style="display: none">$ExtraData</td>
<% if Can(delete) %><td width="18"><a class="deletelink" href="$DeleteLink" title="Delete this row"><img src="cms/images/delete.gif" alt="delete" /></a></td><% end_if %>