Permalink
Browse files

ENHANCEMENT Allowing custom attributes in (most) FormField implementa…

…tions, which allows for HTML5 data attributes
  • Loading branch information...
1 parent c77f4e8 commit b5421d9598570cc9e96d434900aad66842a0786c @chillu chillu committed Dec 22, 2011
Showing with 407 additions and 137 deletions.
  1. +21 −0 docs/en/changelogs/3.0.0.md
  2. +12 −2 forms/CheckboxField.php
  3. +7 −6 forms/CheckboxSetField.php
  4. +15 −6 forms/CompositeField.php
  5. +6 −6 forms/CountryDropdownField.php
  6. +2 −0 forms/CreditCardField.php
  7. +5 −0 forms/CurrencyField.php
  8. +13 −0 forms/DatalessField.php
  9. +4 −0 forms/DateField.php
  10. +7 −6 forms/DropdownField.php
  11. +4 −8 forms/EmailField.php
  12. +7 −0 forms/FileField.php
  13. +16 −1 forms/FormAction.php
  14. +85 −13 forms/FormField.php
  15. +1 −10 forms/GroupedDropdownField.php
  16. +14 −0 forms/HeaderField.php
  17. +7 −0 forms/HiddenField.php
  18. +12 −11 forms/HtmlEditorField.php
  19. +25 −13 forms/ListboxField.php
  20. +4 −0 forms/NumericField.php
  21. +9 −2 forms/PasswordField.php
  22. +19 −0 forms/ReadonlyField.php
  23. +9 −2 forms/ResetFormAction.php
  24. +5 −7 forms/TextField.php
  25. +11 −15 forms/TextareaField.php
  26. +4 −0 forms/TimeField.php
  27. +5 −1 forms/TreeDropdownField.php
  28. +2 −2 templates/SelectionGroup.ss
  29. +1 −1 templates/forms/CheckboxField.ss
  30. +1 −1 templates/forms/CheckboxFieldHolder.ss
  31. +11 −7 templates/forms/CheckboxSetField.ss
  32. +1 −1 templates/forms/DropdownField.ss
  33. +4 −2 templates/forms/FieldHolder.ss
  34. +1 −1 templates/forms/FileField.ss
  35. +2 −2 templates/forms/FormAction.ss
  36. +2 −2 templates/forms/FormField.ss
  37. +1 −1 templates/forms/HeaderField.ss
  38. +1 −1 templates/forms/HiddenField.ss
  39. +1 −1 templates/forms/LabelField.ss
  40. +1 −1 templates/forms/OptionsetField.ss
  41. +1 −1 templates/forms/TextField.ss
  42. +1 −1 templates/forms/TextareaField.ss
  43. +2 −2 templates/forms/TreeDropdownField.ss
  44. +44 −0 tests/forms/FormFieldTest.php
  45. +1 −1 tests/model/LabelFieldTest.php
