mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #319 from silverstripe/templatedforms
Templated form field enhancements
This commit is contained in:
commit
0e31846937
@ -197,7 +197,7 @@ form.small .field input.text, form.small .field textarea, form.small .field sele
|
||||
.cms .ss-ui-loading-icon { background: url(../../images/network-save.gif) no-repeat; display: block; width: 16px; height: 16px; }
|
||||
|
||||
/** ---------------------------------------------------- Grouped form fields ---------------------------------------------------- */
|
||||
.fieldgroup .fieldgroup-field { float: left; display: block; width: 184px; padding-right: 8px; }
|
||||
.fieldgroup .fieldgroup-field { float: left; display: block; width: 184px; padding: 8px 0 0 8px; }
|
||||
.fieldgroup .fieldgroup-field .field { border: none; padding-bottom: 0; }
|
||||
|
||||
/** ---------------------------------------------------- Checkbox Field ---------------------------------------------------- */
|
||||
@ -353,7 +353,7 @@ body.cms { overflow: hidden; }
|
||||
/* -------------------------------------------------------- Content Tools is the sidebar on the left of the main content panel */
|
||||
.cms-content-tools { background-color: #dde3e7; width: 192px; border-right: 1px solid #bfcad2; overflow-y: auto; overflow-x: hidden; z-index: 70; -moz-box-shadow: rgba(107, 120, 123, 0.5) 0 0 4px; -webkit-box-shadow: rgba(107, 120, 123, 0.5) 0 0 4px; -o-box-shadow: rgba(107, 120, 123, 0.5) 0 0 4px; box-shadow: rgba(107, 120, 123, 0.5) 0 0 4px; float: left; position: relative; }
|
||||
.cms-content-tools .cms-panel-header { clear: both; margin: 0 0 7px; line-height: 24px; border-bottom: 1px solid rgba(201, 205, 206, 0.8); -webkit-box-shadow: 0 1px 0 rgba(228, 230, 230, 0.8); -moz-box-shadow: 0 1px 0 rgba(228, 230, 230, 0.8); -o-box-shadow: 0 1px 0 rgba(228, 230, 230, 0.8); box-shadow: 0 1px 0 rgba(228, 230, 230, 0.8); }
|
||||
.cms-content-tools .cms-panel-content { width: 176px; padding: 8px 8px; overflow: auto; height: 100%; }
|
||||
.cms-content-tools .cms-panel-content { width: 176px; padding: 0 8px; overflow: auto; height: 100%; }
|
||||
.cms-content-tools .cms-panel-content .dropdown select { width: 160px; }
|
||||
.cms-content-tools .cms-panel-content #LastEditedFrom { -moz-box-shadow: none; -webkit-box-shadow: none; -o-box-shadow: none; box-shadow: none; }
|
||||
.cms-content-tools .cms-panel-content #LastEditedFrom input { width: 160px; }
|
||||
|
@ -406,7 +406,7 @@ form.small .field, .field.small {
|
||||
float: left;
|
||||
display: block;
|
||||
width: $grid-x * 23;
|
||||
padding-right: $grid-x;
|
||||
padding: $grid-y 0 0 $grid-x;
|
||||
|
||||
&.odd {
|
||||
|
||||
|
@ -610,8 +610,8 @@ body.cms {
|
||||
}
|
||||
|
||||
.cms-panel-content {
|
||||
width: $grid-x * 22;
|
||||
padding: $grid-y $grid-x;
|
||||
width: ($grid-x * 22);
|
||||
padding: 0 $grid-x;
|
||||
overflow: auto;
|
||||
height:100%;
|
||||
.dropdown select {
|
||||
|
@ -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; }
|
||||
|
@ -8,17 +8,17 @@ table.details tr { background: #eeeee0; }
|
||||
|
||||
p { line-height: 1.5em; margin-top: 0.5em; margin-bottom: 1.0em; }
|
||||
|
||||
h1 { margin: 0px 0px 5px; font: 165% verdana, arial, helvetica; }
|
||||
h1 { margin: 0px 0px 5px; font: 165% verdana,arial,helvetica; }
|
||||
|
||||
h2 { margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana, arial, helvetica; }
|
||||
h2 { margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica; }
|
||||
|
||||
h3 { margin-bottom: 0.5em; font: bold 115% verdana, arial, helvetica; }
|
||||
h3 { margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica; }
|
||||
|
||||
h4 { margin-bottom: 0.5em; font: bold 100% verdana, arial, helvetica; }
|
||||
h4 { margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica; }
|
||||
|
||||
h5 { margin-bottom: 0.5em; font: bold 100% verdana, arial, helvetica; }
|
||||
h5 { margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica; }
|
||||
|
||||
h6 { margin-bottom: 0.5em; font: bold 100% verdana, arial, helvetica; }
|
||||
h6 { margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica; }
|
||||
|
||||
.Error { font-weight: bold; color: red; }
|
||||
|
||||
|
@ -228,7 +228,10 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
|
||||
|
||||
// Preserve memory settings
|
||||
$this->originalMemoryLimit = ini_get('memory_limit');
|
||||
|
||||
|
||||
// turn off template debugging
|
||||
SSViewer::set_source_file_comments(false);
|
||||
|
||||
// Clear requirements
|
||||
Requirements::clear();
|
||||
}
|
||||
|
@ -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 @@ class CheckboxField extends FormField {
|
||||
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 @@ class CheckboxField extends FormField {
|
||||
|
||||
/**
|
||||
* Readonly version of a checkbox field - "Yes" or "No".
|
||||
*
|
||||
* @package forms
|
||||
* @subpackage fields-basic
|
||||
*/
|
||||
|
@ -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 @@ class CheckboxSetField extends OptionsetField {
|
||||
|
||||
$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 @@ class CheckboxSetField extends OptionsetField {
|
||||
function ExtraOptions() {
|
||||
return FormField::ExtraOptions();
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
*/
|
||||
@ -59,6 +62,8 @@ class CompositeField extends FormField {
|
||||
|
||||
/**
|
||||
* Returns all the sub-fields, suitable for <% control FieldList %>
|
||||
*
|
||||
* @return FieldList
|
||||
*/
|
||||
public function FieldList() {
|
||||
return $this->children;
|
||||
@ -76,9 +81,10 @@ class CompositeField extends FormField {
|
||||
$this->id = $id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Accessor method for $this->children
|
||||
*
|
||||
* @return FieldList
|
||||
*/
|
||||
public function getChildren() {
|
||||
@ -93,24 +99,33 @@ class CompositeField extends FormField {
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @param String */
|
||||
/**
|
||||
* @param string
|
||||
*/
|
||||
public function setTag($tag) {
|
||||
$this->tag = $tag;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return String */
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTag() {
|
||||
return $this->tag;
|
||||
}
|
||||
|
||||
/** @param String */
|
||||
/**
|
||||
* @param string
|
||||
*/
|
||||
public function setLegend($legend) {
|
||||
$this->legend = $legend;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return String */
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLegend() {
|
||||
return $this->legend;
|
||||
}
|
||||
@ -118,6 +133,7 @@ class CompositeField extends FormField {
|
||||
function extraClasses() {
|
||||
$classes = array('field', 'CompositeField', parent::extraClasses());
|
||||
if($this->columnCount) $classes[] = 'multicolumn';
|
||||
|
||||
return implode(' ', $classes);
|
||||
}
|
||||
|
||||
@ -134,80 +150,10 @@ class CompositeField extends FormField {
|
||||
);
|
||||
}
|
||||
|
||||
public function Field($properties = array()) {
|
||||
$content = '';
|
||||
|
||||
if($this->tag == 'fieldset' && $this->legend) {
|
||||
$content .= '<legend>' . $this->legend . '<legend>';
|
||||
}
|
||||
|
||||
$fs = $this->FieldList();
|
||||
foreach($fs as $subfield) {
|
||||
if($this->columnCount) {
|
||||
$className = "column{$this->columnCount}";
|
||||
if(!next($fs)) $className .= " lastcolumn";
|
||||
$content .= "\n<div class=\"{$className}\">\n" . $subfield->Field() . "\n</div>\n";
|
||||
} else if($subfield){
|
||||
$content .= "\n" . $subfield->Field() . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $this->createTag($this->getTag(), $this->getAttributes(), $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fields nested inside another DIV
|
||||
*/
|
||||
function FieldHolder($properties = array()) {
|
||||
$content = '';
|
||||
|
||||
if($this->tag == 'fieldset' && $this->legend) {
|
||||
$content .= '<legend>' . $this->legend . '<legend>';
|
||||
}
|
||||
|
||||
$fs = $this->FieldList();
|
||||
foreach($fs as $subfield) {
|
||||
if($this->columnCount) {
|
||||
$className = "column{$this->columnCount}";
|
||||
if(!next($fs)) $className .= " lastcolumn";
|
||||
$content .= "\n<div class=\"{$className}\">\n" . $subfield->FieldHolder() . "\n</div>\n";
|
||||
} else if($subfield){
|
||||
$content .= "\n" . $subfield->FieldHolder() . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $this->createTag($this->getTag(), $this->getAttributes(), $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fields in the restricted field holder inside a DIV.
|
||||
*/
|
||||
function SmallFieldHolder() {
|
||||
$fs = $this->FieldList();
|
||||
$tag = $this->getTag();
|
||||
$idAtt = isset($this->id) ? " id=\"{$this->id}\"" : '';
|
||||
$className = ($this->columnCount) ? "field CompositeField {$this->extraClass()} multicolumn" : "field CompositeField {$this->extraClass()}";
|
||||
$content = "<$tag class=\"$className\"$idAtt>";
|
||||
|
||||
if($this->tag == 'fieldset' && $this->legend) {
|
||||
$content .= '<legend>' . $this->legend . '<legend>';
|
||||
}
|
||||
|
||||
foreach($fs as $subfield) {
|
||||
if($this->columnCount) {
|
||||
$className = "column{$this->columnCount}";
|
||||
if(!next($fs)) $className .= " lastcolumn";
|
||||
$content .= "<div class=\"{$className}\">" . $subfield->FieldHolder() . "</div>";
|
||||
} else if($subfield){
|
||||
$content .= $subfield->SmallFieldHolder() . " ";
|
||||
}
|
||||
}
|
||||
$content .= "</$tag>";
|
||||
|
||||
return $content;
|
||||
}
|
||||
/**
|
||||
* Add all of the non-composite fields contained within this field to the list.
|
||||
* Add all of the non-composite fields contained within this field to the
|
||||
* list.
|
||||
*
|
||||
* Sequentialisation is used when connecting the form to its data source
|
||||
*/
|
||||
public function collateDataFields(&$list, $saveableOnly = false) {
|
||||
@ -232,8 +178,11 @@ class CompositeField extends FormField {
|
||||
}
|
||||
|
||||
function setForm($form) {
|
||||
foreach($this->children as $f) if(is_object($f)) $f->setForm($form);
|
||||
foreach($this->children as $f)
|
||||
if(is_object($f)) $f->setForm($form);
|
||||
|
||||
parent::setForm($form);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -242,6 +191,10 @@ class CompositeField extends FormField {
|
||||
return $this;
|
||||
}
|
||||
|
||||
function getColumnCount() {
|
||||
return $this->columnCount;
|
||||
}
|
||||
|
||||
function isComposite() {
|
||||
return true;
|
||||
}
|
||||
@ -253,8 +206,11 @@ class CompositeField extends FormField {
|
||||
public function fieldByName($name) {
|
||||
return $this->children->fieldByName($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new child field to the end of the set.
|
||||
*
|
||||
* @param FormField
|
||||
*/
|
||||
public function push(FormField $field) {
|
||||
$this->children->push($field);
|
||||
|
@ -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 @@ class DropdownField extends FormField {
|
||||
|
||||
$properties = array_merge($properties, array('Options' => new ArrayList($options)));
|
||||
|
||||
return $this->customise($properties)->renderWith($this->getTemplate());
|
||||
return parent::Field($properties);
|
||||
}
|
||||
|
||||
function getAttributes() {
|
||||
|
@ -45,8 +45,8 @@
|
||||
* @subpackage fields-structural
|
||||
*/
|
||||
class FieldGroup extends CompositeField {
|
||||
|
||||
protected $zebra;
|
||||
public $subfieldParam = "SmallFieldHolder";
|
||||
|
||||
function __construct($arg1 = null, $arg2 = null) {
|
||||
if(is_array($arg1) || is_a($arg1, 'FieldSet')) {
|
||||
@ -85,45 +85,10 @@ class FieldGroup extends CompositeField {
|
||||
return preg_replace("/[^a-zA-Z0-9]+/", "", $this->title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a set of <span class="subfield"> tags, each containing a sub-field.
|
||||
* You can also use <% control FieldSet %>, if you'd like more control over the generated HTML
|
||||
*
|
||||
* @todo Shouldn't use SmallFieldHolder() (very difficult to style),
|
||||
* it is easier to overwrite the <div class="field"> behaviour in a more specific class
|
||||
*/
|
||||
function Field($properties = array()) {
|
||||
$fs = $this->FieldList();
|
||||
$spaceZebra = isset($this->zebra) ? " fieldgroup-$this->zebra" : '';
|
||||
$idAtt = isset($this->id) ? " id=\"{$this->id}\"" : '';
|
||||
$content = "<div class=\"fieldgroup$spaceZebra\"$idAtt>";
|
||||
|
||||
$count = 1;
|
||||
foreach($fs as $subfield) {
|
||||
$childZebra = (!isset($childZebra) || $childZebra == "odd") ? "even" : "odd";
|
||||
if($subfield->hasMethod('setZebra')) {
|
||||
$subfield->setZebra($childZebra);
|
||||
}
|
||||
|
||||
//label the first and last fields of each surrounding div
|
||||
if ($count == 1) $firstLast = "first";
|
||||
elseif ($count == count($fs)) $firstLast = "last";
|
||||
else $firstLast = '';
|
||||
|
||||
$content .= "<div class=\"fieldgroup-field $firstLast\">" . $subfield->{$this->subfieldParam}() . "</div>";
|
||||
$count++;
|
||||
}
|
||||
$content .= "</div>";
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function setID($id) {
|
||||
$this->id = Convert::raw2att($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an odd/even class
|
||||
*
|
||||
* @param string $zebra one of odd or even.
|
||||
*/
|
||||
function setZebra($zebra) {
|
||||
if($zebra == 'odd' || $zebra == 'even') $this->zebra = $zebra;
|
||||
@ -131,47 +96,40 @@ class FieldGroup extends CompositeField {
|
||||
return $this;
|
||||
}
|
||||
|
||||
function FieldHolder($properties = array()) {
|
||||
$Title = $this->XML_val('Title');
|
||||
$Message = $this->XML_val('Message');
|
||||
$MessageType = $this->XML_val('MessageType');
|
||||
$RightTitle = $this->XML_val('RightTitle');
|
||||
$Type = $this->XML_val('Type');
|
||||
$extraClass = $this->XML_val('extraClass');
|
||||
$Name = $this->XML_val('Name');
|
||||
$Field = $this->XML_val('Field');
|
||||
|
||||
$titleBlock = (!empty($Title)) ? "<label class=\"left\">$Title</label>" : "";
|
||||
$messageBlock = (!empty($Message)) ? "<span class=\"message $MessageType\">$Message</span>" : "";
|
||||
$rightTitleBlock = (!empty($RightTitle)) ? "<label class=\"right\">$RightTitle</label>" : "";
|
||||
$id = $Name ? ' id="$Name"' : '';
|
||||
|
||||
return <<<HTML
|
||||
<div$id class="field $Type $extraClass">$titleBlock<div class="middleColumn">$Field</div>$rightTitleBlock$messageBlock</div>
|
||||
HTML;
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function getZebra() {
|
||||
return $this->zebra;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function Message() {
|
||||
$fs = $this->FieldList();
|
||||
|
||||
foreach($fs as $subfield) {
|
||||
if($m = $subfield->Message()) $message[] = $m;
|
||||
}
|
||||
if(isset($message)) return implode(", ", $message) . ". ";
|
||||
|
||||
return (isset($message)) ? implode(", ", $message) . ". " : "";
|
||||
}
|
||||
|
||||
function MessageType(){
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function MessageType() {
|
||||
$fs = $this->FieldList();
|
||||
|
||||
foreach($fs as $subfield) {
|
||||
if($m = $subfield->MessageType()) $MessageType[] = $m;
|
||||
}
|
||||
if(isset($MessageType)) {
|
||||
return implode(". ", $MessageType);
|
||||
}
|
||||
|
||||
return (isset($MessageType)) ? implode(". ", $MessageType) : "";
|
||||
}
|
||||
|
||||
function php($data){
|
||||
function php($data) {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -42,8 +42,6 @@
|
||||
* @subpackage fields-files
|
||||
*/
|
||||
class FileField extends FormField {
|
||||
|
||||
protected $template = 'FileField';
|
||||
|
||||
/**
|
||||
* Restrict filesize for either all filetypes
|
||||
@ -112,8 +110,11 @@ class FileField extends FormField {
|
||||
}
|
||||
|
||||
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() {
|
||||
|
@ -12,8 +12,6 @@
|
||||
*/
|
||||
class FileIFrameField extends FileField {
|
||||
|
||||
protected $template = 'FileIFrameField';
|
||||
|
||||
public static $allowed_actions = array (
|
||||
'iframe',
|
||||
'EditFileForm',
|
||||
|
@ -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 @@ class FormAction extends FormField {
|
||||
'UseButtonTag' => $this->useButtonTag
|
||||
)
|
||||
);
|
||||
return $this->customise($properties)->renderWith($this->getTemplate());
|
||||
|
||||
return parent::Field($properties);
|
||||
}
|
||||
|
||||
function FieldHolder($properties = array()) {
|
||||
|
@ -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 @@ class FormField extends RequestHandler {
|
||||
* 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 @@ class FormField extends RequestHandler {
|
||||
* 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 @@ class FormField extends RequestHandler {
|
||||
* 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 @@ class FormField extends RequestHandler {
|
||||
'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 @@ class FormField extends RequestHandler {
|
||||
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 @@ class FormField extends RequestHandler {
|
||||
public function securityTokenEnabled() {
|
||||
$form = $this->getForm();
|
||||
if(!$form) return false;
|
||||
|
||||
return $form->getSecurityToken()->isEnabled();
|
||||
}
|
||||
|
||||
@ -471,6 +456,7 @@ class FormField extends RequestHandler {
|
||||
function setError($message, $messageType) {
|
||||
$this->message = $message;
|
||||
$this->messageType = $messageType;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -479,10 +465,11 @@ class FormField extends RequestHandler {
|
||||
* 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 @@ class FormField extends RequestHandler {
|
||||
* 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,20 +490,65 @@ class FormField extends RequestHandler {
|
||||
* 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
|
||||
@ -529,7 +561,8 @@ class FormField extends RequestHandler {
|
||||
*/
|
||||
function Field($properties = array()) {
|
||||
$obj = ($properties) ? $this->customise($properties) : $this;
|
||||
return $obj->renderWith($this->getTemplate());
|
||||
|
||||
return $obj->renderWith($this->getTemplates());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -544,28 +577,80 @@ class FormField extends RequestHandler {
|
||||
*/
|
||||
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;
|
||||
|
||||
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'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
$result .= $this->Field();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
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 @@ class FormField extends RequestHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return String
|
||||
* @return string
|
||||
*/
|
||||
function getDescription() {
|
||||
return $this->description;
|
||||
|
@ -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 @@ class HeaderField extends DatalessField {
|
||||
function Type() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -8,8 +8,6 @@
|
||||
* @subpackage fields-dataless
|
||||
*/
|
||||
class LabelField extends DatalessField {
|
||||
|
||||
protected $template = 'LabelField';
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
|
@ -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 @@ class ListboxField extends DropdownField {
|
||||
));
|
||||
}
|
||||
}
|
||||
$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() {
|
||||
|
@ -55,8 +55,6 @@
|
||||
* @subpackage fields-basic
|
||||
*/
|
||||
class OptionsetField extends DropdownField {
|
||||
|
||||
protected $template = 'OptionsetField';
|
||||
|
||||
/**
|
||||
* @var Array
|
||||
@ -67,6 +65,7 @@ class OptionsetField extends DropdownField {
|
||||
$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 @@ class OptionsetField extends DropdownField {
|
||||
}
|
||||
}
|
||||
|
||||
$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 @@ class OptionsetField extends DropdownField {
|
||||
$field = new LookupField($this->name, $this->title ? $this->title : '', $items, $this->value);
|
||||
$field->setForm($this->form);
|
||||
$field->setReadonly(true);
|
||||
|
||||
return $field;
|
||||
}
|
||||
|
||||
|
@ -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 @@ class SelectionGroup extends CompositeField {
|
||||
|
||||
$firstSelected = $checked ="";
|
||||
}
|
||||
|
||||
return new ArrayList($newItems);
|
||||
}
|
||||
|
||||
@ -72,8 +73,8 @@ class SelectionGroup extends CompositeField {
|
||||
Requirements::css(SAPPHIRE_DIR . '/css/SelectionGroup.css');
|
||||
|
||||
$obj = $properties ? $this->customise($properties) : $this;
|
||||
|
||||
return $obj->renderWith($this->template);
|
||||
|
||||
return $obj->renderWith($this->getTemplates());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 @@ class TabSet extends CompositeField {
|
||||
Requirements::javascript(SAPPHIRE_DIR . '/javascript/TabSet.js');
|
||||
|
||||
$obj = $properties ? $this->customise($properties) : $this;
|
||||
return $obj->renderWith($this->template);
|
||||
|
||||
return $obj->renderWith($this->getTemplates());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,6 +89,7 @@ class TabSet extends CompositeField {
|
||||
public function Tabs() {
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
public function setTabs($children){
|
||||
$this->children = $children;
|
||||
}
|
||||
|
@ -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 @@ class TextField extends FormField {
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 @@ class TextField extends FormField {
|
||||
function InternallyLabelledField() {
|
||||
if(!$this->value) $this->value = $this->Title();
|
||||
return $this->Field();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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 @@ class TextareaField extends FormField {
|
||||
}
|
||||
|
||||
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 @@ class TextareaField extends FormField {
|
||||
* 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() {
|
||||
|
@ -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 @@ class ToggleCompositeField extends CompositeField {
|
||||
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 @@ class ToggleCompositeField extends CompositeField {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return String
|
||||
* @return string
|
||||
*/
|
||||
public function HeadingLevel() {
|
||||
return $this->headingLevel;
|
||||
|
@ -44,11 +44,6 @@ class UploadField extends FileField {
|
||||
'$Action!' => '$Action',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var String
|
||||
*/
|
||||
protected $template = 'UploadField';
|
||||
|
||||
/**
|
||||
* @var String
|
||||
*/
|
||||
@ -375,13 +370,15 @@ class UploadField extends FileField {
|
||||
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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -12,8 +12,6 @@
|
||||
*/
|
||||
class GridFieldDetailForm implements GridField_URLHandler {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @var String
|
||||
*/
|
||||
|
@ -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;
|
||||
|
5
templates/forms/CheckboxField_holder_small.ss
Normal file
5
templates/forms/CheckboxField_holder_small.ss
Normal file
@ -0,0 +1,5 @@
|
||||
<% if $Title %>
|
||||
<label class="checkboxfield-small" <% if ID %>for="$ID"<% end_if %>>$Title</label>
|
||||
<% end_if %>
|
||||
|
||||
$Field
|
@ -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>
|
15
templates/forms/CompositeField.ss
Normal file
15
templates/forms/CompositeField.ss
Normal file
@ -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">
|
||||
$Field
|
||||
</div>
|
||||
<% else %>
|
||||
$Field
|
||||
<% end_if %>
|
||||
<% end_loop %>
|
||||
</$Tag>
|
15
templates/forms/CompositeField_holder.ss
Normal file
15
templates/forms/CompositeField_holder.ss
Normal file
@ -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
Normal file
15
templates/forms/CompositeField_holder_small.ss
Normal file
@ -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>
|
7
templates/forms/FieldGroup.ss
Normal file
7
templates/forms/FieldGroup.ss
Normal file
@ -0,0 +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
|
||||
</div>
|
||||
<% end_loop %>
|
||||
</div>
|
13
templates/forms/FieldGroup_holder.ss
Normal file
13
templates/forms/FieldGroup_holder.ss
Normal file
@ -0,0 +1,13 @@
|
||||
<div <% if Name %>id="$Name"<% end_if %> class="field $Type $extraClass">
|
||||
<% if Title %><label class="left">$Title</label><% end_if %>
|
||||
|
||||
<div class="middleColumn fieldgroup <% if Zebra %>fieldgroup-$Zebra<% end_if %>">
|
||||
<% loop FieldList %>
|
||||
<div class="fieldgroup-field $FirstLast $EvenOdd">
|
||||
$SmallFieldHolder
|
||||
</div>
|
||||
<% end_loop %>
|
||||
</div>
|
||||
<% if RightTitle %><label class="right">$RightTitle</label><% end_if %>
|
||||
<% if Message %><span class="message $MessageType">$Message</span><% end_if %>
|
||||
</div>
|
11
templates/forms/FormField_holder_small.ss
Normal file
11
templates/forms/FormField_holder_small.ss
Normal file
@ -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>
|
@ -15,7 +15,7 @@ class CompositeFieldTest extends SapphireTest {
|
||||
),
|
||||
new TextField('D')
|
||||
);
|
||||
|
||||
|
||||
$this->assertEquals(0, $compositeOuter->fieldPosition('A'));
|
||||
$this->assertEquals(1, $compositeOuter->fieldPosition('B'));
|
||||
$this->assertEquals(3, $compositeOuter->fieldPosition('D'));
|
||||
@ -30,16 +30,18 @@ class CompositeFieldTest extends SapphireTest {
|
||||
}
|
||||
|
||||
function testTag() {
|
||||
$composite = new CompositeField(
|
||||
$div = new CompositeField(
|
||||
new TextField('A'),
|
||||
new TextField('B')
|
||||
);
|
||||
$this->assertStringStartsWith('<div', trim($composite->FieldHolder()));
|
||||
$this->assertStringEndsWith('/div>', trim($composite->FieldHolder()));
|
||||
$this->assertStringStartsWith('<div', trim($div->FieldHolder()));
|
||||
$this->assertStringEndsWith('/div>', trim($div->FieldHolder()));
|
||||
|
||||
$fieldset = new CompositeField();
|
||||
$fieldset->setTag('fieldset');
|
||||
|
||||
$composite->setTag('fieldset');
|
||||
$this->assertStringStartsWith('<fieldset', trim($composite->FieldHolder()));
|
||||
$this->assertStringEndsWith('/fieldset>', trim($composite->FieldHolder()));
|
||||
$this->assertStringStartsWith('<fieldset', trim($fieldset->FieldHolder()));
|
||||
$this->assertStringEndsWith('/fieldset>', trim($fieldset->FieldHolder()));
|
||||
}
|
||||
|
||||
function testLegend() {
|
||||
@ -47,18 +49,14 @@ class CompositeFieldTest extends SapphireTest {
|
||||
new TextField('A'),
|
||||
new TextField('B')
|
||||
);
|
||||
$composite->setLegend('My legend');
|
||||
$parser = new CSSContentParser($composite->Field());
|
||||
$root = $parser->getBySelector('div.composite');
|
||||
$this->assertObjectHasAttribute('title', $root[0]->attributes());
|
||||
$this->assertEquals('My legend', (string)$root[0]['title']);
|
||||
|
||||
|
||||
$composite->setTag('fieldset');
|
||||
$composite->setLegend('My legend');
|
||||
|
||||
$parser = new CSSContentParser($composite->Field());
|
||||
$root = $parser->getBySelector('fieldset.composite');
|
||||
$this->assertObjectNotHasAttribute('title', $root[0]->attributes());
|
||||
$legend = $parser->getBySelector('fieldset.composite legend');
|
||||
|
||||
$this->assertNotNull($legend);
|
||||
$this->assertEquals('My legend', (string)$legend[0]);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user