Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

ENHANCEMENT: populate FormField:: on the fly based on class name of f…

…ield rather than requiring explict definition.
  • Loading branch information...
commit 07d2d5273ac890e9a5ea81a4bf83b5ef001e3bb6 1 parent 907568b
Will Rossiter wilr authored
Showing with 270 additions and 219 deletions.
  1. +2 −2 css/GridField.css
  2. +2 −15 forms/CheckboxField.php
  3. +2 −5 forms/CheckboxSetField.php
  4. +5 −33 forms/CompositeField.php
  5. +1 −3 forms/DropdownField.php
  6. +0 −23 forms/FieldGroup.php
  7. +5 −4 forms/FileField.php
  8. +0 −2  forms/FileIFrameField.php
  9. +4 −3 forms/FormAction.php
  10. +144 −59 forms/FormField.php
  11. +2 −3 forms/HeaderField.php
  12. +1 −2  forms/HiddenField.php
  13. +0 −2  forms/LabelField.php
  14. +7 −2 forms/ListboxField.php
  15. +8 −4 forms/OptionsetField.php
  16. +7 −6 forms/SelectionGroup.php
  17. +3 −3 forms/TabSet.php
  18. +6 −7 forms/TextField.php
  19. +8 −8 forms/TextareaField.php
  20. +4 −4 forms/ToggleCompositeField.php
  21. +3 −6 forms/UploadField.php
  22. +0 −2  forms/gridfield/GridFieldDetailForm.php
  23. +4 −4 scss/GridField.scss
  24. 0  templates/forms/{CheckboxFieldHolder.ss → CheckboxField_holder.ss}
  25. +5 −0 templates/forms/CheckboxField_holder_small.ss
  26. +0 −11 templates/forms/CheckboxSetField_Select.ss
  27. +4 −4 templates/forms/CompositeField.ss
  28. +15 −0 templates/forms/CompositeField_holder.ss
  29. +15 −0 templates/forms/CompositeField_holder_small.ss
  30. +1 −1  templates/forms/{FieldGroupField.ss → FieldGroup.ss}
  31. 0  templates/forms/{FieldGroupHolder.ss → FieldGroup_holder.ss}
  32. 0  templates/forms/{FieldHolder.ss → FormField_holder.ss}
  33. +11 −0 templates/forms/FormField_holder_small.ss
  34. 0  templates/{ → forms}/ToggleCompositeField.ss
  35. +1 −1  tests/forms/CompositeFieldTest.php