@@ -63,6 +63,27 @@ not when simply using the CMS or developing other CMS functionality.
If you want to extend the CMS stylesheets for your own projects without SCSS,
please create a new CSS file and link it into the CMS via `[api:LeftAndMain::require_css()]`.
+### FormField consistently adds classes to HTML elements ###
+
+The [api:FormField] API has been refactored to use SilverStripe templates
+for constructing the field HTML, as well as new accessors for HTML attributes.
+This change makes the HTML a bit more predictable, but it also means that
+you need to check any code (CSS, JavaScript, etc) relying on the old inconsistencies.
+Particularly, CSS class names applied through [api:FormField->addExtraClass()]
+and the "type" class are now consistently added to the container `<div>`
+as well as the HTML form element itself.
+
+ :::html
+ Before (abbreviated):
+ <div class="field checkbox extraClass"...>
+ <input type="checkbox".../>
+ </div>
+
+ After (abbreviated):
+ <div class="field checkbox extraClass"...>
+ <input type="checkbox" class="checkbox extraClass".../>
+ </div>
+
### Restructured files and folders ###
In order to make the `sapphire` framework useable without the `cms` module,
View
@@ -22,8 +22,6 @@ function Value() {
return ($this->value) ? 1 : 0;
}
- }
-
/**
* Returns a restricted field holder used within things like FieldGroups
*/
@@ -35,6 +33,18 @@ function SmallFieldHolder() {
return $result;
}
+ function getAttributes() {
+ $attrs = parent::getAttributes();
+ $attrs['value'] = 1;
+ return array_merge(
+ $attrs,
+ array(
+ 'checked' => ($this->Value()) ? 'checked' : null,
+ 'type' => 'checkbox',
+ )
+ );
+ }
+
/**
* Returns a readonly version of this field
*/
View
@@ -98,12 +98,9 @@ function Field($properties = array()) {
}
$odd = 0;
- $options = '';
+ $options = array();
- if ($source == null) {
- $source = array();
- $options = "<li>No options available</li>";
- }
+ if ($source == null) $source = array();
if($source) {
foreach($source as $value => $item) {
@@ -122,7 +119,7 @@ function Field($properties = array()) {
$options[] = new ArrayData(array(
'ID' => $itemID,
'Class' => $extraClass,
- 'Name' => $this->name,
+ 'Name' => "{$this->name}[{$value}]",
'Value' => $value,
'Title' => $title,
'isChecked' => in_array($value, $items) || in_array($value, $this->defaultItems),
@@ -283,6 +280,10 @@ function performReadonlyTransformation() {
return $field;
}
+
+ function Type() {
+ return 'optionset checkboxset';
+ }
function ExtraOptions() {
return FormField::ExtraOptions();
View
@@ -83,15 +83,25 @@ public function setChildren($children) {
$this->children = $children;
}
+ function extraClasses() {
+ $classes = array('field', 'CompositeField', parent::extraClasses());
+ if($this->columnCount) $classes[] = 'multicolumn';
+ return implode(' ', $classes);
+ }
+
+ function getAttributes() {
+ return array_merge(
+ parent::getAttributes(),
+ array('tabindex' => null, 'type' => null, 'value' => null, 'type' => null)
+ );
+ }
+
/**
* Returns the fields nested inside another DIV
*/
function FieldHolder() {
+ $content = '';
$fs = $this->FieldList();
- $idAtt = isset($this->id) ? " id=\"{$this->id}\"" : '';
- $className = ($this->columnCount) ? "field CompositeField {$this->extraClass()} multicolumn" : "field CompositeField {$this->extraClass()}";
- $content = "<div class=\"$className\"$idAtt>\n";
-
foreach($fs as $subfield) {
if($this->columnCount) {
$className = "column{$this->columnCount}";
@@ -101,9 +111,8 @@ function FieldHolder() {
$content .= "\n" . $subfield->FieldHolder() . "\n";
}
}
- $content .= "</div>\n";
- return $content;
+ $this->createTag('div', $this->getAttributes(), $content);
}
/**
@@ -22,14 +22,14 @@ function __construct($name, $title = null, $source = null, $value = "", $form=nu
function defaultToVisitorCountry($val) {
$this->defaultToVisitorCountry = $val;
}
-
- function Field() {
+
+ function Value() {
$source = $this->getSource();
-
if($this->defaultToVisitorCountry && !$this->value || !isset($source[$this->value])) {
- $this->value = ($vc = Geoip::visitor_country()) ? $vc : Geoip::get_default_country_code();
+ return ($vc = Geoip::visitor_country()) ? $vc : Geoip::get_default_country_code();
+ } else {
+ return $this->value;
}
-
- return parent::Field();
}
+
}
@@ -9,6 +9,8 @@ class CreditCardField extends TextField {
function Field() {
$parts = explode("\n", chunk_split($this->value,4,"\n"));
$parts = array_pad($parts, 4, "");
+
+ // TODO Mark as disabled/readonly
$field = "<span id=\"{$this->name}_Holder\" class=\"creditCardField\">" .
"<input autocomplete=\"off\" name=\"{$this->name}[0]\" value=\"$parts[0]\" maxlength=\"4\"" . $this->getTabIndexHTML(0) . " /> - " .
"<input autocomplete=\"off\" name=\"{$this->name}[1]\" value=\"$parts[1]\" maxlength=\"4\"" . $this->getTabIndexHTML(1) . " /> - " .
View
@@ -27,6 +27,11 @@ function dataValue() {
return 0.00;
}
}
+
+ function Type() {
+ return 'currency text';
+ }
+
/**
* Create a new class for this field
*/
View
@@ -18,6 +18,15 @@ class DatalessField extends FormField {
* Always returns false.
*/
function hasData() { return false; }
+
+ function getAttributes() {
+ return array_merge(
+ parent::getAttributes(),
+ array(
+ 'type' => 'hidden',
+ )
+ );
+ }
/**
* Returns the field's representation in the form.
@@ -58,4 +67,8 @@ function getAllowHTML() {
return $this->allowHTML;
}
+ function Type() {
+ return 'readonly';
+ }
+
}
View
@@ -174,6 +174,10 @@ function Field() {
return $html;
}
+
+ function Type() {
+ return 'date text';
+ }
/**
* Sets the internal value to ISO date format.
View
@@ -162,6 +162,13 @@ function Field($properties = array()) {
return $this->customise($properties)->renderWith($this->getTemplate());
}
+ function getAttributes() {
+ return array_merge(
+ parent::getAttributes(),
+ array('type' => null)
+ );
+ }
+
/**
* @return boolean
*/
@@ -230,12 +237,6 @@ function performReadonlyTransformation() {
return $field;
}
- function extraClass() {
- $ret = parent::extraClass();
- if($this->extraClass) $ret .= " $this->extraClass";
- return $ret;
- }
-
/**
* Set form being disabled
*/
View
@@ -6,6 +6,10 @@
*/
class EmailField extends TextField {
+ function Type() {
+ return 'email text';
+ }
+
function jsValidation() {
$formID = $this->form->FormName();
$error = _t('EmailField.VALIDATIONJS', 'Please enter an email address.');
@@ -40,14 +44,6 @@ function jsValidation() {
JS;
}
- /**
- * Returns the field type - used by templates.
- * @return string
- */
- function Type() {
- return 'text';
- }
-
/**
* Validates for RFC 2822 compliant email adresses.
*
View
@@ -117,6 +117,13 @@ public function Field($properties = array()) {
return $this->customise($properties)->renderWith($this->getTemplate());
}
+ function getAttributes() {
+ return array_merge(
+ parent::getAttributes(),
+ array('type' => 'file')
+ );
+ }
+
public function saveInto(DataObject $record) {
if(!isset($_FILES[$this->name])) return false;
$fileClass = File::get_class_for_file_extension(pathinfo($_FILES[$this->name]['name'], PATHINFO_EXTENSION));
View
@@ -91,7 +91,22 @@ function Field($properties = array()) {
}
public function Type() {
- return ($this->useButtonTag) ? 'button' : 'submit';
+ return 'action';
+ }
+
+ function getAttributes() {
+ return array_merge(
+ parent::getAttributes(),
+ array(
+ 'disabled' => ($this->isReadonly() || $this->isDisabled()),
+ 'value' => $this->Title(),
+ 'type' => ($this->useButtonTag) ? null : 'submit'
+ )
+ );
+ }
+
+ function extraClass() {
+ return 'action ' . parent::extraClass();
}
/**
Oops, something went wrong.

0 comments on commit b5421d9

Please sign in to comment.