mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #4125 from assertchris/clean-up-form-field
Clean up FormField
This commit is contained in:
commit
ebeea242fe
@ -1,18 +1,24 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a field in a form.
|
* Represents a field in a form.
|
||||||
*
|
*
|
||||||
* A FieldList contains a number of FormField objects which make up the whole of a form.
|
* A FieldList contains a number of FormField objects which make up the whole of a form.
|
||||||
* In addition to single fields, FormField objects can be "composite", for example, the {@link TabSet}
|
|
||||||
* field. Composite fields let us define complex forms without having to resort to custom HTML.
|
|
||||||
*
|
*
|
||||||
* <b>Subclassing</b>
|
* In addition to single fields, FormField objects can be "composite", for example, the
|
||||||
|
* {@link TabSet} field. Composite fields let us define complex forms without having to resort to
|
||||||
|
* custom HTML.
|
||||||
*
|
*
|
||||||
* Define a {@link dataValue()} method that returns a value suitable for inserting into a single database field.
|
* To subclass:
|
||||||
* For example, you might tidy up the format of a date or currency field.
|
*
|
||||||
* Define {@link saveInto()} to totally customise saving.
|
* Define a {@link dataValue()} method that returns a value suitable for inserting into a single
|
||||||
* For example, data might be saved to the filesystem instead of the data record,
|
* database field.
|
||||||
* or saved to a component of the data record instead of the data record itself.
|
*
|
||||||
|
* For example, you might tidy up the format of a date or currency field. Define {@link saveInto()}
|
||||||
|
* to totally customise saving.
|
||||||
|
*
|
||||||
|
* For example, data might be saved to the filesystem instead of the data record, or saved to a
|
||||||
|
* component of the data record instead of the data record itself.
|
||||||
*
|
*
|
||||||
* @package forms
|
* @package forms
|
||||||
* @subpackage core
|
* @subpackage core
|
||||||
@ -24,152 +30,243 @@ class FormField extends RequestHandler {
|
|||||||
*/
|
*/
|
||||||
protected $form;
|
protected $form;
|
||||||
|
|
||||||
protected $name, $title, $value ,$message, $messageType, $extraClass;
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var $description string Adds a "title"-attribute to the markup.
|
* @var null|string
|
||||||
|
*/
|
||||||
|
protected $title;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
protected $value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $messageType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $extraClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a title attribute to the markup.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*
|
||||||
* @todo Implement in all subclasses
|
* @todo Implement in all subclasses
|
||||||
*/
|
*/
|
||||||
protected $description;
|
protected $description;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var $extraClasses array Extra CSS-classes for the formfield-container
|
* Extra CSS classes for the FormField container.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $extraClasses;
|
protected $extraClasses;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
public $dontEscape;
|
public $dontEscape;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var $rightTitle string Used in SmallFieldHolder to force a right-aligned label, or in FieldHolder
|
* Right-aligned, contextual label for the field.
|
||||||
* to create contextual label.
|
*
|
||||||
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $rightTitle;
|
protected $rightTitle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var $leftTitle string Used in SmallFieldHolder() to force a left-aligned label with correct spacing.
|
* Left-aligned, contextual label for the field.
|
||||||
* Please use $title for FormFields rendered with FieldHolder().
|
*
|
||||||
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $leftTitle;
|
protected $leftTitle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores a reference to the FieldList that contains this object.
|
* Stores a reference to the FieldList that contains this object.
|
||||||
|
*
|
||||||
* @var FieldList
|
* @var FieldList
|
||||||
*/
|
*/
|
||||||
protected $containerFieldList;
|
protected $containerFieldList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var boolean
|
* @var bool
|
||||||
*/
|
*/
|
||||||
protected $readonly = false;
|
protected $readonly = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var boolean
|
* @var bool
|
||||||
*/
|
*/
|
||||||
protected $disabled = false;
|
protected $disabled = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string custom validation message for the Field
|
* Custom validation message for the field.
|
||||||
*/
|
|
||||||
protected $customValidationMessage = "";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Name of the template used to render this form field. If not set, then
|
|
||||||
* will look up the class ancestry for the first matching template where
|
|
||||||
* the template name equals the class name.
|
|
||||||
*
|
|
||||||
* To explicitly use a custom template or one named other than the form
|
|
||||||
* field see {@link setTemplate()}, {@link setFieldHolderTemplate()}
|
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected
|
protected $customValidationMessage = '';
|
||||||
$template,
|
|
||||||
$fieldHolderTemplate,
|
|
||||||
$smallFieldHolderTemplate;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array All attributes on the form field (not the field holder).
|
* Name of the template used to render this form field. If not set, then will look up the class
|
||||||
* Partially determined based on other instance properties, please use {@link getAttributes()}.
|
* ancestry for the first matching template where the template name equals the class name.
|
||||||
|
*
|
||||||
|
* To explicitly use a custom template or one named other than the form field see
|
||||||
|
* {@link setTemplate()}.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $template;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the template used to render this form field. If not set, then will look up the class
|
||||||
|
* ancestry for the first matching template where the template name equals the class name.
|
||||||
|
*
|
||||||
|
* To explicitly use a custom template or one named other than the form field see
|
||||||
|
* {@link setFieldHolderTemplate()}.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $fieldHolderTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $smallFieldHolderTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All attributes on the form field (not the field holder).
|
||||||
|
*
|
||||||
|
* Partially determined based on other instance properties.
|
||||||
|
*
|
||||||
|
* @see getAttributes()
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $attributes = array();
|
protected $attributes = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a fieldname and converts camelcase to spaced
|
* Takes a field name and converts camelcase to spaced words. Also resolves combined field
|
||||||
* words. Also resolves combined fieldnames with dot syntax
|
* names with dot syntax to spaced words.
|
||||||
* to spaced words.
|
|
||||||
*
|
*
|
||||||
* Examples:
|
* Examples:
|
||||||
|
*
|
||||||
* - 'TotalAmount' will return 'Total Amount'
|
* - 'TotalAmount' will return 'Total Amount'
|
||||||
* - 'Organisation.ZipCode' will return 'Organisation Zip Code'
|
* - 'Organisation.ZipCode' will return 'Organisation Zip Code'
|
||||||
*
|
*
|
||||||
* @param string $fieldName
|
* @param string $fieldName
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function name_to_label($fieldName) {
|
public static function name_to_label($fieldName) {
|
||||||
if(strpos($fieldName, '.') !== false) {
|
if(strpos($fieldName, '.') !== false) {
|
||||||
$parts = explode('.', $fieldName);
|
$parts = explode('.', $fieldName);
|
||||||
$label = $parts[count($parts)-2] . ' ' . $parts[count($parts)-1];
|
|
||||||
|
$label = $parts[count($parts) - 2] . ' ' . $parts[count($parts) - 1];
|
||||||
} else {
|
} else {
|
||||||
$label = $fieldName;
|
$label = $fieldName;
|
||||||
}
|
}
|
||||||
$label = preg_replace("/([a-z]+)([A-Z])/","$1 $2", $label);
|
|
||||||
|
|
||||||
return $label;
|
return preg_replace('/([a-z]+)([A-Z])/', '$1 $2', $label);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct and return HTML tag.
|
* Construct and return HTML tag.
|
||||||
|
*
|
||||||
|
* @param string $tag
|
||||||
|
* @param array $attributes
|
||||||
|
* @param null|string $content
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function create_tag($tag, $attributes, $content = null) {
|
public static function create_tag($tag, $attributes, $content = null) {
|
||||||
$preparedAttributes = '';
|
$preparedAttributes = '';
|
||||||
foreach($attributes as $k => $v) {
|
|
||||||
// Note: as indicated by the $k == value item here; the decisions over what to include in the attributes
|
foreach($attributes as $attributeKey => $attributeValue) {
|
||||||
// can sometimes get finicky
|
if(!empty($attributeValue) || $attributeValue === '0' || ($attributeKey == 'value' && $attributeValue !== null)) {
|
||||||
if(!empty($v) || $v === '0' || ($k == 'value' && $v !== null) ) {
|
$preparedAttributes .= sprintf(
|
||||||
$preparedAttributes .= " $k=\"" . Convert::raw2att($v) . "\"";
|
' %s="%s"', $attributeKey, Convert::raw2att($attributeValue)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($content || $tag != 'input') return "<$tag$preparedAttributes>$content</$tag>";
|
if($content || $tag != 'input') {
|
||||||
else return "<$tag$preparedAttributes />";
|
return sprintf(
|
||||||
|
'<%s%s>%s</%s>', $tag, $preparedAttributes, $content, $tag
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
'<%s%s />', $tag, $preparedAttributes
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new field.
|
* Creates a new field.
|
||||||
*
|
*
|
||||||
* @param string $name The internal field name, passed to forms.
|
* @param string $name The internal field name, passed to forms.
|
||||||
* @param string $title The human-readable field label.
|
* @param null|string $title The human-readable field label.
|
||||||
* @param mixed $value The value of the field.
|
* @param mixed $value The value of the field.
|
||||||
*/
|
*/
|
||||||
public function __construct($name, $title = null, $value = null) {
|
public function __construct($name, $title = null, $value = null) {
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->title = ($title === null) ? self::name_to_label($name) : $title;
|
|
||||||
|
|
||||||
if($value !== NULL) $this->setValue($value);
|
if($title === null) {
|
||||||
|
$this->title = self::name_to_label($name);
|
||||||
|
} else {
|
||||||
|
$this->title = $title;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($value !== null) {
|
||||||
|
$this->setValue($value);
|
||||||
|
}
|
||||||
|
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a Link to this field
|
* Return a Link to this field.
|
||||||
|
*
|
||||||
|
* @param null|string $action
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function Link($action = null) {
|
public function Link($action = null) {
|
||||||
return Controller::join_links($this->form->FormAction(), 'field/' . $this->name, $action);
|
return Controller::join_links($this->form->FormAction(), 'field/' . $this->name, $action);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the HTML ID of the field - used in the template by label tags.
|
* Returns the HTML ID of the field.
|
||||||
* The ID is generated as FormName_FieldName. All Field functions should ensure
|
*
|
||||||
* that this ID is included in the field.
|
* The ID is generated as FormName_FieldName. All Field functions should ensure that this ID is
|
||||||
|
* included in the field.
|
||||||
*/
|
*/
|
||||||
public function ID() {
|
public function ID() {
|
||||||
$name = preg_replace('/(^-)|(-$)/', '', preg_replace('/[^A-Za-z0-9_-]+/', '-', $this->name));
|
$name = $this->name;
|
||||||
if($this->form) return $this->form->FormName() . '_' . $name;
|
$name = preg_replace('/[^A-Za-z0-9_-]+/', '-', $name);
|
||||||
else return $name;
|
$name = preg_replace('/(^-)|(-$)/', '', $name);
|
||||||
|
|
||||||
|
if($this->form) {
|
||||||
|
return $this->form->FormName() . '_' . $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the field name - used by templates.
|
* Returns the field name.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@ -179,6 +276,7 @@ class FormField extends RequestHandler {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the field message, used by form validation.
|
* Returns the field message, used by form validation.
|
||||||
|
*
|
||||||
* Use {@link setError()} to set this property.
|
* Use {@link setError()} to set this property.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
@ -188,9 +286,10 @@ class FormField extends RequestHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the field message type, used by form validation.
|
* Returns the field message type.
|
||||||
* Arbitrary value which is mostly used for CSS classes
|
*
|
||||||
* in the rendered HTML, e.g. "required".
|
* Arbitrary value which is mostly used for CSS classes in the rendered HTML, e.g "required".
|
||||||
|
*
|
||||||
* Use {@link setError()} to set this property.
|
* Use {@link setError()} to set this property.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
@ -200,7 +299,9 @@ class FormField extends RequestHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the field value - used by templates.
|
* Returns the field value.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function Value() {
|
public function Value() {
|
||||||
return $this->value;
|
return $this->value;
|
||||||
@ -208,9 +309,8 @@ class FormField extends RequestHandler {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to save this form field into the given data object.
|
* Method to save this form field into the given data object.
|
||||||
* By default, makes use of $this->dataValue()
|
|
||||||
*
|
*
|
||||||
* @param DataObjectInterface $record DataObject to save data into
|
* @param DataObjectInterface $record
|
||||||
*/
|
*/
|
||||||
public function saveInto(DataObjectInterface $record) {
|
public function saveInto(DataObjectInterface $record) {
|
||||||
if($this->name) {
|
if($this->name) {
|
||||||
@ -219,90 +319,117 @@ class FormField extends RequestHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the field value suitable for insertion into the data object
|
* Returns the field value suitable for insertion into the data object.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function dataValue() {
|
public function dataValue() {
|
||||||
return $this->value;
|
return $this->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the field label - used by templates.
|
* Returns the field label.
|
||||||
*/
|
*/
|
||||||
public function Title() {
|
public function Title() {
|
||||||
return $this->title;
|
return $this->title;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setTitle($val) {
|
/**
|
||||||
$this->title = $val;
|
* @param string $title
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setTitle($title) {
|
||||||
|
$this->title = $title;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the contextual label than can be used for additional field description.
|
* @return string
|
||||||
* Can be shown to the right or under the field in question.
|
|
||||||
*
|
|
||||||
* @return string Contextual label text.
|
|
||||||
*/
|
*/
|
||||||
public function RightTitle() {
|
public function RightTitle() {
|
||||||
return $this->rightTitle;
|
return $this->rightTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the contextual label.
|
* @param string $rightTitle
|
||||||
*
|
*
|
||||||
* @param $val string Text to set on the label.
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setRightTitle($val) {
|
public function setRightTitle($rightTitle) {
|
||||||
$this->rightTitle = $val;
|
$this->rightTitle = $rightTitle;
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function LeftTitle() {
|
|
||||||
return $this->leftTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setLeftTitle($val) {
|
|
||||||
$this->leftTitle = $val;
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiles all CSS-classes. Optionally includes a "nolabel"-class
|
* @return string
|
||||||
* if no title was set on the formfield.
|
*/
|
||||||
* Uses {@link Message()} and {@link MessageType()} to add validatoin
|
public function LeftTitle() {
|
||||||
* error classes which can be used to style the contained tags.
|
return $this->leftTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $leftTitle
|
||||||
*
|
*
|
||||||
* @return string CSS-classnames
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setLeftTitle($leftTitle) {
|
||||||
|
$this->leftTitle = $leftTitle;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiles all CSS-classes. Optionally includes a "nolabel" class if no title was set on the
|
||||||
|
* FormField.
|
||||||
|
*
|
||||||
|
* Uses {@link Message()} and {@link MessageType()} to add validation error classes which can
|
||||||
|
* be used to style the contained tags.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function extraClass() {
|
public function extraClass() {
|
||||||
$classes = array();
|
$classes = array();
|
||||||
|
|
||||||
$classes[] = $this->Type();
|
$classes[] = $this->Type();
|
||||||
|
|
||||||
if($this->extraClasses) $classes = array_merge($classes, array_values($this->extraClasses));
|
if($this->extraClasses) {
|
||||||
|
$classes = array_merge(
|
||||||
|
$classes,
|
||||||
|
array_values($this->extraClasses)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Allow customization of label and field tag positioning
|
if(!$this->Title()) {
|
||||||
if(!$this->Title()) $classes[] = "nolabel";
|
$classes[] = 'nolabel';
|
||||||
|
}
|
||||||
|
|
||||||
// Allow custom styling of any element in the container based
|
// Allow custom styling of any element in the container based on validation errors,
|
||||||
// on validation errors, e.g. red borders on input tags.
|
// e.g. red borders on input tags.
|
||||||
// CSS-Class needs to be different from the one rendered
|
//
|
||||||
// through {@link FieldHolder()}
|
// CSS class needs to be different from the one rendered through {@link FieldHolder()}.
|
||||||
if($this->Message()) $classes[] .= "holder-" . $this->MessageType();
|
if($this->Message()) {
|
||||||
|
$classes[] .= 'holder-' . $this->MessageType();
|
||||||
|
}
|
||||||
|
|
||||||
return implode(' ', $classes);
|
return implode(' ', $classes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add one or more CSS-classes to the formfield-container. Multiple class
|
* Add one or more CSS-classes to the FormField container.
|
||||||
* names should be space delimited.
|
*
|
||||||
|
* Multiple class names should be space delimited.
|
||||||
*
|
*
|
||||||
* @param string $class
|
* @param string $class
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function addExtraClass($class) {
|
public function addExtraClass($class) {
|
||||||
$classes = preg_split('/\s+/', $class);
|
$classes = preg_split('/\s+/', $class);
|
||||||
|
|
||||||
foreach ($classes as $class) {
|
foreach($classes as $class) {
|
||||||
$this->extraClasses[$class] = $class;
|
$this->extraClasses[$class] = $class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,14 +437,16 @@ class FormField extends RequestHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove one or more CSS-classes from the formfield-container.
|
* Remove one or more CSS-classes from the FormField container.
|
||||||
*
|
*
|
||||||
* @param string $class
|
* @param string $class
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function removeExtraClass($class) {
|
public function removeExtraClass($class) {
|
||||||
$classes = preg_split('/\s+/', $class);
|
$classes = preg_split('/\s+/', $class);
|
||||||
|
|
||||||
foreach ($classes as $class) {
|
foreach($classes as $class) {
|
||||||
unset($this->extraClasses[$class]);
|
unset($this->extraClasses[$class]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,41 +456,50 @@ class FormField extends RequestHandler {
|
|||||||
/**
|
/**
|
||||||
* Set an HTML attribute on the field element, mostly an <input> tag.
|
* Set an HTML attribute on the field element, mostly an <input> tag.
|
||||||
*
|
*
|
||||||
* Some attributes are best set through more specialized methods, to avoid interfering with built-in behaviour:
|
* Some attributes are best set through more specialized methods, to avoid interfering with
|
||||||
|
* built-in behaviour:
|
||||||
|
*
|
||||||
* - 'class': {@link addExtraClass()}
|
* - 'class': {@link addExtraClass()}
|
||||||
* - 'title': {@link setDescription()}
|
* - 'title': {@link setDescription()}
|
||||||
* - 'value': {@link setValue}
|
* - 'value': {@link setValue}
|
||||||
* - 'name': {@link setName}
|
* - 'name': {@link setName}
|
||||||
*
|
*
|
||||||
* CAUTION Doesn't work on most fields which are composed of more than one HTML form field:
|
* Caution: this doesn't work on most fields which are composed of more than one HTML form
|
||||||
* AjaxUniqueTextField, CheckboxSetField, ComplexTableField, CompositeField, ConfirmedPasswordField,
|
* field.
|
||||||
* CountryDropdownField, CreditCardField, CurrencyField, DateField, DatetimeField, FieldGroup, GridField,
|
|
||||||
* HtmlEditorField, ImageField, ImageFormAction, InlineFormAction, ListBoxField, etc.
|
|
||||||
*
|
*
|
||||||
* @param string
|
* @param string $name
|
||||||
* @param string
|
* @param string $value
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setAttribute($name, $value) {
|
public function setAttribute($name, $value) {
|
||||||
$this->attributes[$name] = $value;
|
$this->attributes[$name] = $value;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an HTML attribute defined by the field, or added through {@link setAttribute()}.
|
* Get an HTML attribute defined by the field, or added through {@link setAttribute()}.
|
||||||
* Caution: Doesn't work on all fields, see {@link setAttribute()}.
|
|
||||||
*
|
*
|
||||||
* @return string
|
* Caution: this doesn't work on all fields, see {@link setAttribute()}.
|
||||||
|
*
|
||||||
|
* @return null|string
|
||||||
*/
|
*/
|
||||||
public function getAttribute($name) {
|
public function getAttribute($name) {
|
||||||
$attrs = $this->getAttributes();
|
$attributes = $this->getAttributes();
|
||||||
if(isset($attrs[$name])) return $attrs[$name];
|
|
||||||
|
if(isset($attributes[$name])) {
|
||||||
|
return $attributes[$name];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getAttributes() {
|
public function getAttributes() {
|
||||||
$attrs = array(
|
$attributes = array(
|
||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
'name' => $this->getName(),
|
'name' => $this->getName(),
|
||||||
'value' => $this->Value(),
|
'value' => $this->Value(),
|
||||||
@ -371,49 +509,73 @@ class FormField extends RequestHandler {
|
|||||||
'readonly' => $this->isReadonly()
|
'readonly' => $this->isReadonly()
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($this->Required()) {
|
if($this->Required()) {
|
||||||
$attrs['required'] = 'required';
|
$attributes['required'] = 'required';
|
||||||
$attrs['aria-required'] = 'true';
|
$attributes['aria-required'] = 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
return array_merge($attrs, $this->attributes);
|
return array_merge($attributes, $this->attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Array Custom attributes to process. Falls back to {@link getAttributes()}.
|
* Custom attributes to process. Falls back to {@link getAttributes()}.
|
||||||
* If at least one argument is passed as a string, all arguments act as excludes by name.
|
*
|
||||||
* @return string HTML attributes, ready for insertion into an HTML tag
|
* If at least one argument is passed as a string, all arguments act as excludes, by name.
|
||||||
|
*
|
||||||
|
* @param array $attributes
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getAttributesHTML($attrs = null) {
|
public function getAttributesHTML($attributes = null) {
|
||||||
$exclude = (is_string($attrs)) ? func_get_args() : null;
|
$exclude = null;
|
||||||
|
|
||||||
if(!$attrs || is_string($attrs)) $attrs = $this->getAttributes();
|
if(is_string($attributes)) {
|
||||||
|
$exclude = func_get_args();
|
||||||
|
}
|
||||||
|
|
||||||
// Remove empty
|
if(!$attributes || is_string($attributes)) {
|
||||||
$attrs = array_filter((array)$attrs, function($v) {
|
$attributes = $this->getAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
|
$attributes = (array) $attributes;
|
||||||
|
|
||||||
|
$attributes = array_filter($attributes, function ($v) {
|
||||||
return ($v || $v === 0 || $v === '0');
|
return ($v || $v === 0 || $v === '0');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove excluded
|
if($exclude) {
|
||||||
if($exclude) $attrs = array_diff_key($attrs, array_flip($exclude));
|
$attributes = array_diff_key(
|
||||||
|
$attributes,
|
||||||
|
array_flip($exclude)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Create markkup
|
|
||||||
$parts = array();
|
$parts = array();
|
||||||
foreach($attrs as $name => $value) {
|
|
||||||
$parts[] = ($value === true) ? "{$name}=\"{$name}\"" : "{$name}=\"" . Convert::raw2att($value) . "\"";
|
foreach($attributes as $name => $value) {
|
||||||
|
if($value === true) {
|
||||||
|
$parts[] = sprintf('%s="%s"', $name, $name);
|
||||||
|
} else {
|
||||||
|
$parts[] = sprintf('%s="%s"', $name, Convert::raw2att($value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return implode(' ', $parts);
|
return implode(' ', $parts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a version of a title suitable for insertion into an HTML attribute
|
* Returns a version of a title suitable for insertion into an HTML attribute.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function attrTitle() {
|
public function attrTitle() {
|
||||||
return Convert::raw2att($this->title);
|
return Convert::raw2att($this->title);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a version of a title suitable for insertion into an HTML attribute
|
* Returns a version of a title suitable for insertion into an HTML attribute.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function attrValue() {
|
public function attrValue() {
|
||||||
return Convert::raw2att($this->value);
|
return Convert::raw2att($this->value);
|
||||||
@ -423,29 +585,41 @@ class FormField extends RequestHandler {
|
|||||||
* Set the field value.
|
* Set the field value.
|
||||||
*
|
*
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @param mixed $data Optional data source passed in by {@see Form::loadDataFrom}
|
* @param null|array|DataObject $data {@see Form::loadDataFrom}
|
||||||
* @return FormField Self reference
|
*
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setValue($value) {
|
public function setValue($value) {
|
||||||
$this->value = $value;
|
$this->value = $value;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the field name
|
* Set the field name.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setName($name) {
|
public function setName($name) {
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the container form.
|
* Set the container form.
|
||||||
* This is called whenever you create a new form and put fields inside it, so that you don't
|
*
|
||||||
* have to worry about linking the two.
|
* This is called automatically when fields are added to forms.
|
||||||
|
*
|
||||||
|
* @param Form $form
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setForm($form) {
|
public function setForm($form) {
|
||||||
$this->form = $form;
|
$this->form = $form;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,23 +633,29 @@ class FormField extends RequestHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return TRUE if security token protection is enabled on the parent {@link Form}.
|
* Return true if security token protection is enabled on the parent {@link Form}.
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function securityTokenEnabled() {
|
public function securityTokenEnabled() {
|
||||||
$form = $this->getForm();
|
$form = $this->getForm();
|
||||||
if(!$form) return false;
|
|
||||||
|
if(!$form) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return $form->getSecurityToken()->isEnabled();
|
return $form->getSecurityToken()->isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the error message to be displayed on the form field
|
* Sets the error message to be displayed on the form field.
|
||||||
* Set by php validation of the form.
|
|
||||||
*
|
*
|
||||||
* @param string $message Message to show to the user. Allows HTML content,
|
* Allows HTML content, so remember to use Convert::raw2xml().
|
||||||
* which means you need to use Convert::raw2xml() for any user supplied data.
|
*
|
||||||
|
* @param string $message
|
||||||
|
* @param string $messageType
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setError($message, $messageType) {
|
public function setError($message, $messageType) {
|
||||||
$this->message = $message;
|
$this->message = $message;
|
||||||
@ -485,24 +665,24 @@ class FormField extends RequestHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the custom error message to show instead of the default
|
* Set the custom error message to show instead of the default format.
|
||||||
* format of Please Fill In XXX. Different from setError() as
|
|
||||||
* that appends it to the standard error messaging
|
|
||||||
*
|
*
|
||||||
* @param string Message for the error
|
* Different from setError() as that appends it to the standard error messaging.
|
||||||
|
*
|
||||||
|
* @param string $customValidationMessage
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setCustomValidationMessage($msg) {
|
public function setCustomValidationMessage($customValidationMessage) {
|
||||||
$this->customValidationMessage = $msg;
|
$this->customValidationMessage = $customValidationMessage;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the custom error message for this form field. If a custom
|
* Get the custom error message for this form field. If a custom message has not been defined
|
||||||
* message has not been defined then just return blank. The default
|
* then just return blank. The default error is defined on {@link Validator}.
|
||||||
* error is defined on {@link Validator}.
|
|
||||||
*
|
*
|
||||||
* @todo Should the default error message be stored here instead
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getCustomValidationMessage() {
|
public function getCustomValidationMessage() {
|
||||||
@ -511,10 +691,13 @@ class FormField extends RequestHandler {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set name of template (without path or extension).
|
* Set name of template (without path or extension).
|
||||||
* Caution: Not consistently implemented in all subclasses,
|
|
||||||
* please check the {@link Field()} method on the subclass for support.
|
|
||||||
*
|
*
|
||||||
* @param string
|
* Caution: Not consistently implemented in all subclasses, please check the {@link Field()}
|
||||||
|
* method on the subclass for support.
|
||||||
|
*
|
||||||
|
* @param string $template
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setTemplate($template) {
|
public function setTemplate($template) {
|
||||||
$this->template = $template;
|
$this->template = $template;
|
||||||
@ -537,16 +720,18 @@ class FormField extends RequestHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set name of template (without path or extension) for the holder,
|
* Set name of template (without path or extension) for the holder, which in turn is
|
||||||
* which in turn is responsible for rendering {@link Field()}.
|
* responsible for rendering {@link Field()}.
|
||||||
*
|
*
|
||||||
* Caution: Not consistently implemented in all subclasses,
|
* Caution: Not consistently implemented in all subclasses, please check the {@link Field()}
|
||||||
* please check the {@link Field()} method on the subclass for support.
|
* method on the subclass for support.
|
||||||
*
|
*
|
||||||
* @param string
|
* @param string $fieldHolderTemplate
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setFieldHolderTemplate($template) {
|
public function setFieldHolderTemplate($fieldHolderTemplate) {
|
||||||
$this->fieldHolderTemplate = $template;
|
$this->fieldHolderTemplate = $fieldHolderTemplate;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -559,50 +744,67 @@ class FormField extends RequestHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set name of template (without path or extension) for the small holder,
|
* Set name of template (without path or extension) for the small holder, which in turn is
|
||||||
* which in turn is responsible for rendering {@link Field()}.
|
* responsible for rendering {@link Field()}.
|
||||||
*
|
*
|
||||||
* Caution: Not consistently implemented in all subclasses,
|
* Caution: Not consistently implemented in all subclasses, please check the {@link Field()}
|
||||||
* please check the {@link Field()} method on the subclass for support.
|
* method on the subclass for support.
|
||||||
*
|
*
|
||||||
* @param string
|
* @param string $smallFieldHolderTemplate
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setSmallFieldHolderTemplate($template) {
|
public function setSmallFieldHolderTemplate($smallFieldHolderTemplate) {
|
||||||
$this->smallFieldHolderTemplate = $template;
|
$this->smallFieldHolderTemplate = $smallFieldHolderTemplate;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the form field - used by templates.
|
* Returns the form field.
|
||||||
|
*
|
||||||
* Although FieldHolder is generally what is inserted into templates, all of the field holder
|
* Although FieldHolder is generally what is inserted into templates, all of the field holder
|
||||||
* templates make use of $Field. It's expected that FieldHolder will give you the "complete"
|
* templates make use of $Field. It's expected that FieldHolder will give you the "complete"
|
||||||
* representation of the field on the form, whereas Field will give you the core editing widget,
|
* representation of the field on the form, whereas Field will give you the core editing widget,
|
||||||
* such as an input tag.
|
* such as an input tag.
|
||||||
*
|
*
|
||||||
* @param array $properties key value pairs of template variables
|
* @param array $properties
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function Field($properties = array()) {
|
public function Field($properties = array()) {
|
||||||
$obj = ($properties) ? $this->customise($properties) : $this;
|
$context = $this;
|
||||||
|
|
||||||
|
if(count($properties)) {
|
||||||
|
$context = $context->customise($properties);
|
||||||
|
}
|
||||||
|
|
||||||
$this->extend('onBeforeRender', $this);
|
$this->extend('onBeforeRender', $this);
|
||||||
return $obj->renderWith($this->getTemplates());
|
|
||||||
|
return $context->renderWith($this->getTemplates());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a "field holder" for this field - used by templates.
|
* Returns a "field holder" for this field.
|
||||||
*
|
*
|
||||||
* Forms are constructed by concatenating a number of these field holders.
|
* Forms are constructed by concatenating a number of these field holders.
|
||||||
|
*
|
||||||
* The default field holder is a label and a form field inside a div.
|
* The default field holder is a label and a form field inside a div.
|
||||||
|
*
|
||||||
* @see FieldHolder.ss
|
* @see FieldHolder.ss
|
||||||
*
|
*
|
||||||
* @param array $properties key value pairs of template variables
|
* @param array $properties
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function FieldHolder($properties = array()) {
|
public function FieldHolder($properties = array()) {
|
||||||
$obj = ($properties) ? $this->customise($properties) : $this;
|
$context = $this;
|
||||||
|
|
||||||
return $obj->renderWith($this->getFieldHolderTemplates());
|
if(count($properties)) {
|
||||||
|
$context = $this->customise($properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $context->renderWith($this->getFieldHolderTemplates());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -613,13 +815,17 @@ class FormField extends RequestHandler {
|
|||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function SmallFieldHolder($properties = array()) {
|
public function SmallFieldHolder($properties = array()) {
|
||||||
$obj = ($properties) ? $this->customise($properties) : $this;
|
$context = $this;
|
||||||
|
|
||||||
return $obj->renderWith($this->getSmallFieldHolderTemplates());
|
if(count($properties)) {
|
||||||
|
$context = $this->customise($properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $context->renderWith($this->getSmallFieldHolderTemplates());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of templates to use for rendering {@link FieldH}
|
* Returns an array of templates to use for rendering {@link FieldHolder}.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
@ -628,7 +834,7 @@ class FormField extends RequestHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of templates to use for rendering {@link FieldHolder}
|
* Returns an array of templates to use for rendering {@link FieldHolder}.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
@ -640,7 +846,7 @@ class FormField extends RequestHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of templates to use for rendering {@link SmallFieldHolder}
|
* Returns an array of templates to use for rendering {@link SmallFieldHolder}.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
@ -653,31 +859,37 @@ class FormField extends RequestHandler {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate an array of classname strings to use for rendering this form
|
* Generate an array of class name strings to use for rendering this form field into HTML.
|
||||||
* field into HTML
|
|
||||||
*
|
*
|
||||||
* @param string $custom custom template (if set)
|
* @param string $customTemplate
|
||||||
* @param string $suffix template suffix
|
* @param string $customTemplateSuffix
|
||||||
*
|
*
|
||||||
* @return array $stack a stack of
|
* @return array
|
||||||
*/
|
*/
|
||||||
private function _templates($custom = null, $suffix = null) {
|
private function _templates($customTemplate = null, $customTemplateSuffix = null) {
|
||||||
$matches = array();
|
$matches = array();
|
||||||
|
|
||||||
foreach(array_reverse(ClassInfo::ancestry($this)) as $className) {
|
foreach(array_reverse(ClassInfo::ancestry($this)) as $className) {
|
||||||
$matches[] = $className . $suffix;
|
$matches[] = $className . $customTemplateSuffix;
|
||||||
|
|
||||||
if($className == "FormField") break;
|
if($className == "FormField") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($custom) array_unshift($matches, $custom);
|
if($customTemplate) {
|
||||||
|
array_unshift($matches, $customTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
return $matches;
|
return $matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this field is a composite field.
|
* Returns true if this field is a composite field.
|
||||||
|
*
|
||||||
* To create composite field types, you should subclass {@link CompositeField}.
|
* To create composite field types, you should subclass {@link CompositeField}.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isComposite() {
|
public function isComposite() {
|
||||||
return false;
|
return false;
|
||||||
@ -685,68 +897,91 @@ class FormField extends RequestHandler {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this field has its own data.
|
* Returns true if this field has its own data.
|
||||||
* Some fields, such as titles and composite fields, don't actually have any data. It doesn't
|
*
|
||||||
* make sense for data-focused methods to look at them. By overloading hasData() to return false,
|
* Some fields, such as titles and composite fields, don't actually have any data. It doesn't
|
||||||
* you can prevent any data-focused methods from looking at it.
|
* make sense for data-focused methods to look at them. By overloading hasData() to return
|
||||||
|
* false, you can prevent any data-focused methods from looking at it.
|
||||||
*
|
*
|
||||||
* @see FieldList::collateDataFields()
|
* @see FieldList::collateDataFields()
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function hasData() {
|
public function hasData() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return boolean
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isReadonly() {
|
public function isReadonly() {
|
||||||
return $this->readonly;
|
return $this->readonly;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets readonly-flag on form-field. Please use performReadonlyTransformation()
|
* Sets a read-only flag on this FormField.
|
||||||
* to actually transform this instance.
|
*
|
||||||
* @param $bool boolean Setting "false" has no effect on the field-state.
|
* Use performReadonlyTransformation() to transform this instance.
|
||||||
|
*
|
||||||
|
* Setting this to false has no effect on the field.
|
||||||
|
*
|
||||||
|
* @param bool $readonly
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setReadonly($bool) {
|
public function setReadonly($readonly) {
|
||||||
$this->readonly = $bool;
|
$this->readonly = $readonly;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return boolean
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isDisabled() {
|
public function isDisabled() {
|
||||||
return $this->disabled;
|
return $this->disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets disabed-flag on form-field. Please use performDisabledTransformation()
|
* Sets a disabled flag on this FormField.
|
||||||
* to actually transform this instance.
|
*
|
||||||
* @param $bool boolean Setting "false" has no effect on the field-state.
|
* Use performDisabledTransformation() to transform this instance.
|
||||||
|
*
|
||||||
|
* Setting this to false has no effect on the field.
|
||||||
|
*
|
||||||
|
* @param bool $disabled
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setDisabled($bool) {
|
public function setDisabled($disabled) {
|
||||||
$this->disabled = $bool;
|
$this->disabled = $disabled;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a readonly version of this field
|
* Returns a read-only version of this field.
|
||||||
|
*
|
||||||
|
* @return FormField
|
||||||
*/
|
*/
|
||||||
public function performReadonlyTransformation() {
|
public function performReadonlyTransformation() {
|
||||||
$copy = $this->castedCopy('ReadonlyField');
|
$copy = $this->castedCopy('ReadonlyField');
|
||||||
|
|
||||||
$copy->setReadonly(true);
|
$copy->setReadonly(true);
|
||||||
|
|
||||||
return $copy;
|
return $copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a disabled version of this field.
|
* Return a disabled version of this field.
|
||||||
* Tries to find a class of the class name of this field suffixed with "_Disabled",
|
*
|
||||||
* failing that, finds a method {@link setDisabled()}.
|
* Tries to find a class of the class name of this field suffixed with "_Disabled", failing
|
||||||
|
* that, finds a method {@link setDisabled()}.
|
||||||
*
|
*
|
||||||
* @return FormField
|
* @return FormField
|
||||||
*/
|
*/
|
||||||
public function performDisabledTransformation() {
|
public function performDisabledTransformation() {
|
||||||
$disabledClassName = $this->class . '_Disabled';
|
$disabledClassName = $this->class . '_Disabled';
|
||||||
|
|
||||||
if(ClassInfo::exists($disabledClassName)) {
|
if(ClassInfo::exists($disabledClassName)) {
|
||||||
$clone = $this->castedCopy($disabledClassName);
|
$clone = $this->castedCopy($disabledClassName);
|
||||||
} else {
|
} else {
|
||||||
@ -754,24 +989,39 @@ class FormField extends RequestHandler {
|
|||||||
$clone->setDisabled(true);
|
$clone->setDisabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $clone;
|
return $clone;
|
||||||
}
|
|
||||||
|
|
||||||
public function transform(FormTransformation $trans) {
|
|
||||||
return $trans->transform($this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hasClass($class){
|
/**
|
||||||
$patten = '/'.strtolower($class).'/i';
|
* @param FormTransformation $transformation
|
||||||
$subject = strtolower($this->class." ".$this->extraClass());
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function transform(FormTransformation $transformation) {
|
||||||
|
return $transformation->transform($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $class
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function hasClass($class) {
|
||||||
|
$patten = '/' . strtolower($class) . '/i';
|
||||||
|
|
||||||
|
$subject = strtolower($this->class . ' ' . $this->extraClass());
|
||||||
|
|
||||||
return preg_match($patten, $subject);
|
return preg_match($patten, $subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the field type - used by templates.
|
* Returns the field type.
|
||||||
|
*
|
||||||
* The field type is the class name with the word Field dropped off the end, all lowercase.
|
* The field type is the class name with the word Field dropped off the end, all lowercase.
|
||||||
* It's handy for assigning HTML classes. Doesn't signify the <input type> attribute,
|
*
|
||||||
* see {link getAttributes()}.
|
* It's handy for assigning HTML classes. Doesn't signify the <input type> attribute.
|
||||||
|
*
|
||||||
|
* @see {link getAttributes()}.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@ -781,19 +1031,28 @@ class FormField extends RequestHandler {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.2 Use FormField::create_tag()
|
* @deprecated 3.2 Use FormField::create_tag()
|
||||||
|
*
|
||||||
|
* @param string $tag
|
||||||
|
* @param array $attributes
|
||||||
|
* @param null|string $content
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function createTag($tag, $attributes, $content = null) {
|
public function createTag($tag, $attributes, $content = null) {
|
||||||
Deprecation::notice('3.2', 'Use FormField::create_tag()');
|
Deprecation::notice('3.2', 'Use FormField::create_tag()');
|
||||||
|
|
||||||
return self::create_tag($tag, $attributes, $content);
|
return self::create_tag($tag, $attributes, $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract method each {@link FormField} subclass must implement,
|
* Abstract method each {@link FormField} subclass must implement, determines whether the field
|
||||||
* determines whether the field is valid or not based on the value.
|
* is valid or not based on the value.
|
||||||
|
*
|
||||||
* @todo Make this abstract.
|
* @todo Make this abstract.
|
||||||
*
|
*
|
||||||
* @param Validator
|
* @param Validator $validator
|
||||||
* @return boolean
|
*
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function validate($validator) {
|
public function validate($validator) {
|
||||||
return true;
|
return true;
|
||||||
@ -801,13 +1060,16 @@ class FormField extends RequestHandler {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe this field, provide help text for it.
|
* Describe this field, provide help text for it.
|
||||||
* By default, renders as a <span class="description">
|
|
||||||
* underneath the form field.
|
|
||||||
*
|
*
|
||||||
* @return string Description
|
* By default, renders as a <span class="description"> underneath the form field.
|
||||||
|
*
|
||||||
|
* @param string $description
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setDescription($description) {
|
public function setDescription($description) {
|
||||||
$this->description = $description;
|
$this->description = $description;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -818,37 +1080,51 @@ class FormField extends RequestHandler {
|
|||||||
return $this->description;
|
return $this->description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function debug() {
|
public function debug() {
|
||||||
return "$this->class ($this->name: $this->title : <font style='color:red;'>$this->message</font>)"
|
return sprintf(
|
||||||
. " = $this->value";
|
'%s (%s: %s : <span style="color:red;">%s</span>) = %s',
|
||||||
|
$this->class,
|
||||||
|
$this->name,
|
||||||
|
$this->title,
|
||||||
|
$this->message,
|
||||||
|
$this->value
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is used by the template processor. If you refer to a field as a $ variable, it
|
* This function is used by the template processor. If you refer to a field as a $ variable, it
|
||||||
* will return the $Field value.
|
* will return the $Field value.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function forTemplate() {
|
public function forTemplate() {
|
||||||
return $this->Field();
|
return $this->Field();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @uses Validator->fieldIsRequired()
|
* @return bool
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public function Required() {
|
public function Required() {
|
||||||
if($this->form && ($validator = $this->form->Validator)) {
|
if($this->form && ($validator = $this->form->Validator)) {
|
||||||
return $validator->fieldIsRequired($this->name);
|
return $validator->fieldIsRequired($this->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the FieldList that contains this field.
|
* Set the FieldList that contains this field.
|
||||||
*
|
*
|
||||||
* @param FieldList $list
|
* @param FieldList $containerFieldList
|
||||||
|
*
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function setContainerFieldList($list) {
|
public function setContainerFieldList($containerFieldList) {
|
||||||
$this->containerFieldList = $list;
|
$this->containerFieldList = $containerFieldList;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -861,31 +1137,46 @@ class FormField extends RequestHandler {
|
|||||||
return $this->containerFieldList;
|
return $this->containerFieldList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return null|FieldList
|
||||||
|
*/
|
||||||
public function rootFieldList() {
|
public function rootFieldList() {
|
||||||
if(is_object($this->containerFieldList)) return $this->containerFieldList->rootFieldList();
|
if(is_object($this->containerFieldList)) {
|
||||||
else user_error("rootFieldList() called on $this->class object without a containerFieldList", E_USER_ERROR);
|
return $this->containerFieldList->rootFieldList();
|
||||||
|
}
|
||||||
|
|
||||||
|
user_error(
|
||||||
|
"rootFieldList() called on $this->class object without a containerFieldList",
|
||||||
|
E_USER_ERROR
|
||||||
|
);
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns another instance of this field, but "cast" to a different class.
|
* Returns another instance of this field, but "cast" to a different class. The logic tries to
|
||||||
* The logic tries to retain all of the instance properties,
|
* retain all of the instance properties, and may be overloaded by subclasses to set additional
|
||||||
* and may be overloaded by subclasses to set additional ones.
|
* ones.
|
||||||
*
|
*
|
||||||
* Assumes the standard FormField parameter signature with
|
* Assumes the standard FormField parameter signature with its name as the only mandatory
|
||||||
* its name as the only mandatory argument. Mainly geared towards
|
* argument. Mainly geared towards creating *_Readonly or *_Disabled subclasses of the same
|
||||||
* creating *_Readonly or *_Disabled subclasses of the same type,
|
* type, or casting to a {@link ReadonlyField}.
|
||||||
* or casting to a {@link ReadonlyField}.
|
|
||||||
*
|
*
|
||||||
* Does not copy custom field templates, since they probably won't apply to
|
* Does not copy custom field templates, since they probably won't apply to the new instance.
|
||||||
* the new instance.
|
*
|
||||||
|
* @param mixed $classOrCopy Class name for copy, or existing copy instance to update
|
||||||
*
|
*
|
||||||
* @param String $classOrCopy Class name for copy, or existing copy instance to update
|
|
||||||
* @return FormField
|
* @return FormField
|
||||||
*/
|
*/
|
||||||
public function castedCopy($classOrCopy) {
|
public function castedCopy($classOrCopy) {
|
||||||
$field = (is_object($classOrCopy)) ? $classOrCopy : new $classOrCopy($this->name);
|
$field = $classOrCopy;
|
||||||
|
|
||||||
|
if(!is_object($field)) {
|
||||||
|
$field = new $classOrCopy($this->name);
|
||||||
|
}
|
||||||
|
|
||||||
$field
|
$field
|
||||||
->setValue($this->value) // get value directly from property, avoid any conversions
|
->setValue($this->value)
|
||||||
->setForm($this->form)
|
->setForm($this->form)
|
||||||
->setTitle($this->Title())
|
->setTitle($this->Title())
|
||||||
->setLeftTitle($this->LeftTitle())
|
->setLeftTitle($this->LeftTitle())
|
||||||
@ -893,15 +1184,14 @@ class FormField extends RequestHandler {
|
|||||||
->addExtraClass($this->extraClass())
|
->addExtraClass($this->extraClass())
|
||||||
->setDescription($this->getDescription());
|
->setDescription($this->getDescription());
|
||||||
|
|
||||||
// Only include built-in attributes, ignore anything
|
// Only include built-in attributes, ignore anything set through getAttributes().
|
||||||
// set through getAttributes(), since those might change important characteristics
|
// Those might change important characteristics of the field, e.g. its "type" attribute.
|
||||||
// of the field, e.g. its "type" attribute.
|
foreach($this->attributes as $attributeKey => $attributeValue) {
|
||||||
foreach($this->attributes as $k => $v) {
|
$field->setAttribute($attributeKey, $attributeValue);
|
||||||
$field->setAttribute($k, $v);
|
}
|
||||||
}
|
|
||||||
$field->dontEscape = $this->dontEscape;
|
$field->dontEscape = $this->dontEscape;
|
||||||
|
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user