4 css/GridField.css
View
@@ -65,10 +65,10 @@
.cms table.ss-gridfield-table tr th button.ss-gridfield-sort:hover { background-position: right -34px; }
.cms table.ss-gridfield-table tr th button.ss-gridfield-sort.ss-gridfield-sorted-desc { background-position: right -72px; }
.cms table.ss-gridfield-table tr th button.ss-gridfield-sort.ss-gridfield-sorted-asc { background-position: right -116px; }
-.cms table.ss-gridfield-table tr th button.ss-gridfield-button-filter.ss-ui-button { position: absolute; right: 5px; top: -28px; display: block; text-indent: -9999em; width: 30px; height: 28px; border-top-left-radius: 0px; border-bottom-left-radius: 0px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-width: 1px; border-color: #9a9a9a; background: url(../images/icons/filter-icons.png) no-repeat -40px 6px, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffffff), color-stop(100%, #d9d9d9)); background: url(../images/icons/filter-icons.png) no-repeat -40px 6px, -webkit-linear-gradient(#ffffff, #d9d9d9); background: url(../images/icons/filter-icons.png) no-repeat -40px 6px, -moz-linear-gradient(#ffffff, #d9d9d9); background: url(../images/icons/filter-icons.png) no-repeat -40px 6px, -o-linear-gradient(#ffffff, #d9d9d9); background: url(../images/icons/filter-icons.png) no-repeat -40px 6px, -ms-linear-gradient(#ffffff, #d9d9d9); background: url(../images/icons/filter-icons.png) no-repeat -40px 6px, linear-gradient(#ffffff, #d9d9d9); }
+.cms table.ss-gridfield-table tr th button.ss-gridfield-button-filter.ss-ui-button { position: absolute; top: 0; right: 0; display: block; text-indent: -9999em; width: 30px; height: 28px; border-top-left-radius: 0px; border-bottom-left-radius: 0px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-width: 1px; border-color: #9a9a9a; background: url(../images/icons/filter-icons.png) no-repeat -40px 6px, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffffff), color-stop(100%, #d9d9d9)); background: url(../images/icons/filter-icons.png) no-repeat -40px 6px, -webkit-linear-gradient(#ffffff, #d9d9d9); background: url(../images/icons/filter-icons.png) no-repeat -40px 6px, -moz-linear-gradient(#ffffff, #d9d9d9); background: url(../images/icons/filter-icons.png) no-repeat -40px 6px, -o-linear-gradient(#ffffff, #d9d9d9); background: url(../images/icons/filter-icons.png) no-repeat -40px 6px, -ms-linear-gradient(#ffffff, #d9d9d9); background: url(../images/icons/filter-icons.png) no-repeat -40px 6px, linear-gradient(#ffffff, #d9d9d9); }
.cms table.ss-gridfield-table tr th button.ss-gridfield-button-filter.ss-ui-button.hover-alike:active { background: url(../images/icons/filter-icons.png) no-repeat -16px 6px, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #4199cd), color-stop(100%, #2e7ead)); background: url(../images/icons/filter-icons.png) no-repeat -16px 6px, -webkit-linear-gradient(#4199cd, #2e7ead); background: url(../images/icons/filter-icons.png) no-repeat -16px 6px, -moz-linear-gradient(#4199cd, #2e7ead); background: url(../images/icons/filter-icons.png) no-repeat -16px 6px, -o-linear-gradient(#4199cd, #2e7ead); background: url(../images/icons/filter-icons.png) no-repeat -16px 6px, -ms-linear-gradient(#4199cd, #2e7ead); background: url(../images/icons/filter-icons.png) no-repeat -16px 6px, linear-gradient(#4199cd, #2e7ead); -moz-box-shadow: inset 0 1px 3px #17181a, 0 1px 0 rgba(255, 255, 255, 0.6); -webkit-box-shadow: inset 0 1px 3px #17181a, 0 1px 0 rgba(255, 255, 255, 0.6); -o-box-shadow: inset 0 1px 3px #17181a, 0 1px 0 rgba(255, 255, 255, 0.6); box-shadow: inset 0 1px 3px #17181a, 0 1px 0 rgba(255, 255, 255, 0.6); }
.cms table.ss-gridfield-table tr th button.ss-gridfield-button-filter.ss-ui-button.hover-alike { background: url(../images/icons/filter-icons.png) no-repeat -16px 6px, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #4199cd), color-stop(100%, #2e7ead)); background: url(../images/icons/filter-icons.png) no-repeat -16px 6px, -webkit-linear-gradient(#4199cd, #2e7ead); background: url(../images/icons/filter-icons.png) no-repeat -16px 6px, -moz-linear-gradient(#4199cd, #2e7ead); background: url(../images/icons/filter-icons.png) no-repeat -16px 6px, -o-linear-gradient(#4199cd, #2e7ead); background: url(../images/icons/filter-icons.png) no-repeat -16px 6px, -ms-linear-gradient(#4199cd, #2e7ead); background: url(../images/icons/filter-icons.png) no-repeat -16px 6px, linear-gradient(#4199cd, #2e7ead); }
-.cms table.ss-gridfield-table tr th button.ss-gridfield-button-reset.ss-ui-button { position: absolute; right: 34px; top: -28px; display: block; text-indent: -9999em; width: 30px; height: 28px; float: right; border-radius: 0px; border-bottom-width: 1px; border-color: #9a9a9a; background: url(../images/icons/filter-icons.png) no-repeat 8px 5px, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffffff), color-stop(100%, #d9d9d9)); background: url(../images/icons/filter-icons.png) no-repeat 8px 5px, -webkit-linear-gradient(#ffffff, #d9d9d9); background: url(../images/icons/filter-icons.png) no-repeat 8px 5px, -moz-linear-gradient(#ffffff, #d9d9d9); background: url(../images/icons/filter-icons.png) no-repeat 8px 5px, -o-linear-gradient(#ffffff, #d9d9d9); background: url(../images/icons/filter-icons.png) no-repeat 8px 5px, -ms-linear-gradient(#ffffff, #d9d9d9); background: url(../images/icons/filter-icons.png) no-repeat 8px 5px, linear-gradient(#ffffff, #d9d9d9); }
+.cms table.ss-gridfield-table tr th button.ss-gridfield-button-reset.ss-ui-button { position: absolute; right: 29px; top: 0; display: block; text-indent: -9999em; width: 30px; height: 28px; float: right; border-radius: 0px; border-bottom-width: 1px; border-color: #9a9a9a; background: url(../images/icons/filter-icons.png) no-repeat 8px 5px, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffffff), color-stop(100%, #d9d9d9)); background: url(../images/icons/filter-icons.png) no-repeat 8px 5px, -webkit-linear-gradient(#ffffff, #d9d9d9); background: url(../images/icons/filter-icons.png) no-repeat 8px 5px, -moz-linear-gradient(#ffffff, #d9d9d9); background: url(../images/icons/filter-icons.png) no-repeat 8px 5px, -o-linear-gradient(#ffffff, #d9d9d9); background: url(../images/icons/filter-icons.png) no-repeat 8px 5px, -ms-linear-gradient(#ffffff, #d9d9d9); background: url(../images/icons/filter-icons.png) no-repeat 8px 5px, linear-gradient(#ffffff, #d9d9d9); }
.cms table.ss-gridfield-table tr th button.ss-gridfield-button-reset.ss-ui-button.filtered:hover { background: url(../images/icons/filter-icons.png) no-repeat 8px -17px, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ff0000), color-stop(100%, #cc0000)); background: url(../images/icons/filter-icons.png) no-repeat 8px -17px, -webkit-linear-gradient(#ff0000, #cc0000); background: url(../images/icons/filter-icons.png) no-repeat 8px -17px, -moz-linear-gradient(#ff0000, #cc0000); background: url(../images/icons/filter-icons.png) no-repeat 8px -17px, -o-linear-gradient(#ff0000, #cc0000); background: url(../images/icons/filter-icons.png) no-repeat 8px -17px, -ms-linear-gradient(#ff0000, #cc0000); background: url(../images/icons/filter-icons.png) no-repeat 8px -17px, linear-gradient(#ff0000, #cc0000); }
.cms table.ss-gridfield-table tr th button.ss-gridfield-button-reset.ss-ui-button.filtered:active { background: url(../images/icons/filter-icons.png) no-repeat 8px -17px, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ff0000), color-stop(100%, #cc0000)); background: url(../images/icons/filter-icons.png) no-repeat 8px -17px, -webkit-linear-gradient(#ff0000, #cc0000); background: url(../images/icons/filter-icons.png) no-repeat 8px -17px, -moz-linear-gradient(#ff0000, #cc0000); background: url(../images/icons/filter-icons.png) no-repeat 8px -17px, -o-linear-gradient(#ff0000, #cc0000); background: url(../images/icons/filter-icons.png) no-repeat 8px -17px, -ms-linear-gradient(#ff0000, #cc0000); background: url(../images/icons/filter-icons.png) no-repeat 8px -17px, linear-gradient(#ff0000, #cc0000); -moz-box-shadow: inset 0 1px 3px #17181a, 0 1px 0 rgba(255, 255, 255, 0.6); -webkit-box-shadow: inset 0 1px 3px #17181a, 0 1px 0 rgba(255, 255, 255, 0.6); -o-box-shadow: inset 0 1px 3px #17181a, 0 1px 0 rgba(255, 255, 255, 0.6); box-shadow: inset 0 1px 3px #17181a, 0 1px 0 rgba(255, 255, 255, 0.6); }
.cms table.ss-gridfield-table tr th input.ss-gridfield-sort { padding: 2px; }
17 forms/CheckboxField.php
View
@@ -1,15 +1,12 @@
<?php
/**
* Single checkbox field.
+ *
* @package forms
* @subpackage fields-basic
*/
class CheckboxField extends FormField {
- protected $template = 'CheckboxField';
-
- protected $fieldHolderTemplate = 'CheckboxFieldHolder';
-
function setValue($value) {
$this->value = ($value) ? 1 : 0;
return $this;
@@ -23,17 +20,6 @@ function Value() {
return ($this->value) ? 1 : 0;
}
- /**
- * Returns a restricted field holder used within things like FieldGroups
- */
- function SmallFieldHolder() {
- $result = $this->Field();
- if($t = $this->Title()) {
- $result .= "<label for=\"" . $this->id() ."\">$t</label> ";
- }
- return $result;
- }
-
function getAttributes() {
$attrs = parent::getAttributes();
$attrs['value'] = 1;
@@ -65,6 +51,7 @@ function performDisabledTransformation() {
/**
* Readonly version of a checkbox field - "Yes" or "No".
+ *
* @package forms
* @subpackage fields-basic
*/
7 forms/CheckboxSetField.php
View
@@ -33,11 +33,9 @@
* @subpackage fields-basic
*/
class CheckboxSetField extends OptionsetField {
-
- protected $template = 'CheckboxSetField';
/**
- * @var Array
+ * @var array
*/
protected $defaultItems = array();
@@ -130,7 +128,7 @@ function Field($properties = array()) {
$properties = array_merge($properties, array('Options' => new ArrayList($options)));
- return $this->customise($properties)->renderWith($this->getTemplate());
+ return $this->customise($properties)->renderWith($this->getTemplates());
}
/**
@@ -288,5 +286,4 @@ function Type() {
function ExtraOptions() {
return FormField::ExtraOptions();
}
-
}
38 forms/CompositeField.php
View
@@ -1,8 +1,11 @@
<?php
/**
* Base class for all fields that contain other fields.
- * Implements sequentialisation - so that when we're saving / loading data, we can populate
- * a tabbed form properly. All of the children are stored in $this->children
+ *
+ * Implements sequentialisation - so that when we're saving / loading data, we
+ * can populate a tabbed form properly. All of the children are stored in
+ * $this->children
+ *
* @package forms
* @subpackage fields-structural
*/
@@ -34,11 +37,6 @@ class CompositeField extends FormField {
protected $tag = 'div';
/**
- * @var string
- */
- protected $template = "CompositeField";
-
- /**
* @var String Optional description for this set of fields.
* If the {@link $tag} property is set to use a 'fieldset', this will be
* rendered as a <legend> tag, otherwise its a 'title' attribute.
@@ -152,32 +150,6 @@ function getAttributes() {
);
}
- public function Field($properties = array()) {
- $props = $this->customise($properties);
-
- return $props->renderWith($this->getTemplate());
- }
-
- /**
- * @param array
- */
- function FieldHolder($properties = array()) {
- $props = $this->customise($properties);
-
- return $props->renderWith($this->getTemplate());
- }
-
- /**
- * Returns the fields in the restricted field holder.
- *
- * @param array
- */
- function SmallFieldHolder($properties = array()) {
- $obj = ($properties) ? $this->customise($properties) : $this;
-
- return $obj->renderWith($this->getTemplate());
- }
-
/**
* Add all of the non-composite fields contained within this field to the
* list.
4 forms/DropdownField.php
View
@@ -75,8 +75,6 @@
* @subpackage fields-basic
*/
class DropdownField extends FormField {
-
- protected $template = 'DropdownField';
/**
* @var boolean $source Associative or numeric array of all dropdown items,
@@ -158,7 +156,7 @@ function Field($properties = array()) {
$properties = array_merge($properties, array('Options' => new ArrayList($options)));
- return $this->customise($properties)->renderWith($this->getTemplate());
+ return parent::Field($properties);
}
function getAttributes() {
23 forms/FieldGroup.php
View
@@ -85,29 +85,6 @@ function Name(){
return preg_replace("/[^a-zA-Z0-9]+/", "", $this->title);
}
-
- /**
- * Generates the field HTML with the HTML for child {@link FormField}
- *
- * @param array $properties custom properties for the template
- */
- function Field($properties = array()) {
- $props = $this->customise(new ArrayData($properties));
-
- return $props->renderWith('FieldGroupField');
- }
-
- /**
- * Generates the field HTML with the HTML for child {@link FormField}
- *
- * @param array $properties custom properties for the template
- */
- function FieldHolder($properties = array()) {
- $props = $this->customise(new ArrayData($properties));
-
- return $props->renderWith('FieldGroupHolder');
- }
-
/**
* Set an odd/even class
*
9 forms/FileField.php
View
@@ -42,8 +42,6 @@
* @subpackage fields-files
*/
class FileField extends FormField {
-
- protected $template = 'FileField';
/**
* Restrict filesize for either all filetypes
@@ -112,8 +110,11 @@ function __construct($name, $title = null, $value = null) {
}
public function Field($properties = array()) {
- $properties = array_merge($properties, array('MaxFileSize' => $this->getValidator()->getAllowedMaxFileSize()));
- return $this->customise($properties)->renderWith($this->getTemplate());
+ $properties = array_merge($properties, array(
+ 'MaxFileSize' => $this->getValidator()->getAllowedMaxFileSize()
+ ));
+
+ return parent::Field($properties);
}
function getAttributes() {
2  forms/FileIFrameField.php
View
@@ -12,8 +12,6 @@
*/
class FileIFrameField extends FileField {
- protected $template = 'FileIFrameField';
-
public static $allowed_actions = array (
'iframe',
'EditFileForm',
7 forms/FormAction.php
View
@@ -20,8 +20,6 @@
*/
class FormAction extends FormField {
- protected $template = 'FormAction';
-
protected $action;
/**
@@ -36,12 +34,14 @@ class FormAction extends FormField {
/**
* Create a new action button.
+ *
* @param action The method to call when the button is clicked
* @param title The label on the button
* @param form The parent form, auto-set when the field is placed inside a form
*/
function __construct($action, $title = "", $form = null) {
$this->action = "action_$action";
+
parent::__construct($this->action, $title, null, $form);
}
@@ -67,7 +67,8 @@ function Field($properties = array()) {
'UseButtonTag' => $this->useButtonTag
)
);
- return $this->customise($properties)->renderWith($this->getTemplate());
+
+ return parent::Field($properties);
}
function FieldHolder($properties = array()) {
203 forms/FormField.php
View
@@ -57,31 +57,35 @@ class FormField extends RequestHandler {
protected $containerFieldSet;
/**
- * @var $readonly boolean
+ * @var boolean
*/
protected $readonly = false;
/**
- * @var $disabled boolean
+ * @var boolean
*/
protected $disabled = false;
/**
- * @var String
- */
- protected $template = 'FormField';
-
- /**
- * @var Custom Validation Message for the Field
+ * @var string custom validation message for the Field
*/
protected $customValidationMessage = "";
-
+
/**
- * Template name to render this FormField field holder into.
+ * 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
*/
- protected $fieldHolderTemplate = 'FieldHolder';
-
+ protected
+ $template,
+ $fieldHolderTemplate,
+ $smallFieldHolderTemplate;
+
/**
* @var array All attributes on the form field (not the field holder).
* Partially determined based on other instance properties, please use {@link getAttributes()}.
@@ -268,7 +272,7 @@ public function getTabIndex() {
* Uses {@link Message()} and {@link MessageType()} to add validatoin
* error classes which can be used to style the contained tags.
*
- * @return String CSS-classnames
+ * @return string CSS-classnames
*/
function extraClass() {
$classes = array();
@@ -323,8 +327,8 @@ function removeExtraClass($class) {
* CreditCardField, CurrencyField, DateField, DatetimeField, FieldGroup, GridField, HtmlEditorField,
* ImageField, ImageFormAction, InlineFormAction, ListBoxField, etc.
*
- * @param String
- * @param String
+ * @param string
+ * @param string
*/
function setAttribute($name, $value) {
$this->attributes[$name] = $value;
@@ -335,7 +339,7 @@ function setAttribute($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
+ * @return string
*/
function getAttribute($name) {
$attrs = $this->getAttributes();
@@ -355,13 +359,14 @@ function getAttributes() {
'disabled' => $this->isDisabled(),
'title' => $this->getDescription(),
);
+
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
+ * @return string HTML attributes, ready for insertion into an HTML tag
*/
function getAttributesHTML($attrs = null) {
$exclude = (is_string($attrs)) ? func_get_args() : null;
@@ -431,28 +436,7 @@ function setForm($form) {
function getForm() {
return $this->form;
}
-
- /**
- * @return String
- */
- public function getFieldHolderTemplate() {
- return $this->fieldHolderTemplate;
- }
-
- /**
- * 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
- */
- public function setFieldHolderTemplate($template) {
- $this->fieldHolderTemplate = $template;
- return $this;
- }
-
+
/**
* Return TRUE if security token protection is enabled on the parent {@link Form}.
*
@@ -461,6 +445,7 @@ public function setFieldHolderTemplate($template) {
public function securityTokenEnabled() {
$form = $this->getForm();
if(!$form) return false;
+
return $form->getSecurityToken()->isEnabled();
}
@@ -471,6 +456,7 @@ public function securityTokenEnabled() {
function setError($message, $messageType) {
$this->message = $message;
$this->messageType = $messageType;
+
return $this;
}
@@ -479,10 +465,11 @@ function setError($message, $messageType) {
* format of Please Fill In XXX. Different from setError() as
* that appends it to the standard error messaging
*
- * @param String Message for the error
+ * @param string Message for the error
*/
public function setCustomValidationMessage($msg) {
$this->customValidationMessage = $msg;
+
return $this;
}
@@ -492,7 +479,7 @@ public function setCustomValidationMessage($msg) {
* error is defined on {@link Validator}.
*
* @todo Should the default error message be stored here instead
- * @return String
+ * @return string
*/
public function getCustomValidationMessage() {
return $this->customValidationMessage;
@@ -503,21 +490,66 @@ public function getCustomValidationMessage() {
* Caution: Not consistently implemented in all subclasses,
* please check the {@link Field()} method on the subclass for support.
*
- * @param String
+ * @param string
*/
function setTemplate($template) {
$this->template = $template;
+
return $this;
}
/**
- * @return String
+ * @return string
*/
function getTemplate() {
return $this->template;
}
/**
+ * @return string
+ */
+ public function getFieldHolderTemplate() {
+ return $this->fieldHolderTemplate;
+ }
+
+ /**
+ * 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
+ */
+ public function setFieldHolderTemplate($template) {
+ $this->fieldHolderTemplate = $template;
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getSmallFieldHolderTemplate() {
+ return $this->smallFieldHolderTemplate;
+ }
+
+ /**
+ * Set name of template (without path or extension) for the small 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
+ */
+ public function setSmallFieldHolderTemplate($template) {
+ $this->smallFieldHolderTemplate = $template;
+
+ return $this;
+ }
+
+ /**
* 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"
@@ -529,7 +561,8 @@ function getTemplate() {
*/
function Field($properties = array()) {
$obj = ($properties) ? $this->customise($properties) : $this;
- return $obj->renderWith($this->getTemplate());
+
+ return $obj->renderWith($this->getTemplates());
}
/**
@@ -544,29 +577,81 @@ function Field($properties = array()) {
*/
function FieldHolder($properties = array()) {
$obj = ($properties) ? $this->customise($properties) : $this;
- return $obj->renderWith($this->getFieldHolderTemplate());
+
+ return $obj->renderWith($this->getFieldHolderTemplates());
}
/**
* Returns a restricted field holder used within things like FieldGroups.
+ *
+ * @param array $properties
+ *
+ * @return string
*/
- function SmallFieldHolder() {
- $result = '';
- // set label
- if($title = $this->RightTitle()){
- $result .= "<label class=\"right\" for=\"" . $this->id() . "\">{$title}</label>\n";
- } elseif($title = $this->LeftTitle()) {
- $result .= "<label class=\"left\" for=\"" . $this->id() . "\">{$title}</label>\n";
- } elseif($title = $this->Title()) {
- $result .= "<label for=\"" . $this->id() . "\">{$title}</label>\n";
- }
+ function SmallFieldHolder($properties = array()) {
+ $obj = ($properties) ? $this->customise($properties) : $this;
- $result .= $this->Field();
+ return $obj->renderWith($this->getSmallFieldHolderTemplates());
+ }
+
+ /**
+ * Returns an array of templates to use for rendering {@link FieldH}
+ *
+ * @return array
+ */
+ public function getTemplates() {
+ return $this->_templates($this->getTemplate());
+ }
+
+ /**
+ * Returns an array of templates to use for rendering {@link FieldHolder}
+ *
+ * @return array
+ */
+ public function getFieldHolderTemplates() {
+ return $this->_templates(
+ $this->getFieldHolderTemplate(),
+ '_holder'
+ );
+ }
+
+ /**
+ * Returns an array of templates to use for rendering {@link SmallFieldHolder}
+ *
+ * @return array
+ */
+ public function getSmallFieldHolderTemplates() {
+ return $this->_templates(
+ $this->getSmallFieldHolderTemplate(),
+ '_holder_small'
+ );
+ }
- return $result;
- }
/**
+ * Generate an array of classname strings to use for rendering this form
+ * field into HTML
+ *
+ * @param string $custom custom template (if set)
+ * @param string $suffix template suffix
+ *
+ * @return array $stack a stack of
+ */
+ private function _templates($custom = null, $suffix = null) {
+ $matches = array();
+
+ foreach(array_reverse(ClassInfo::ancestry($this)) as $className) {
+ $matches[] = $className . $suffix;
+
+ if($className == "FormField") break;
+ }
+
+ if($custom) array_unshift($matches, $custom);
+
+ return $matches;
+ }
+
+ /**
* Returns true if this field is a composite field.
* To create composite field types, you should subclass {@link CompositeField}.
*/
@@ -722,7 +807,7 @@ function setDescription($description) {
}
/**
- * @return String
+ * @return string
*/
function getDescription() {
return $this->description;
5 forms/HeaderField.php
View
@@ -1,13 +1,13 @@
<?php
/**
* Field that generates a heading tag.
+ *
* This can be used to add extra text in your forms.
+ *
* @package forms
* @subpackage fields-dataless
*/
class HeaderField extends DatalessField {
-
- protected $template = 'HeaderField';
/**
* @var int $headingLevel The level of the <h1> to <h6> HTML tag. Default: 2
@@ -53,5 +53,4 @@ function getAttributes() {
function Type() {
return null;
}
-
}
3  forms/HiddenField.php
View
@@ -1,13 +1,12 @@
<?php
/**
* Hidden field.
+ *
* @package forms
* @subpackage fields-dataless
*/
class HiddenField extends FormField {
- protected $template = 'HiddenField';
-
function FieldHolder($properties = array()) {
return $this->Field($properties);
}
2  forms/LabelField.php
View
@@ -8,8 +8,6 @@
* @subpackage fields-dataless
*/
class LabelField extends DatalessField {
-
- protected $template = 'LabelField';
/**
* @param string $name
9 forms/ListboxField.php
View
@@ -64,6 +64,7 @@ class ListboxField extends DropdownField {
function __construct($name, $title = '', $source = array(), $value = '', $size = null, $multiple = false) {
if($size) $this->size = $size;
if($multiple) $this->multiple = $multiple;
+
parent::__construct($name, $title, $source, $value);
}
@@ -96,8 +97,12 @@ function Field($properties = array()) {
));
}
}
- $properties = array_merge($properties, array('Options' => new ArrayList($options)));
- return $this->customise($properties)->renderWith($this->getTemplate());
+
+ $properties = array_merge($properties, array(
+ 'Options' => new ArrayList($options)
+ ));
+
+ return $this->customise($properties)->renderWith($this->getTemplates());
}
function getAttributes() {
12 forms/OptionsetField.php
View
@@ -55,8 +55,6 @@
* @subpackage fields-basic
*/
class OptionsetField extends DropdownField {
-
- protected $template = 'OptionsetField';
/**
* @var Array
@@ -67,6 +65,7 @@ function Field($properties = array()) {
$source = $this->getSource();
$odd = 0;
$options = array();
+
if($source) {
foreach($source as $value => $title) {
$itemID = $this->ID() . '_' . preg_replace('/[^a-zA-Z0-9]/', '', $value);
@@ -86,9 +85,13 @@ function Field($properties = array()) {
}
}
- $properties = array_merge($properties, array('Options' => new ArrayList($options)));
+ $properties = array_merge($properties, array(
+ 'Options' => new ArrayList($options)
+ ));
- return $this->customise($properties)->renderWith($this->getTemplate());
+ return $this->customise($properties)->renderWith(
+ $this->getTemplates()
+ );
}
function performReadonlyTransformation() {
@@ -97,6 +100,7 @@ function performReadonlyTransformation() {
$field = new LookupField($this->name, $this->title ? $this->title : '', $items, $this->value);
$field->setForm($this->form);
$field->setReadonly(true);
+
return $field;
}
13 forms/SelectionGroup.php
View
@@ -1,15 +1,15 @@
<?php
/**
- * SelectionGroup represents a number of fields that are selectable by a radio button that appears at
- * the beginning of each item. Using CSS, you can configure the field to only display its contents if
- * the corresponding radio button is selected.
+ * SelectionGroup represents a number of fields that are selectable by a radio
+ * button that appears at the beginning of each item. Using CSS, you can
+ * configure the field to only display its contents if the corresponding radio
+ * button is selected.
+ *
* @package forms
* @subpackage fields-structural
*/
class SelectionGroup extends CompositeField {
- protected $template = "SelectionGroup";
-
/**
* Create a new selection group.
* @param name The field name of the selection group.
@@ -59,6 +59,7 @@ function FieldList() {
$firstSelected = $checked ="";
}
+
return new ArrayList($newItems);
}
@@ -73,7 +74,7 @@ function FieldHolder($properties = array()) {
$obj = $properties ? $this->customise($properties) : $this;
- return $obj->renderWith($this->template);
+ return $obj->renderWith($this->getFieldHolderTemplates());
}
}
6 forms/TabSet.php
View
@@ -27,8 +27,6 @@
*/
class TabSet extends CompositeField {
- protected $template = "TabSetFieldHolder";
-
/**
* @param string $name Identifier
* @param string $title (Optional) Natural language title of the tabset
@@ -81,7 +79,8 @@ public function FieldHolder($properties = array()) {
Requirements::javascript(SAPPHIRE_DIR . '/javascript/TabSet.js');
$obj = $properties ? $this->customise($properties) : $this;
- return $obj->renderWith($this->template);
+
+ return $obj->renderWith($this->getFieldHolderTemplates());
}
/**
@@ -90,6 +89,7 @@ public function FieldHolder($properties = array()) {
public function Tabs() {
return $this->children;
}
+
public function setTabs($children){
$this->children = $children;
}
13 forms/TextField.php
View
@@ -1,15 +1,14 @@
<?php
/**
* Text input field.
+ *
* @package forms
* @subpackage fields-basic
*/
class TextField extends FormField {
- protected $template = 'TextField';
-
/**
- * @var Int
+ * @var int
*/
protected $maxLength;
@@ -23,15 +22,16 @@ function __construct($name, $title = null, $value = '', $maxLength = null, $form
}
/**
- * @param Int $length
+ * @param int $length
*/
function setMaxLength($length) {
$this->maxLength = $length;
+
return $this;
}
/**
- * @return Int
+ * @return int
*/
function getMaxLength() {
return $this->maxLength;
@@ -50,6 +50,5 @@ function getAttributes() {
function InternallyLabelledField() {
if(!$this->value) $this->value = $this->Title();
return $this->Field();
- }
-
+ }
}
16 forms/TextareaField.php
View
@@ -21,16 +21,14 @@
* @subpackage fields-basic
*/
class TextareaField extends FormField {
-
- protected $template = 'TextareaField';
-
+
/**
- * @var Int Visible number of text lines.
+ * @var int Visible number of text lines.
*/
protected $rows = 5;
/**
- * @var Int Width of the text area (in average character widths)
+ * @var int Width of the text area (in average character widths)
*/
protected $cols = 20;
@@ -60,13 +58,14 @@ function getAttributes() {
}
function getTemplate() {
- return ($this->isReadonly()) ? "{$this->template}_Readonly" : $this->template;
+ return ($this->isReadonly()) ? "{$this->template}_readonly" : $this->template;
}
/**
- * Performs a readonly transformation on this field. You should still be able
- * to copy from this field, and it should still send when you submit
+ * Performs a readonly transformation on this field. You should still be
+ * able to copy from this field, and it should still send when you submit
* the form it's attached to.
+ *
* The element shouldn't be both disabled and readonly at the same time.
*/
function performReadonlyTransformation() {
@@ -80,6 +79,7 @@ function performReadonlyTransformation() {
* Performs a disabled transformation on this field. You shouldn't be able to
* copy from this field, and it should not send any data when you submit the
* form it's attached to.
+ *
* The element shouldn't be both disabled and readonly at the same time.
*/
function performDisabledTransformation() {
8 forms/ToggleCompositeField.php
View
@@ -1,13 +1,12 @@
<?php
/**
* Allows visibility of a group of fields to be toggled using '+' and '-' icons
+ *
* @package forms
* @subpackage fields-structural
*/
class ToggleCompositeField extends CompositeField {
- protected $template = "ToggleCompositeField";
-
/**
* @var $headingLevel int
*/
@@ -28,7 +27,8 @@ public function FieldHolder($properties = array()) {
Requirements::javascript(SAPPHIRE_DIR . "/javascript/ToggleCompositeField.js");
$obj = $properties ? $this->customise($properties) : $this;
- return $obj->renderWith($this->template);
+
+ return $obj->renderWith($this->getTemplates());
}
/**
@@ -41,7 +41,7 @@ public function startClosed($bool) {
}
/**
- * @return String
+ * @return string
*/
public function HeadingLevel() {
return $this->headingLevel;
9 forms/UploadField.php
View
@@ -47,11 +47,6 @@ class UploadField extends FileField {
/**
* @var String
*/
- protected $template = 'UploadField';
-
- /**
- * @var String
- */
protected $templateFileButtons = 'UploadField_FileButtons';
/**
@@ -375,13 +370,15 @@ public function Field($properties = array()) {
if (is_numeric($config['maxNumberOfFiles']) && $this->getItems()->count()) {
$configOverwrite['maxNumberOfFiles'] = $config['maxNumberOfFiles'] - $this->getItems()->count();
}
+
$config = array_merge($config, $this->ufConfig, $configOverwrite);
+
return $this->customise(array(
'configString' => str_replace('"', "'", Convert::raw2json($config)),
'config' => new ArrayData($config),
'multiple' => $config['maxNumberOfFiles'] !== 1,
'displayInput' => (!isset($configOverwrite['maxNumberOfFiles']) || $configOverwrite['maxNumberOfFiles'])
- ))->renderWith($this->getTemplate());
+ ))->renderWith($this->getTemplates());
}
/**
2  forms/gridfield/GridFieldDetailForm.php
View
@@ -12,8 +12,6 @@
*/
class GridFieldDetailForm implements GridField_URLHandler {
-
-
/**
* @var String
*/
8 scss/GridField.scss
View
@@ -375,8 +375,8 @@ $gf_grid_x: 16px;
}
&.ss-gridfield-button-filter.ss-ui-button{
position:absolute;
- right:5px; //positions filter button in correct position on top of input field
- top:-28px;
+ top: 0;
+ right: 0;
display:block;
text-indent:-9999em;
width:30px;
@@ -412,8 +412,8 @@ $gf_grid_x: 16px;
}
&.ss-gridfield-button-reset.ss-ui-button{
position:absolute;
- right:34px; //positions reset button in correct position on top of input field and to the left of the filter button
- top:-28px;
+ right: 29px;
+ top: 0;
display:block;
text-indent:-9999em;
width:30px;
0  templates/forms/CheckboxFieldHolder.ss → templates/forms/CheckboxField_holder.ss
View
File renamed without changes
5 templates/forms/CheckboxField_holder_small.ss
View
@@ -0,0 +1,5 @@
+<% if $Title %>
+ <label class="checkboxfield-small" <% if ID %>for="$ID"<% end_if %>>$Title</label>
+<% end_if %>
+
+$Field
11 templates/forms/CheckboxSetField_Select.ss
View
@@ -1,11 +0,0 @@
-<%-- Renders a CheckboxField with $multiple=true as a select element which can save into relations.--%>
-<%-- TODO Make relation saving available on ListboxField --%>
-<select id="$ID" class="$extraClass" name="$Name[]" multiple="true">
- <% if Options.Count %>
- <% control Options %>
- <option class="$Class" value="$Value"<% if isChecked %> selected="selected"<% end_if %>>
- $Title
- </option>
- <% end_control %>
- <% end_if %>
-</select>
8 templates/forms/CompositeField.ss
View
@@ -1,4 +1,4 @@
-<$Tag class="CompositeField $extraClass <% if ColumnCount %>multi-column<% end_if %>">
+<$Tag class="CompositeField $extraClass <% if ColumnCount %>multicolumn<% end_if %>">
<% if $Tag == 'fieldset' && $Legend %>
<legend>$Legend</legend>
<% end_if %>
@@ -6,10 +6,10 @@
<% loop FieldList %>
<% if ColumnCount %>
<div class="column-{$ColumnCount} $FirstLast">
- $FieldHolder
+ $Field
</div>
<% else %>
- $FieldHolder
+ $Field
<% end_if %>
<% end_loop %>
-</$Tag>
+</$Tag>
15 templates/forms/CompositeField_holder.ss
View
@@ -0,0 +1,15 @@
+<$Tag class="CompositeField $extraClass <% if ColumnCount %>multicolumn<% end_if %>">
+ <% if $Tag == 'fieldset' && $Legend %>
+ <legend>$Legend</legend>
+ <% end_if %>
+
+ <% loop FieldList %>
+ <% if ColumnCount %>
+ <div class="column-{$ColumnCount} $FirstLast">
+ $FieldHolder
+ </div>
+ <% else %>
+ $FieldHolder
+ <% end_if %>
+ <% end_loop %>
+</$Tag>
15 templates/forms/CompositeField_holder_small.ss
View
@@ -0,0 +1,15 @@
+<$Tag class="field CompositeField $extraClass <% if ColumnCount %>multicolumn<% end_if %>">
+ <% if $Tag == 'fieldset' && $Legend %>
+ <legend>$Legend</legend>
+ <% end_if %>
+
+ <% loop FieldList %>
+ <% if ColumnCount %>
+ <div class="column-{$ColumnCount} $FirstLast">
+ $SmallFieldHolder
+ </div>
+ <% else %>
+ $SmallFieldHolder
+ <% end_if %>
+ <% end_loop %>
+</$Tag>
2  templates/forms/FieldGroupField.ss → templates/forms/FieldGroup.ss
View
@@ -1,7 +1,7 @@
<div class="fieldgroup <% if Zebra %>fieldgroup-zebra<% end_if %>" <% if ID %>id="$ID"<% end_if %>>
<% loop FieldList %>
<div class="fieldgroup-field $FirstLast $EvenOdd">
- SmallFieldHolder
+ $SmallFieldHolder
</div>
<% end_loop %>
</div>
0  templates/forms/FieldGroupHolder.ss → templates/forms/FieldGroup_holder.ss
View
File renamed without changes
0  templates/forms/FieldHolder.ss → templates/forms/FormField_holder.ss
View
File renamed without changes
11 templates/forms/FormField_holder_small.ss
View
@@ -0,0 +1,11 @@
+<div class="fieldholder-small">
+ <% if $RightTitle %>
+ <label class="right fieldholder-small-label" <% if ID %>for="$ID"<% end_if %>>$RightTitle</label>
+ <% else_if $LeftTitle %>
+ <label class="left fieldholder-small-label" <% if ID %>for="$ID"<% end_if %>>$LeftTitle</label>
+ <% else_if $Title %>
+ <label class="fieldholder-small-label" <% if ID %>for="$ID"<% end_if %>>$Title</label>
+ <% end_if %>
+
+ $Field
+</div>
0  templates/ToggleCompositeField.ss → templates/forms/ToggleCompositeField.ss
View
File renamed without changes
2  tests/forms/CompositeFieldTest.php
View
@@ -15,7 +15,7 @@ function testFieldPosition() {
),
new TextField('D')
);
-
+
$this->assertEquals(0, $compositeOuter->fieldPosition('A'));
$this->assertEquals(1, $compositeOuter->fieldPosition('B'));
$this->assertEquals(3, $compositeOuter->fieldPosition('D'));
Please sign in to comment.
Something went wrong with that request. Please try again.