mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
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:
parent
716d406754
commit
3bc0eaafbb
@ -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.
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -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))
|
||||
{
|
||||
|
@ -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){
|
||||
|
@ -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)
|
||||
|
@ -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 **/
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 %>
|
||||
|
Loading…
Reference in New Issue
Block a user