2007-07-19 12:40:28 +02:00
|
|
|
<?php
|
|
|
|
/**
|
2010-10-15 02:04:14 +02:00
|
|
|
* Represents a field in a form.
|
|
|
|
*
|
2011-10-28 03:37:27 +02:00
|
|
|
* A FieldList contains a number of FormField objects which make up the whole of a form.
|
2007-07-19 12:40:28 +02:00
|
|
|
* 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.
|
2010-10-15 02:04:14 +02:00
|
|
|
*
|
|
|
|
* <b>Subclassing</b>
|
|
|
|
*
|
|
|
|
* Define a {@link dataValue()} method that returns a value suitable for inserting into a single database field.
|
|
|
|
* 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.
|
|
|
|
*
|
2008-01-09 05:18:36 +01:00
|
|
|
* @package forms
|
|
|
|
* @subpackage core
|
2007-07-19 12:40:28 +02:00
|
|
|
*/
|
2008-10-30 23:03:21 +01:00
|
|
|
class FormField extends RequestHandler {
|
2011-03-23 05:12:25 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var Form
|
|
|
|
*/
|
2007-07-19 12:40:28 +02:00
|
|
|
protected $form;
|
2011-03-23 05:12:25 +01:00
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
protected $name, $title, $value ,$message, $messageType, $extraClass;
|
2007-10-05 00:17:44 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var $description string Adds a "title"-attribute to the markup.
|
2008-01-11 02:49:50 +01:00
|
|
|
* @todo Implement in all subclasses
|
2007-10-05 00:17:44 +02:00
|
|
|
*/
|
2007-07-19 12:40:28 +02:00
|
|
|
protected $description;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var $extraClasses array Extra CSS-classes for the formfield-container
|
|
|
|
*/
|
|
|
|
protected $extraClasses;
|
|
|
|
|
|
|
|
public $dontEscape;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var $rightTitle string Used in SmallFieldHolder() to force a right-aligned label.
|
|
|
|
*/
|
|
|
|
protected $rightTitle;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var $leftTitle string Used in SmallFieldHolder() to force a left-aligned label with correct spacing.
|
2009-06-27 09:00:01 +02:00
|
|
|
* Please use $title for FormFields rendered with FieldHolder().
|
2007-07-19 12:40:28 +02:00
|
|
|
*/
|
|
|
|
protected $leftTitle;
|
|
|
|
|
2008-04-06 06:01:28 +02:00
|
|
|
/**
|
|
|
|
* Set the "tabindex" HTML attribute on the field.
|
|
|
|
*
|
|
|
|
* @var int
|
|
|
|
*/
|
|
|
|
protected $tabIndex;
|
2008-09-11 02:02:49 +02:00
|
|
|
|
|
|
|
/**
|
2011-10-28 03:37:27 +02:00
|
|
|
* Stores a reference to the FieldList that contains this object.
|
|
|
|
* @var FieldList
|
2008-09-11 02:02:49 +02:00
|
|
|
*/
|
|
|
|
protected $containerFieldSet;
|
2008-04-06 06:01:28 +02:00
|
|
|
|
2008-08-12 04:58:48 +02:00
|
|
|
/**
|
|
|
|
* @var $readonly boolean
|
|
|
|
*/
|
|
|
|
protected $readonly = false;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var $disabled boolean
|
|
|
|
*/
|
|
|
|
protected $disabled = false;
|
|
|
|
|
2011-04-16 05:09:30 +02:00
|
|
|
/**
|
|
|
|
* @var String
|
|
|
|
*/
|
2011-12-21 17:35:42 +01:00
|
|
|
protected $template = 'FormField';
|
2011-04-16 05:09:30 +02:00
|
|
|
|
2009-04-29 01:55:53 +02:00
|
|
|
/**
|
|
|
|
* @var Custom Validation Message for the Field
|
|
|
|
*/
|
|
|
|
protected $customValidationMessage = "";
|
2011-03-23 05:12:25 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Template name to render this FormField field holder into.
|
|
|
|
* @var string
|
|
|
|
*/
|
2011-12-21 17:35:42 +01:00
|
|
|
protected $fieldHolderTemplate = 'FieldHolder';
|
2011-03-23 05:12:25 +01:00
|
|
|
|
2011-12-22 13:10:57 +01:00
|
|
|
/**
|
|
|
|
* @var array All attributes on the form field (not the field holder).
|
|
|
|
* Partially determined based on other instance properties, please use {@link getAttributes()}.
|
|
|
|
*/
|
|
|
|
protected $attributes = array();
|
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
/**
|
|
|
|
* Create a new field.
|
|
|
|
* @param name The internal field name, passed to forms.
|
|
|
|
* @param title The field label.
|
|
|
|
* @param value The value of the field.
|
|
|
|
* @param form Reference to the container form
|
|
|
|
* @param maxLength The Maximum length of the attribute
|
|
|
|
*/
|
2007-11-06 02:07:54 +01:00
|
|
|
function __construct($name, $title = null, $value = null, $form = null, $rightTitle = null) {
|
2007-07-19 12:40:28 +02:00
|
|
|
$this->name = $name;
|
|
|
|
$this->title = ($title === null) ? $name : $title;
|
|
|
|
|
2010-04-14 06:40:04 +02:00
|
|
|
if($value !== NULL) $this->setValue($value);
|
2007-07-19 12:40:28 +02:00
|
|
|
if($form) $this->setForm($form);
|
|
|
|
|
|
|
|
parent::__construct();
|
|
|
|
}
|
|
|
|
|
2008-08-09 05:29:30 +02:00
|
|
|
/**
|
|
|
|
* Return a Link to this field
|
|
|
|
*/
|
2009-10-11 02:07:16 +02:00
|
|
|
function Link($action = null) {
|
|
|
|
return Controller::join_links($this->form->FormAction(), 'field/' . $this->name, $action);
|
2008-08-09 05:29:30 +02:00
|
|
|
}
|
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
/**
|
|
|
|
* Returns the HTML ID of the field - used in the template by label tags.
|
|
|
|
* The ID is generated as FormName_FieldName. All Field functions should ensure
|
|
|
|
* that this ID is included in the field.
|
|
|
|
*/
|
2011-03-23 05:12:25 +01:00
|
|
|
function ID() {
|
2007-07-19 12:40:28 +02:00
|
|
|
$name = ereg_replace('(^-)|(-$)','',ereg_replace('[^A-Za-z0-9_-]+','-',$this->name));
|
|
|
|
if($this->form) return $this->form->FormName() . '_' . $name;
|
|
|
|
else return $name;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the field name - used by templates.
|
2009-03-17 12:38:52 +01:00
|
|
|
*
|
|
|
|
* @return string
|
2007-07-19 12:40:28 +02:00
|
|
|
*/
|
2011-05-05 16:48:45 +02:00
|
|
|
function getName() {
|
2007-07-19 12:40:28 +02:00
|
|
|
return $this->name;
|
|
|
|
}
|
2011-05-05 16:48:45 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated 3.0 Use {@link getName()}.
|
|
|
|
*/
|
|
|
|
public function Name() {
|
2011-10-29 01:02:11 +02:00
|
|
|
Deprecation::notice('3.0', 'Use getName() instead.');
|
2011-05-05 16:48:45 +02:00
|
|
|
return $this->getName();
|
|
|
|
}
|
2007-07-19 12:40:28 +02:00
|
|
|
|
|
|
|
/**
|
2009-03-17 12:38:52 +01:00
|
|
|
* Returns the field message, used by form validation.
|
|
|
|
* Use {@link setError()} to set this property.
|
|
|
|
*
|
|
|
|
* @return string
|
2007-07-19 12:40:28 +02:00
|
|
|
*/
|
2009-04-29 03:20:24 +02:00
|
|
|
function Message() {
|
2007-07-19 12:40:28 +02:00
|
|
|
return $this->message;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2009-03-17 12:38:52 +01:00
|
|
|
* Returns the field message type, used by form validation.
|
|
|
|
* Arbitrary value which is mostly used for CSS classes
|
|
|
|
* in the rendered HTML, e.g. "required".
|
|
|
|
* Use {@link setError()} to set this property.
|
|
|
|
*
|
|
|
|
* @return string
|
2007-07-19 12:40:28 +02:00
|
|
|
*/
|
2009-04-29 03:20:24 +02:00
|
|
|
function MessageType() {
|
2007-07-19 12:40:28 +02:00
|
|
|
return $this->messageType;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the field value - used by templates.
|
|
|
|
*/
|
|
|
|
function Value() {
|
|
|
|
return $this->value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Method to save this form field into the given data object.
|
|
|
|
* By default, makes use of $this->dataValue()
|
|
|
|
*/
|
2007-12-04 05:07:04 +01:00
|
|
|
function saveInto(DataObjectInterface $record) {
|
2007-07-19 12:40:28 +02:00
|
|
|
if($this->name) {
|
|
|
|
$record->setCastedField($this->name, $this->dataValue());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the field value suitable for insertion into the data object
|
|
|
|
*/
|
|
|
|
function dataValue() {
|
|
|
|
return $this->value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the field label - used by templates.
|
|
|
|
*/
|
|
|
|
function Title() {
|
|
|
|
return $this->title;
|
|
|
|
}
|
|
|
|
|
|
|
|
function setTitle($val) {
|
|
|
|
$this->title = $val;
|
|
|
|
}
|
2011-03-23 05:12:25 +01:00
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
function RightTitle() {
|
|
|
|
return $this->rightTitle;
|
|
|
|
}
|
2011-03-23 05:12:25 +01:00
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
function setRightTitle($val) {
|
|
|
|
$this->rightTitle = $val;
|
|
|
|
}
|
|
|
|
|
|
|
|
function LeftTitle() {
|
|
|
|
return $this->leftTitle;
|
|
|
|
}
|
2011-03-23 05:12:25 +01:00
|
|
|
|
|
|
|
function setLeftTitle($val) {
|
2007-07-19 12:40:28 +02:00
|
|
|
$this->leftTitle = $val;
|
|
|
|
}
|
2011-03-23 05:12:25 +01:00
|
|
|
|
2008-04-06 06:01:28 +02:00
|
|
|
/**
|
|
|
|
* Set tabindex HTML attribute
|
|
|
|
* (defaults to none).
|
|
|
|
*
|
|
|
|
* @param int $index
|
|
|
|
*/
|
|
|
|
public function setTabIndex($index) {
|
|
|
|
$this->tabIndex = $index;
|
|
|
|
}
|
2011-03-23 05:12:25 +01:00
|
|
|
|
2008-04-06 06:01:28 +02:00
|
|
|
/**
|
|
|
|
* Get tabindex (if previously set)
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
public function getTabIndex() {
|
|
|
|
return $this->tabIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get tabindex HTML string
|
|
|
|
*
|
|
|
|
* @param int $increment Increase current tabindex by this value
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
protected function getTabIndexHTML($increment = 0) {
|
|
|
|
$tabIndex = (int)$this->getTabIndex() + (int)$increment;
|
|
|
|
return (is_numeric($tabIndex)) ? ' tabindex = "' . $tabIndex . '"' : '';
|
|
|
|
}
|
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
/**
|
|
|
|
* Compiles all CSS-classes. Optionally includes a "nolabel"-class
|
|
|
|
* if no title was set on the formfield.
|
2009-03-17 12:38:52 +01:00
|
|
|
* Uses {@link Message()} and {@link MessageType()} to add validatoin
|
|
|
|
* error classes which can be used to style the contained tags.
|
2007-07-19 12:40:28 +02:00
|
|
|
*
|
|
|
|
* @return String CSS-classnames
|
|
|
|
*/
|
|
|
|
function extraClass() {
|
2011-12-22 13:10:57 +01:00
|
|
|
$classes = array();
|
|
|
|
|
|
|
|
$classes[] = $this->Type();
|
|
|
|
|
|
|
|
if($this->extraClasses) $classes = array_merge($classes, array_values($this->extraClasses));
|
2009-03-17 12:38:52 +01:00
|
|
|
|
|
|
|
// Allow customization of label and field tag positioning
|
2011-12-22 13:10:57 +01:00
|
|
|
if(!$this->Title()) $classes[] = "nolabel";
|
2007-07-19 12:40:28 +02:00
|
|
|
|
2009-03-17 12:38:52 +01:00
|
|
|
// Allow custom styling of any element in the container based
|
|
|
|
// on validation errors, e.g. red borders on input tags.
|
|
|
|
// CSS-Class needs to be different from the one rendered
|
|
|
|
// through {@link FieldHolder()}
|
2011-12-22 13:10:57 +01:00
|
|
|
if($this->Message()) $classes[] .= "holder-" . $this->MessageType();
|
2009-03-17 12:38:52 +01:00
|
|
|
|
2011-12-22 13:10:57 +01:00
|
|
|
return implode(' ', $classes);
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a CSS-class to the formfield-container.
|
|
|
|
*
|
|
|
|
* @param $class String
|
|
|
|
*/
|
|
|
|
function addExtraClass($class) {
|
|
|
|
$this->extraClasses[$class] = $class;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove a CSS-class from the formfield-container.
|
|
|
|
*
|
|
|
|
* @param $class String
|
|
|
|
*/
|
|
|
|
function removeExtraClass($class) {
|
2009-06-19 03:34:06 +02:00
|
|
|
if(isset($this->extraClasses) && array_key_exists($class, $this->extraClasses)) unset($this->extraClasses[$class]);
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
|
|
|
|
2011-12-22 13:10:57 +01:00
|
|
|
/**
|
|
|
|
* Set an HTML attribute on the field element, mostly an <input> tag.
|
|
|
|
*
|
|
|
|
* CAUTION Doesn't work on most fields which are composed of more than one HTML form field:
|
|
|
|
* AjaxUniqueTextField, CheckboxSetField, ComplexTableField, CompositeField, ConfirmedPasswordField, CountryDropdownField,
|
|
|
|
* CreditCardField, CurrencyField, DateField, DatetimeField, FieldGroup, GridField, HtmlEditorField,
|
|
|
|
* ImageField, ImageFormAction, InlineFormAction, ListBoxField, etc.
|
|
|
|
*
|
|
|
|
* @param String
|
|
|
|
* @param String
|
|
|
|
*/
|
|
|
|
function setAttribute($name, $value) {
|
|
|
|
$this->attributes[$name] = $value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
|
|
|
function getAttribute($name) {
|
|
|
|
$attrs = $this->getAttributes();
|
|
|
|
return @$attrs[$name];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
function getAttributes() {
|
|
|
|
$attrs = array(
|
|
|
|
'type' => 'text',
|
|
|
|
'name' => $this->getName(),
|
|
|
|
'value' => $this->Value(),
|
|
|
|
'class' => $this->extraClass(),
|
|
|
|
'id' => $this->ID(),
|
|
|
|
'tabindex' => $this->getTabIndex(),
|
|
|
|
'disabled' => $this->isDisabled(),
|
|
|
|
);
|
|
|
|
return array_merge($attrs, $this->attributes);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Array 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
|
|
|
|
*/
|
|
|
|
function getAttributesHTML($attrs = null) {
|
|
|
|
$exclude = (is_string($attrs)) ? func_get_args() : null;
|
|
|
|
|
|
|
|
if(!$attrs || is_string($attrs)) $attrs = $this->getAttributes();
|
|
|
|
|
|
|
|
// Remove empty
|
|
|
|
$attrs = array_filter((array)$attrs, create_function('$v', 'return ($v || $v === 0);')); ;
|
|
|
|
|
|
|
|
// Remove excluded
|
|
|
|
if($exclude) $attrs = array_diff_key($attrs, array_flip($exclude));
|
|
|
|
|
|
|
|
// Create markkup
|
|
|
|
$parts = array();
|
|
|
|
foreach($attrs as $name => $value) {
|
|
|
|
$parts[] = ($value === true) ? "{$name}=\"{$name}\"" : "{$name}=\"" . Convert::raw2att($value) . "\"";
|
|
|
|
}
|
|
|
|
|
|
|
|
return implode(' ', $parts);
|
|
|
|
}
|
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
/**
|
|
|
|
* Returns a version of a title suitable for insertion into an HTML attribute
|
|
|
|
*/
|
|
|
|
function attrTitle() {
|
|
|
|
return Convert::raw2att($this->title);
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Returns a version of a title suitable for insertion into an HTML attribute
|
|
|
|
*/
|
|
|
|
function attrValue() {
|
|
|
|
return Convert::raw2att($this->value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the field value.
|
|
|
|
* Returns $this.
|
|
|
|
*/
|
2008-11-22 04:33:00 +01:00
|
|
|
function setValue($value) {
|
|
|
|
$this->value = $value; return $this;
|
|
|
|
}
|
2007-07-19 12:40:28 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the field name
|
|
|
|
*/
|
2008-11-22 04:33:00 +01:00
|
|
|
function setName($name) {
|
|
|
|
$this->name = $name;
|
|
|
|
}
|
2007-07-19 12:40:28 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
function setForm($form) {
|
|
|
|
$this->form = $form;
|
|
|
|
}
|
|
|
|
|
2008-04-06 05:33:55 +02:00
|
|
|
/**
|
|
|
|
* Get the currently used form.
|
|
|
|
*
|
|
|
|
* @return Form
|
|
|
|
*/
|
|
|
|
function getForm() {
|
|
|
|
return $this->form;
|
|
|
|
}
|
2011-03-23 05:12:25 +01:00
|
|
|
|
2011-12-21 17:35:42 +01:00
|
|
|
/**
|
|
|
|
* @return String
|
|
|
|
*/
|
2011-03-23 05:12:25 +01:00
|
|
|
public function getFieldHolderTemplate() {
|
|
|
|
return $this->fieldHolderTemplate;
|
|
|
|
}
|
|
|
|
|
2011-12-21 17:35:42 +01:00
|
|
|
/**
|
|
|
|
* Set name of template (without path or extension) for the holder,
|
|
|
|
* which in turn is responsible for rendering {@link Field()}.
|
|
|
|
*
|
|
|
|
* Caution: Not consistently implemented in all subclasses,
|
|
|
|
* please check the {@link Field()} method on the subclass for support.
|
|
|
|
*
|
|
|
|
* @param String
|
|
|
|
*/
|
2011-03-23 05:12:25 +01:00
|
|
|
public function setFieldHolderTemplate($template) {
|
|
|
|
$this->fieldHolderTemplate = $template;
|
|
|
|
}
|
|
|
|
|
2009-06-27 10:48:42 +02:00
|
|
|
/**
|
|
|
|
* Return TRUE if security token protection is enabled on the parent {@link Form}.
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function securityTokenEnabled() {
|
2011-10-29 06:10:02 +02:00
|
|
|
$form = $this->getForm();
|
|
|
|
if(!$form) return false;
|
|
|
|
return $form->getSecurityToken()->isEnabled();
|
2009-06-27 10:48:42 +02:00
|
|
|
}
|
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
/**
|
|
|
|
* Sets the error message to be displayed on the form field
|
|
|
|
* Set by php validation of the form
|
|
|
|
*/
|
2011-03-23 05:12:25 +01:00
|
|
|
function setError($message, $messageType) {
|
2007-07-19 12:40:28 +02:00
|
|
|
$this->message = $message;
|
|
|
|
$this->messageType = $messageType;
|
|
|
|
}
|
|
|
|
|
2009-04-29 01:55:53 +02:00
|
|
|
/**
|
|
|
|
* Set the custom error message to show instead of the default
|
|
|
|
* format of Please Fill In XXX. Different from setError() as
|
|
|
|
* that appends it to the standard error messaging
|
|
|
|
*
|
|
|
|
* @param String Message for the error
|
|
|
|
*/
|
|
|
|
public function setCustomValidationMessage($msg) {
|
|
|
|
$this->customValidationMessage = $msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the custom error message for this form field. If a custom
|
|
|
|
* message has not been defined then just return blank. The default
|
|
|
|
* error is defined on {@link Validator}.
|
|
|
|
*
|
|
|
|
* @todo Should the default error message be stored here instead
|
|
|
|
* @return String
|
|
|
|
*/
|
|
|
|
public function getCustomValidationMessage() {
|
|
|
|
return $this->customValidationMessage;
|
|
|
|
}
|
2011-03-23 05:12:25 +01:00
|
|
|
|
2011-04-16 05:09:30 +02:00
|
|
|
/**
|
2011-12-21 17:35:42 +01:00
|
|
|
* 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.
|
2011-04-16 05:09:30 +02:00
|
|
|
*
|
|
|
|
* @param String
|
|
|
|
*/
|
|
|
|
function setTemplate($template) {
|
|
|
|
$this->template = $template;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return String
|
|
|
|
*/
|
|
|
|
function getTemplate() {
|
|
|
|
return $this->template;
|
|
|
|
}
|
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
/**
|
|
|
|
* Returns the form field - used by templates.
|
|
|
|
* 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"
|
|
|
|
* representation of the field on the form, whereas Field will give you the core editing widget,
|
|
|
|
* such as an input tag.
|
|
|
|
*
|
2011-03-23 05:12:25 +01:00
|
|
|
* @param array $properties key value pairs of template variables
|
|
|
|
* @return string
|
2007-07-19 12:40:28 +02:00
|
|
|
*/
|
2011-03-23 05:12:25 +01:00
|
|
|
function Field($properties = array()) {
|
2011-12-21 17:35:42 +01:00
|
|
|
$obj = ($properties) ? $this->customise($properties) : $this;
|
|
|
|
return $obj->renderWith($this->getTemplate());
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
2011-03-23 05:12:25 +01:00
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
/**
|
2011-03-23 05:12:25 +01:00
|
|
|
* Returns a "field holder" for this field - used by templates.
|
2007-07-19 12:40:28 +02:00
|
|
|
*
|
2011-03-23 05:12:25 +01:00
|
|
|
* 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.
|
|
|
|
* @see FieldHolder.ss
|
2007-11-23 02:10:19 +01:00
|
|
|
*
|
2011-03-23 05:12:25 +01:00
|
|
|
* @param array $properties key value pairs of template variables
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
function FieldHolder($properties = array()) {
|
2011-12-21 17:35:42 +01:00
|
|
|
$obj = ($properties) ? $this->customise($properties) : $this;
|
|
|
|
return $obj->renderWith($this->getFieldHolderTemplate());
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
|
|
|
|
2011-03-23 05:12:25 +01:00
|
|
|
/**
|
|
|
|
* Returns a restricted field holder used within things like FieldGroups.
|
|
|
|
*/
|
|
|
|
function SmallFieldHolder() {
|
2007-07-19 12:40:28 +02:00
|
|
|
$result = '';
|
|
|
|
// set label
|
|
|
|
if($title = $this->RightTitle()){
|
2007-10-18 03:07:35 +02:00
|
|
|
$result .= "<label class=\"right\" for=\"" . $this->id() . "\">{$title}</label>\n";
|
2007-07-19 12:40:28 +02:00
|
|
|
} elseif($title = $this->LeftTitle()) {
|
2007-10-18 03:07:35 +02:00
|
|
|
$result .= "<label class=\"left\" for=\"" . $this->id() . "\">{$title}</label>\n";
|
2007-07-19 12:40:28 +02:00
|
|
|
} elseif($title = $this->Title()) {
|
2007-10-18 03:07:35 +02:00
|
|
|
$result .= "<label for=\"" . $this->id() . "\">{$title}</label>\n";
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
2011-03-23 05:12:25 +01:00
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
$result .= $this->Field();
|
2011-03-23 05:12:25 +01:00
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
return $result;
|
2011-03-23 05:12:25 +01:00
|
|
|
}
|
2007-07-19 12:40:28 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if this field is a composite field.
|
|
|
|
* To create composite field types, you should subclass {@link CompositeField}.
|
|
|
|
*/
|
2011-03-23 05:12:25 +01:00
|
|
|
function isComposite() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
/**
|
|
|
|
* 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,
|
|
|
|
* you can prevent any data-focused methods from looking at it.
|
|
|
|
*
|
2011-10-28 03:37:27 +02:00
|
|
|
* @see FieldList::collateDataFields()
|
2007-07-19 12:40:28 +02:00
|
|
|
*/
|
2011-03-23 05:12:25 +01:00
|
|
|
function hasData() {
|
|
|
|
return true;
|
|
|
|
}
|
2007-07-19 12:40:28 +02:00
|
|
|
|
2008-08-12 04:58:48 +02:00
|
|
|
/**
|
|
|
|
* @return boolean
|
|
|
|
*/
|
2007-07-19 12:40:28 +02:00
|
|
|
function isReadonly() {
|
2008-08-12 04:58:48 +02:00
|
|
|
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;
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a readonly version of this field
|
|
|
|
*/
|
|
|
|
function performReadonlyTransformation() {
|
|
|
|
$field = new ReadonlyField($this->name, $this->title, $this->value);
|
2008-10-16 02:43:00 +02:00
|
|
|
$field->addExtraClass($this->extraClass());
|
2007-07-19 12:40:28 +02:00
|
|
|
$field->setForm($this->form);
|
|
|
|
return $field;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return a disabled version of this field
|
|
|
|
*/
|
|
|
|
function performDisabledTransformation() {
|
2008-12-04 23:38:32 +01:00
|
|
|
$clone = clone $this;
|
|
|
|
$disabledClassName = $clone->class . '_Disabled';
|
2007-07-19 12:40:28 +02:00
|
|
|
if( ClassInfo::exists( $disabledClassName ) )
|
|
|
|
return new $disabledClassName( $this->name, $this->title, $this->value );
|
2008-12-04 23:38:32 +01:00
|
|
|
elseif($clone->hasMethod('setDisabled')){
|
|
|
|
$clone->setDisabled(true);
|
|
|
|
return $clone;
|
2007-07-19 12:40:28 +02:00
|
|
|
}else{
|
|
|
|
return $this->performReadonlyTransformation();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function transform(FormTransformation $trans) {
|
|
|
|
return $trans->transform($this);
|
|
|
|
}
|
|
|
|
|
2007-11-23 02:10:19 +01:00
|
|
|
function hasClass($class){
|
|
|
|
$patten = '/'.strtolower($class).'/i';
|
2007-11-25 22:07:02 +01:00
|
|
|
$subject = strtolower($this->class." ".$this->extraClass());
|
2007-11-23 02:10:19 +01:00
|
|
|
return preg_match($patten, $subject);
|
|
|
|
}
|
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
/**
|
|
|
|
* Returns the field type - used by templates.
|
|
|
|
* The field type is the class name with the word Field dropped off the end, all lowercase.
|
2011-12-22 13:10:57 +01:00
|
|
|
* It's handy for assigning HTML classes. Doesn't signify the <input type> attribute,
|
|
|
|
* see {link getAttributes()}.
|
|
|
|
*
|
2011-03-23 05:12:25 +01:00
|
|
|
* @return string
|
2007-07-19 12:40:28 +02:00
|
|
|
*/
|
2011-03-23 05:12:25 +01:00
|
|
|
function Type() {
|
2011-12-22 13:10:57 +01:00
|
|
|
return strtolower(ereg_replace('Field$', '', $this->class));
|
2011-03-23 05:12:25 +01:00
|
|
|
}
|
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
/**
|
2009-03-17 12:38:52 +01:00
|
|
|
* Construct and return HTML tag.
|
|
|
|
*
|
2011-03-23 05:12:25 +01:00
|
|
|
* @deprecated 3.0 Please define your own FormField template using {@link setFieldTemplate()}
|
|
|
|
* and/or {@link renderFieldTemplate()}
|
|
|
|
*
|
2009-03-17 12:38:52 +01:00
|
|
|
* @todo Transform to static helper method.
|
2007-07-19 12:40:28 +02:00
|
|
|
*/
|
|
|
|
function createTag($tag, $attributes, $content = null) {
|
|
|
|
$preparedAttributes = '';
|
|
|
|
foreach($attributes as $k => $v) {
|
2008-10-07 05:03:00 +02:00
|
|
|
// Note: as indicated by the $k == value item here; the decisions over what to include in the attributes can sometimes get finicky
|
|
|
|
if(!empty($v) || $v === '0' || $k == 'value') $preparedAttributes .= " $k=\"" . Convert::raw2att($v) . "\"";
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|
|
|
|
|
2008-10-03 04:59:38 +02:00
|
|
|
if($content || $tag != 'input') return "<$tag$preparedAttributes>$content</$tag>";
|
2007-07-19 12:40:28 +02:00
|
|
|
else return "<$tag$preparedAttributes />";
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-03-06 03:06:47 +01:00
|
|
|
* javascript handler Functions for each field type by default
|
|
|
|
* formfield doesnt have a validation function
|
|
|
|
*
|
|
|
|
* @todo shouldn't this be an abstract method?
|
2007-07-19 12:40:28 +02:00
|
|
|
*/
|
2009-02-02 00:49:53 +01:00
|
|
|
function jsValidation() {
|
|
|
|
}
|
2008-03-06 03:06:47 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Validation Functions for each field type by default
|
|
|
|
* formfield doesnt have a validation function
|
|
|
|
*
|
|
|
|
* @todo shouldn't this be an abstract method?
|
|
|
|
*/
|
2009-02-02 00:49:53 +01:00
|
|
|
function validate() {
|
|
|
|
return true;
|
|
|
|
}
|
2007-07-19 12:40:28 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Describe this field, provide help text for it.
|
|
|
|
* The function returns this so it can be used like this:
|
|
|
|
* $action = FormAction::create('submit', 'Submit')->describe("Send your changes to be approved")
|
2011-07-04 09:41:15 +02:00
|
|
|
*
|
|
|
|
* @return string Description
|
2007-07-19 12:40:28 +02:00
|
|
|
*/
|
|
|
|
function describe($description) {
|
|
|
|
$this->description = $description;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
function debug() {
|
|
|
|
return "$this->class ($this->name: $this->title : <font style='color:red;'>$this->message</font>) = $this->value";
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This function is used by the template processor. If you refer to a field as a $ variable, it
|
|
|
|
* will return the $Field value.
|
|
|
|
*/
|
|
|
|
function forTemplate() {
|
|
|
|
return $this->Field();
|
|
|
|
}
|
|
|
|
|
2009-03-17 12:38:52 +01:00
|
|
|
/**
|
|
|
|
* @uses Validator->fieldIsRequired()
|
|
|
|
* @return boolean
|
|
|
|
*/
|
2007-07-19 12:40:28 +02:00
|
|
|
function Required() {
|
|
|
|
if($this->form && ($validator = $this->form->Validator)) {
|
|
|
|
return $validator->fieldIsRequired($this->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-08-11 01:17:51 +02:00
|
|
|
/**
|
|
|
|
* Takes a fieldname and converts camelcase to spaced
|
|
|
|
* words. Also resolves combined fieldnames with dot syntax
|
|
|
|
* to spaced words.
|
|
|
|
*
|
2010-04-23 02:11:41 +02:00
|
|
|
* Examples:
|
|
|
|
* - 'TotalAmount' will return 'Total Amount'
|
|
|
|
* - 'Organisation.ZipCode' will return 'Organisation Zip Code'
|
2008-08-11 01:17:51 +02:00
|
|
|
*
|
|
|
|
* @param string $fieldName
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function name_to_label($fieldName) {
|
2008-10-13 00:21:35 +02:00
|
|
|
if(strpos($fieldName, '.') !== false) {
|
2008-08-11 01:17:51 +02:00
|
|
|
$parts = explode('.', $fieldName);
|
|
|
|
$label = $parts[count($parts)-2] . ' ' . $parts[count($parts)-1];
|
|
|
|
} else {
|
|
|
|
$label = $fieldName;
|
|
|
|
}
|
|
|
|
$label = preg_replace("/([a-z]+)([A-Z])/","$1 $2", $label);
|
|
|
|
|
|
|
|
return $label;
|
|
|
|
}
|
|
|
|
|
2008-09-11 02:02:49 +02:00
|
|
|
/**
|
2011-10-28 03:37:27 +02:00
|
|
|
* Set the FieldList that contains this field.
|
2008-09-11 02:02:49 +02:00
|
|
|
*
|
2011-05-11 09:51:54 +02:00
|
|
|
* @param FieldList $containerFieldSet
|
2008-09-11 02:02:49 +02:00
|
|
|
*/
|
|
|
|
function setContainerFieldSet($containerFieldSet) {
|
|
|
|
$this->containerFieldSet = $containerFieldSet;
|
|
|
|
}
|
|
|
|
|
|
|
|
function rootFieldSet() {
|
|
|
|
if(is_object($this->containerFieldSet)) return $this->containerFieldSet->rootFieldSet();
|
|
|
|
else user_error("rootFieldSet() called on $this->class object without a containerFieldSet", E_USER_ERROR);
|
|
|
|
}
|
|
|
|
|
2011-03-23 05:12:25 +01:00
|
|
|
}
|