Merged [47044]: Introduces modifications to Sapphire's form handling that allows it to ignore fields marked as Disabled when saving the contents of a form's fields to a DataObject.

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@60469 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Hayden Smith 2008-08-12 02:58:48 +00:00
parent 0bd9bc4ff8
commit 130ecfe5aa
23 changed files with 112 additions and 16 deletions

View File

@ -32,6 +32,12 @@ class DataObject extends ViewableData implements DataObjectInterface {
*/
protected $components;
/**
* DEPRECATED
*
* @var array List of fields and their old values before the last write.
*/
protected $lastWriteFields;
/**
* True if this DataObject has been destroyed.
@ -58,7 +64,6 @@ class DataObject extends ViewableData implements DataObjectInterface {
*/
static $api_access = false;
/**
* Construct a new DataObject.
*

View File

@ -5,6 +5,9 @@
* @subpackage fields-basic
*/
class CheckboxFieldDisabled extends CheckboxField {
protected $disabled = true;
/**
* Returns a single checkbox field - used by templates.
*/

View File

@ -148,6 +148,11 @@ class CheckboxSetField extends OptionsetField {
}
}
function performDisabledTransformation() {
$this->setDisabled(true);
return $this;
}
/**
* Makes a pretty readonly field
*/

View File

@ -148,10 +148,14 @@ JS;
* @subpackage fields-datetime
*/
class CompositeDateField_Disabled extends DateField {
protected $disabled = true;
function setValue($val) {
if($val && $val != "0000-00-00") $this->value = date('d/m/Y', strtotime($val));
else $this->value = _t('Form.DATENOTSET', "(No date set)");
}
function Field() {
if($this->value) {
$df = new Date($this->name);
@ -163,6 +167,7 @@ class CompositeDateField_Disabled extends DateField {
return "<span class=\"readonly\" id=\"" . $this->id() . "\">$val</span>";
}
function Type() {
return "date_disabled readonly";
}

View File

@ -100,11 +100,16 @@ class CompositeField extends FormField {
* Add all of the non-composite fields contained within this field to the list.
* Sequentialisation is used when connecting the form to its data source
*/
public function collateDataFields(&$list) {
public function collateDataFields(&$list, $saveableOnly = false) {
foreach($this->children as $field) {
if(is_object($field)) {
if($field->isComposite()) $field->collateDataFields($list);
if($field->hasData()) {
if($field->isComposite()) $field->collateDataFields($list, $saveableOnly);
if($saveableOnly) {
$isIncluded = ($field->hasData() && !$field->isReadonly() && !$field->isDisabled());
} else {
$isIncluded = ($field->hasData());
}
if($isIncluded) {
$name = $field->Name();
if($name) {
$formName = (isset($this->form)) ? $this->form->FormName() : '(unknown form)';

View File

@ -30,6 +30,7 @@ class DateField extends TextField {
function performReadonlyTransformation() {
$field = new DateField_Disabled($this->name, $this->title, $this->value);
$field->setForm($this->form);
$field->readonly = true;
return $field;
}
@ -90,6 +91,8 @@ JS;
*/
class DateField_Disabled extends DateField {
protected $disabled = true;
function setValue($val) {
if($val && $val != "0000-00-00") $this->value = date('d/m/Y', strtotime($val));
else $this->value = '('._t('DateField.NODATESET', 'No date set').')';

View File

@ -68,6 +68,7 @@ class DropdownField extends FormField {
$field = new LookupField($this->name, $this->title, $this->source);
$field->setValue($this->value);
$field->setForm($this->form);
$field->setReadonly(true);
return $field;
}

View File

@ -15,6 +15,7 @@ class FieldSet extends DataObjectSet {
* @var array
*/
protected $sequentialSet;
protected $sequentialSaveableSet;
/**
* Return a sequential set of all fields that have data. This excludes wrapper composite fields
@ -24,12 +25,22 @@ class FieldSet extends DataObjectSet {
if(!$this->sequentialSet) $this->collateDataFields($this->sequentialSet);
return $this->sequentialSet;
}
protected function collateDataFields(&$list) {
public function saveableFields() {
if(!$this->sequentialSaveableSet) $this->collateDataFields($this->sequentialSaveableSet, true);
return $this->sequentialSaveableSet;
}
protected function collateDataFields(&$list, $saveableOnly = false) {
foreach($this as $field) {
if($field->isComposite()) $field->collateDataFields($list, $saveableOnly);
if($field->isComposite()) $field->collateDataFields($list);
if($field->hasData()) {
if($saveableOnly) {
$isIncluded = ($field->hasData() && !$field->isReadonly() && !$field->isDisabled());
} else {
$isIncluded = ($field->hasData());
}
if($isIncluded) {
$name = $field->Name();
if(isset($list[$name])) {
$errSuffix = "";

View File

@ -739,7 +739,7 @@ class Form extends RequestHandlingData {
* It will make use of setCastedField() to do this.
*/
function saveInto(DataObjectInterface $dataObject) {
$dataFields = $this->fields->dataFields();
$dataFields = $this->fields->saveableFields();
$lastField = null;
if($dataFields) foreach($dataFields as $field) {

View File

@ -69,6 +69,7 @@ class FormAction extends FormField {
* Globally disabled buttons would break the CMS.
*/
function performReadonlyTransformation() {
$this->setDisabled(true);
return $this;
}

View File

@ -42,6 +42,16 @@ class FormField extends RequestHandlingData {
*/
protected $tabIndex;
/**
* @var $readonly boolean
*/
protected $readonly = false;
/**
* @var $disabled boolean
*/
protected $disabled = false;
/**
* Create a new field.
* @param name The internal field name, passed to forms.
@ -352,8 +362,36 @@ HTML;
*/
function hasData() { return true; }
/**
* @return boolean
*/
function isReadonly() {
return !in_array($this->class, array("ReadonlyField","FormField","LookupField"));
return $this->readonly;
}
/**
* Sets readonly-flag on form-field. Please use performReadonlyTransformation()
* to actually transform this instance.
* @param $bool boolean Setting "false" has no effect on the field-state.
*/
function setReadonly($bool) {
$this->readonly = $bool;
}
/**
* @return boolean
*/
function isDisabled() {
return $this->disabled;
}
/**
* Sets disabed-flag on form-field. Please use performDisabledTransformation()
* to actually transform this instance.
* @param $bool boolean Setting "false" has no effect on the field-state.
*/
function setDisabled($bool) {
$this->disabled = $bool;
}
/**

View File

@ -16,6 +16,7 @@ class HiddenField extends FormField {
return $this->Field();
}
function performReadonlyTransformation() {
$this->setReadonly(true);
return $this;
}

View File

@ -53,6 +53,9 @@ class InlineFormAction extends FormField {
* @subpackage actions
*/
class InlineFormAction_ReadOnly extends FormField {
protected $readonly = true;
function Field() {
return "<input type=\"submit\" name=\"action_{$this->name}\" value=\"{$this->title}\" id=\"{$this->id()}\" disabled=\"disabled\" class=\"action$extraClass\" />";
}

View File

@ -29,6 +29,7 @@ class LiteralField extends DatalessField {
}
function performReadonlyTransformation() {
$this->setReadonly(true);
return $this;
}
}

View File

@ -7,6 +7,8 @@
*/
class LookupField extends DropdownField {
protected $readonly = true;
/**
* Returns a readonly span containing the correct value.
*/
@ -40,9 +42,11 @@ class LookupField extends DropdownField {
"\">$mappedValue</span><input type=\"hidden\" name=\"" . $this->name .
"\" value=\"" . $valforInput . "\" />";
}
function performReadonlyTransformation() {
return $this;
}
function Type() {
return "lookup readonly";
}

View File

@ -59,6 +59,7 @@ class OptionsetField extends DropdownField {
$items = $this->source;
$field = new LookupField($this->name,$this->title ? $this->title : "" ,$items,$this->value);
$field->setForm($this->form);
$field->setReadonly(true);
return $field;
}

View File

@ -44,6 +44,7 @@ class PasswordField extends FormField {
$field = new ReadonlyField($this->name, $this->title ? $this->title : '', $stars);
$field->setForm($this->form);
$field->setReadonly(true);
return $field;
}
}

View File

@ -6,6 +6,8 @@
*/
class ReadonlyField extends FormField {
protected $readonly = true;
function performReadonlyTransformation() {
return $this;
}

View File

@ -53,6 +53,7 @@ class SimpleImageField extends FileField {
function performReadonlyTransformation() {
$field = new SimpleImageField_Disabled($this->name, $this->title, $this->value);
$field->setForm($this->form);
$field->setReadonly(true);
return $field;
}
}

View File

@ -311,11 +311,13 @@ class TableField extends TableListField {
function performReadonlyTransformation() {
$this->permissions = array('show');
$this->setReadonly(true);
return $this;
}
function performDisabledTransformation() {
$this->permissions = array('show');
$this->setDisabled(true);
return $this;
}

View File

@ -488,8 +488,8 @@ JS
function performReadonlyTransformation() {
$this->setShowPagination(false);
$this->setPermissions(array('show'));
$this->IsReadOnly = true;
$this->addExtraClass( 'readonly' );
$this->setReadonly(true);
return $this;
}
@ -654,11 +654,11 @@ JS
* Template accessor for Permissions
*/
function Can($mode) {
if($mode == 'add' && $this->IsReadOnly) {
if($mode == 'add' && $this->isReadonly()) {
return false;
} else if($mode == 'delete' && $this->IsReadOnly) {
} else if($mode == 'delete' && $this->isReadonly()) {
return false;
} else if($mode == 'edit' && $this->IsReadOnly) {
} else if($mode == 'edit' && $this->isReadonly()) {
return false;
} else {
return (in_array($mode, $this->permissions));
@ -1207,7 +1207,7 @@ class TableListField_Item extends ViewableData {
function MarkingCheckbox() {
$name = $this->parent->Name() . '[]';
if($this->parent->IsReadOnly || !$this->Can('edit'))
if($this->parent->isReadonly())
return "<input class=\"checkbox\" type=\"checkbox\" name=\"$name\" value=\"{$this->item->ID}\" disabled=\"disabled\" />";
else
return "<input class=\"checkbox\" type=\"checkbox\" name=\"$name\" value=\"{$this->item->ID}\" />";
@ -1234,7 +1234,7 @@ class TableListField_Item extends ViewableData {
/**
* Legacy: Please use permissions instead
*/
function IsReadOnly() {
function isReadonly() {
return $this->parent->Can('delete');
}

View File

@ -62,6 +62,8 @@ class TimeField extends TextField {
*/
class TimeField_Readonly extends TimeField {
protected $readonly = true;
function Field() {
if( $this->value )
$val = $this->attrValue();

View File

@ -132,6 +132,7 @@ HTML;
$field = new LookupField($this->name, $this->title, $source);
$field->setValue($this->value);
$field->setForm($this->form);
$field->setReadonly(true);
return $field;
}