Merge pull request #210 from sminnee/form-visiblefields

Form::VisibleFields() and FieldList::VisibleFields()
This commit is contained in:
Stig Lindqvist 2012-03-08 19:24:25 -08:00
commit 2ab12affec
3 changed files with 145 additions and 88 deletions

View File

@ -219,7 +219,7 @@ class FieldList extends ArrayList {
* @param string $newFieldTitle New title of field * @param string $newFieldTitle New title of field
* @return boolean * @return boolean
*/ */
function renameField($fieldName, $newFieldTitle) { public function renameField($fieldName, $newFieldTitle) {
$field = $this->dataFieldByName($fieldName); $field = $this->dataFieldByName($fieldName);
if(!$field) return false; if(!$field) return false;
@ -424,7 +424,7 @@ class FieldList extends ArrayList {
* *
* @return FieldList * @return FieldList
*/ */
function HiddenFields() { public function HiddenFields() {
$hiddenFields = new FieldList(); $hiddenFields = new FieldList();
$dataFields = $this->dataFields(); $dataFields = $this->dataFields();
@ -435,13 +435,27 @@ class FieldList extends ArrayList {
return $hiddenFields; return $hiddenFields;
} }
/**
* Return all fields except for the hidden fields.
* Useful when making your own simplified form layouts.
*/
public function VisibleFields() {
$visibleFields = new FieldList();
foreach($this as $field) {
if(!($field instanceof HiddenField)) $visibleFields->push($field);
}
return $visibleFields;
}
/** /**
* Transform this FieldList with a given tranform method, * Transform this FieldList with a given tranform method,
* e.g. $this->transform(new ReadonlyTransformation()) * e.g. $this->transform(new ReadonlyTransformation())
* *
* @return FieldList * @return FieldList
*/ */
function transform($trans) { public function transform($trans) {
$this->flushFieldsCache(); $this->flushFieldsCache();
$newFields = new FieldList(); $newFields = new FieldList();
foreach($this as $field) { foreach($this as $field) {
@ -453,12 +467,12 @@ class FieldList extends ArrayList {
/** /**
* Returns the root field set that this belongs to * Returns the root field set that this belongs to
*/ */
function rootFieldSet() { public function rootFieldSet() {
if($this->containerField) return $this->containerField->rootFieldSet(); if($this->containerField) return $this->containerField->rootFieldSet();
else return $this; else return $this;
} }
function setContainerField($field) { public function setContainerField($field) {
$this->containerField = $field; $this->containerField = $field;
return $this; return $this;
} }
@ -468,7 +482,7 @@ class FieldList extends ArrayList {
* *
* @return FieldList * @return FieldList
*/ */
function makeReadonly() { public function makeReadonly() {
return $this->transform(new ReadonlyTransformation()); return $this->transform(new ReadonlyTransformation());
} }
@ -477,7 +491,7 @@ class FieldList extends ArrayList {
* *
* @param string|FormField * @param string|FormField
*/ */
function makeFieldReadonly($field) { public function makeFieldReadonly($field) {
$fieldName = ($field instanceof FormField) ? $field->getName() : $field; $fieldName = ($field instanceof FormField) ? $field->getName() : $field;
$srcField = $this->dataFieldByName($fieldName); $srcField = $this->dataFieldByName($fieldName);
$this->replaceField($fieldName, $srcField->performReadonlyTransformation()); $this->replaceField($fieldName, $srcField->performReadonlyTransformation());
@ -492,7 +506,7 @@ class FieldList extends ArrayList {
* *
* @param array $fieldNames Field names can be given as an array, or just as a list of arguments. * @param array $fieldNames Field names can be given as an array, or just as a list of arguments.
*/ */
function changeFieldOrder($fieldNames) { public function changeFieldOrder($fieldNames) {
// Field names can be given as an array, or just as a list of arguments. // Field names can be given as an array, or just as a list of arguments.
if(!is_array($fieldNames)) $fieldNames = func_get_args(); if(!is_array($fieldNames)) $fieldNames = func_get_args();
@ -527,7 +541,7 @@ class FieldList extends ArrayList {
* @param string|FormField * @param string|FormField
* @return Position in children collection (first position starts with 0). Returns FALSE if the field can't be found. * @return Position in children collection (first position starts with 0). Returns FALSE if the field can't be found.
*/ */
function fieldPosition($field) { public function fieldPosition($field) {
if(is_object($field)) $field = $field->getName(); if(is_object($field)) $field = $field->getName();
$i = 0; $i = 0;
@ -549,7 +563,7 @@ class FieldList extends ArrayList {
* @subpackage fields-structural * @subpackage fields-structural
*/ */
class HiddenFieldList extends FieldList { class HiddenFieldList extends FieldList {
function forTemplate() { public function forTemplate() {
$output = ""; $output = "";
foreach($this as $field) { foreach($this as $field) {
$output .= $field->Field(); $output .= $field->Field();

View File

@ -152,7 +152,7 @@ class Form extends RequestHandler {
* @param FieldList $actions All of the action buttons in the form - a {@link FieldLis} of {@link FormAction} objects * @param FieldList $actions All of the action buttons in the form - a {@link FieldLis} of {@link FormAction} objects
* @param Validator $validator Override the default validator instance (Default: {@link RequiredFields}) * @param Validator $validator Override the default validator instance (Default: {@link RequiredFields})
*/ */
function __construct($controller, $name, FieldList $fields, FieldList $actions, $validator = null) { public function __construct($controller, $name, FieldList $fields, FieldList $actions, $validator = null) {
parent::__construct(); parent::__construct();
if(!$fields instanceof FieldList) throw new InvalidArgumentException('$fields must be a valid FieldList instance'); if(!$fields instanceof FieldList) throw new InvalidArgumentException('$fields must be a valid FieldList instance');
@ -198,7 +198,7 @@ class Form extends RequestHandler {
* Set up current form errors in session to * Set up current form errors in session to
* the current form if appropriate. * the current form if appropriate.
*/ */
function setupFormErrors() { public function setupFormErrors() {
$errorInfo = Session::get("FormInfo.{$this->FormName()}"); $errorInfo = Session::get("FormInfo.{$this->FormName()}");
if(isset($errorInfo['errors']) && is_array($errorInfo['errors'])) { if(isset($errorInfo['errors']) && is_array($errorInfo['errors'])) {
@ -228,7 +228,7 @@ class Form extends RequestHandler {
* and only triggers the requested form action/method * and only triggers the requested form action/method
* if the form is valid. * if the form is valid.
*/ */
function httpSubmission($request) { public function httpSubmission($request) {
$vars = $request->requestVars(); $vars = $request->requestVars();
if(isset($funcName)) { if(isset($funcName)) {
Form::set_current_action($funcName); Form::set_current_action($funcName);
@ -384,7 +384,7 @@ class Form extends RequestHandler {
* @param SS_HTTPRequest $request * @param SS_HTTPRequest $request
* @return FormField * @return FormField
*/ */
function handleField($request) { public function handleField($request) {
$field = $this->Fields()->dataFieldByName($request->param('FieldName')); $field = $this->Fields()->dataFieldByName($request->param('FieldName'));
if($field) { if($field) {
@ -398,7 +398,7 @@ class Form extends RequestHandler {
/** /**
* Convert this form into a readonly form * Convert this form into a readonly form
*/ */
function makeReadonly() { public function makeReadonly() {
$this->transform(new ReadonlyTransformation()); $this->transform(new ReadonlyTransformation());
} }
@ -428,7 +428,7 @@ class Form extends RequestHandler {
* Add an error message to a field on this form. It will be saved into the session * Add an error message to a field on this form. It will be saved into the session
* and used the next time this form is displayed. * and used the next time this form is displayed.
*/ */
function addErrorMessage($fieldName, $message, $messageType) { public function addErrorMessage($fieldName, $message, $messageType) {
Session::add_to_array("FormInfo.{$this->FormName()}.errors", array( Session::add_to_array("FormInfo.{$this->FormName()}.errors", array(
'fieldName' => $fieldName, 'fieldName' => $fieldName,
'message' => $message, 'message' => $message,
@ -436,7 +436,7 @@ class Form extends RequestHandler {
)); ));
} }
function transform(FormTransformation $trans) { public function transform(FormTransformation $trans) {
$newFields = new FieldList(); $newFields = new FieldList();
foreach($this->fields as $field) { foreach($this->fields as $field) {
$newFields->push($field->transform($trans)); $newFields->push($field->transform($trans));
@ -459,14 +459,14 @@ class Form extends RequestHandler {
* Get the {@link Validator} attached to this form. * Get the {@link Validator} attached to this form.
* @return Validator * @return Validator
*/ */
function getValidator() { public function getValidator() {
return $this->validator; return $this->validator;
} }
/** /**
* Set the {@link Validator} on this form. * Set the {@link Validator} on this form.
*/ */
function setValidator( Validator $validator ) { public function setValidator( Validator $validator ) {
if($validator) { if($validator) {
$this->validator = $validator; $this->validator = $validator;
$this->validator->setForm($this); $this->validator->setForm($this);
@ -477,14 +477,14 @@ class Form extends RequestHandler {
/** /**
* Remove the {@link Validator} from this from. * Remove the {@link Validator} from this from.
*/ */
function unsetValidator(){ public function unsetValidator(){
$this->validator = null; $this->validator = null;
} }
/** /**
* Convert this form to another format. * Convert this form to another format.
*/ */
function transformTo(FormTransformation $format) { public function transformTo(FormTransformation $format) {
$newFields = new FieldList(); $newFields = new FieldList();
foreach($this->fields as $field) { foreach($this->fields as $field) {
$newFields->push($field->transformTo($format)); $newFields->push($field->transformTo($format));
@ -525,7 +525,7 @@ class Form extends RequestHandler {
* *
* @return FieldList The form fields * @return FieldList The form fields
*/ */
function Fields() { public function Fields() {
foreach($this->getExtraFields() as $field) { foreach($this->getExtraFields() as $field) {
if(!$this->fields->fieldByName($field->getName())) $this->fields->push($field); if(!$this->fields->fieldByName($field->getName())) $this->fields->push($field);
} }
@ -540,16 +540,24 @@ class Form extends RequestHandler {
* *
* @return FieldList * @return FieldList
*/ */
function HiddenFields() { public function HiddenFields() {
return $this->fields->HiddenFields(); return $this->fields->HiddenFields();
} }
/**
* Return all fields except for the hidden fields.
* Useful when making your own simplified form layouts.
*/
public function VisibleFields() {
return $this->fields->VisibleFields();
}
/** /**
* Setter for the form fields. * Setter for the form fields.
* *
* @param FieldList $fields * @param FieldList $fields
*/ */
function setFields($fields) { public function setFields($fields) {
$this->fields = $fields; $this->fields = $fields;
return $this; return $this;
} }
@ -562,7 +570,7 @@ class Form extends RequestHandler {
* @deprecated 3.0 Use Fields() and FieldList API instead * @deprecated 3.0 Use Fields() and FieldList API instead
* @return FormField * @return FormField
*/ */
function dataFieldByName($name) { public function dataFieldByName($name) {
Deprecation::notice('3.0', 'Use Fields() and FieldList API instead'); Deprecation::notice('3.0', 'Use Fields() and FieldList API instead');
foreach($this->getExtraFields() as $field) { foreach($this->getExtraFields() as $field) {
@ -577,7 +585,7 @@ class Form extends RequestHandler {
* *
* @return FieldList The action list * @return FieldList The action list
*/ */
function Actions() { public function Actions() {
return $this->actions; return $this->actions;
} }
@ -586,7 +594,7 @@ class Form extends RequestHandler {
* *
* @param FieldList $actions * @param FieldList $actions
*/ */
function setActions($actions) { public function setActions($actions) {
$this->actions = $actions; $this->actions = $actions;
return $this; return $this;
} }
@ -594,7 +602,7 @@ class Form extends RequestHandler {
/** /**
* Unset all form actions * Unset all form actions
*/ */
function unsetAllActions(){ public function unsetAllActions(){
$this->actions = new FieldList(); $this->actions = new FieldList();
return $this; return $this;
} }
@ -605,7 +613,7 @@ class Form extends RequestHandler {
* @deprecated 3.0 Use Actions() and FieldList API instead * @deprecated 3.0 Use Actions() and FieldList API instead
* @param string $name * @param string $name
*/ */
function unsetActionByName($name) { public function unsetActionByName($name) {
Deprecation::notice('3.0', 'Use Actions() and FieldList API instead'); Deprecation::notice('3.0', 'Use Actions() and FieldList API instead');
$this->actions->removeByName($name); $this->actions->removeByName($name);
@ -615,7 +623,7 @@ class Form extends RequestHandler {
* @param String * @param String
* @param String * @param String
*/ */
function setAttribute($name, $value) { public function setAttribute($name, $value) {
$this->attributes[$name] = $value; $this->attributes[$name] = $value;
return $this; return $this;
} }
@ -623,11 +631,11 @@ class Form extends RequestHandler {
/** /**
* @return String * @return String
*/ */
function getAttribute($name) { public function getAttribute($name) {
return @$this->attributes[$name]; return @$this->attributes[$name];
} }
function getAttributes() { public function getAttributes() {
$attrs = array( $attrs = array(
'id' => $this->FormName(), 'id' => $this->FormName(),
'action' => $this->FormAction(), 'action' => $this->FormAction(),
@ -651,7 +659,7 @@ class Form extends RequestHandler {
* *
* @deprecated 3.0 Use Fields() and FieldList API instead * @deprecated 3.0 Use Fields() and FieldList API instead
*/ */
function unsetDataFieldByName($fieldName){ public function unsetDataFieldByName($fieldName){
Deprecation::notice('3.0', 'Use Fields() and FieldList API instead'); Deprecation::notice('3.0', 'Use Fields() and FieldList API instead');
foreach($this->Fields()->dataFields() as $child) { foreach($this->Fields()->dataFields() as $child) {
@ -677,7 +685,7 @@ class Form extends RequestHandler {
* If at least one argument is passed as a string, all arguments act as excludes by name. * 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) { public function getAttributesHTML($attrs = null) {
$exclude = (is_string($attrs)) ? func_get_args() : null; $exclude = (is_string($attrs)) ? func_get_args() : null;
if(!$attrs || is_string($attrs)) $attrs = $this->getAttributes(); if(!$attrs || is_string($attrs)) $attrs = $this->getAttributes();
@ -702,7 +710,7 @@ class Form extends RequestHandler {
return implode(' ', $parts); return implode(' ', $parts);
} }
function FormAttributes() { public function FormAttributes() {
return $this->getAttributesHTML(); return $this->getAttributesHTML();
} }
@ -711,7 +719,7 @@ class Form extends RequestHandler {
* *
* @param target The value of the target * @param target The value of the target
*/ */
function setTarget($target) { public function setTarget($target) {
$this->target = $target; $this->target = $target;
return $this; return $this;
} }
@ -720,7 +728,7 @@ class Form extends RequestHandler {
* Set the legend value to be inserted into * Set the legend value to be inserted into
* the <legend> element in the Form.ss template. * the <legend> element in the Form.ss template.
*/ */
function setLegend($legend) { public function setLegend($legend) {
$this->legend = $legend; $this->legend = $legend;
return $this; return $this;
} }
@ -731,7 +739,7 @@ class Form extends RequestHandler {
* *
* @param string $template The name of the template (without the .ss extension) * @param string $template The name of the template (without the .ss extension)
*/ */
function setTemplate($template) { public function setTemplate($template) {
$this->template = $template; $this->template = $template;
return $this; return $this;
} }
@ -743,7 +751,7 @@ class Form extends RequestHandler {
* *
* @return string * @return string
*/ */
function getTemplate() { public function getTemplate() {
if($this->template) return $this->template; if($this->template) return $this->template;
else return $this->class; else return $this->class;
} }
@ -800,7 +808,7 @@ class Form extends RequestHandler {
* *
* @return string HTTP method * @return string HTTP method
*/ */
function FormHttpMethod() { public function FormHttpMethod() {
return $this->formMethod; return $this->formMethod;
} }
@ -810,7 +818,7 @@ class Form extends RequestHandler {
* *
* @return string Form tag compatbile HTTP method: 'get' or 'post' * @return string Form tag compatbile HTTP method: 'get' or 'post'
*/ */
function FormMethod() { public function FormMethod() {
if(in_array($this->formMethod,array('get','post'))) { if(in_array($this->formMethod,array('get','post'))) {
return $this->formMethod; return $this->formMethod;
} else { } else {
@ -823,7 +831,7 @@ class Form extends RequestHandler {
* *
* @param $method string * @param $method string
*/ */
function setFormMethod($method) { public function setFormMethod($method) {
$this->formMethod = strtolower($method); $this->formMethod = strtolower($method);
return $this; return $this;
} }
@ -834,7 +842,7 @@ class Form extends RequestHandler {
* *
* @return string * @return string
*/ */
function FormAction() { public function FormAction() {
if ($this->formActionPath) { if ($this->formActionPath) {
return $this->formActionPath; return $this->formActionPath;
} elseif($this->controller->hasMethod("FormObjectLink")) { } elseif($this->controller->hasMethod("FormObjectLink")) {
@ -853,7 +861,7 @@ class Form extends RequestHandler {
* Note: For "normal" forms, you shouldn't need to use this method. It is recommended only for situations where you have * Note: For "normal" forms, you shouldn't need to use this method. It is recommended only for situations where you have
* two relatively distinct parts of the system trying to communicate via a form post. * two relatively distinct parts of the system trying to communicate via a form post.
*/ */
function setFormAction($path) { public function setFormAction($path) {
$this->formActionPath = $path; $this->formActionPath = $path;
return $this; return $this;
} }
@ -866,7 +874,7 @@ class Form extends RequestHandler {
/** /**
* Returns the name of the form * Returns the name of the form
*/ */
function FormName() { public function FormName() {
if($this->htmlID) return $this->htmlID; if($this->htmlID) return $this->htmlID;
else return $this->class . '_' . str_replace(array('.','/'),'',$this->name); else return $this->class . '_' . str_replace(array('.','/'),'',$this->name);
} }
@ -874,21 +882,21 @@ class Form extends RequestHandler {
/** /**
* Set the HTML ID attribute of the form * Set the HTML ID attribute of the form
*/ */
function setHTMLID($id) { public function setHTMLID($id) {
$this->htmlID = $id; $this->htmlID = $id;
} }
/** /**
* Returns this form's controller * Returns this form's controller
*/ */
function Controller() { public function Controller() {
return $this->controller; return $this->controller;
} }
/** /**
* @return string * @return string
*/ */
function Name() { public function Name() {
return $this->name; return $this->name;
} }
@ -897,7 +905,7 @@ class Form extends RequestHandler {
* That method will return the field itself. * That method will return the field itself.
* It means that you can execute $firstNameField = $form->FieldMap()->FirstName(), which can be handy * It means that you can execute $firstNameField = $form->FieldMap()->FirstName(), which can be handy
*/ */
function FieldMap() { public function FieldMap() {
return new Form_FieldMap($this); return new Form_FieldMap($this);
} }
@ -908,7 +916,7 @@ class Form extends RequestHandler {
* *
* @return string * @return string
*/ */
function Message() { public function Message() {
$this->getMessageFromSession(); $this->getMessageFromSession();
$message = $this->message; $message = $this->message;
$this->clearMessage(); $this->clearMessage();
@ -918,7 +926,7 @@ class Form extends RequestHandler {
/** /**
* @return string * @return string
*/ */
function MessageType() { public function MessageType() {
$this->getMessageFromSession(); $this->getMessageFromSession();
return $this->messageType; return $this->messageType;
} }
@ -940,7 +948,7 @@ class Form extends RequestHandler {
* @param message the text of the message * @param message the text of the message
* @param type Should be set to good, bad, or warning. * @param type Should be set to good, bad, or warning.
*/ */
function setMessage($message, $type) { public function setMessage($message, $type) {
$this->message = $message; $this->message = $message;
$this->messageType = $type; $this->messageType = $type;
return $this; return $this;
@ -952,22 +960,22 @@ class Form extends RequestHandler {
* @param message the text of the message * @param message the text of the message
* @param type Should be set to good, bad, or warning. * @param type Should be set to good, bad, or warning.
*/ */
function sessionMessage($message, $type) { public function sessionMessage($message, $type) {
Session::set("FormInfo.{$this->FormName()}.formError.message", $message); Session::set("FormInfo.{$this->FormName()}.formError.message", $message);
Session::set("FormInfo.{$this->FormName()}.formError.type", $type); Session::set("FormInfo.{$this->FormName()}.formError.type", $type);
} }
static function messageForForm( $formName, $message, $type ) { public static function messageForForm( $formName, $message, $type ) {
Session::set("FormInfo.{$formName}.formError.message", $message); Session::set("FormInfo.{$formName}.formError.message", $message);
Session::set("FormInfo.{$formName}.formError.type", $type); Session::set("FormInfo.{$formName}.formError.type", $type);
} }
function clearMessage() { public function clearMessage() {
$this->message = null; $this->message = null;
Session::clear("FormInfo.{$this->FormName()}.errors"); Session::clear("FormInfo.{$this->FormName()}.errors");
Session::clear("FormInfo.{$this->FormName()}.formError"); Session::clear("FormInfo.{$this->FormName()}.formError");
} }
function resetValidation() { public function resetValidation() {
Session::clear("FormInfo.{$this->FormName()}.errors"); Session::clear("FormInfo.{$this->FormName()}.errors");
} }
@ -977,7 +985,7 @@ class Form extends RequestHandler {
* *
* @return DataObject * @return DataObject
*/ */
function getRecord() { public function getRecord() {
return $this->record; return $this->record;
} }
@ -987,7 +995,7 @@ class Form extends RequestHandler {
* *
* @return string * @return string
*/ */
function getLegend() { public function getLegend() {
return $this->legend; return $this->legend;
} }
@ -1054,7 +1062,7 @@ class Form extends RequestHandler {
* @param $fieldList An optional list of fields to process. This can be useful when you have a * @param $fieldList An optional list of fields to process. This can be useful when you have a
* form that has some fields that save to one object, and some that save to another. * form that has some fields that save to one object, and some that save to another.
*/ */
function loadDataFrom($data, $clearMissingFields = false, $fieldList = null) { public function loadDataFrom($data, $clearMissingFields = false, $fieldList = null) {
if(!is_object($data) && !is_array($data)) { if(!is_object($data) && !is_array($data)) {
user_error("Form::loadDataFrom() not passed an array or an object", E_USER_WARNING); user_error("Form::loadDataFrom() not passed an array or an object", E_USER_WARNING);
return false; return false;
@ -1117,7 +1125,7 @@ class Form extends RequestHandler {
* @param $fieldList An optional list of fields to process. This can be useful when you have a * @param $fieldList An optional list of fields to process. This can be useful when you have a
* form that has some fields that save to one object, and some that save to another. * form that has some fields that save to one object, and some that save to another.
*/ */
function saveInto(DataObjectInterface $dataObject, $fieldList = null) { public function saveInto(DataObjectInterface $dataObject, $fieldList = null) {
$dataFields = $this->fields->saveableFields(); $dataFields = $this->fields->saveableFields();
$lastField = null; $lastField = null;
if($dataFields) foreach($dataFields as $field) { if($dataFields) foreach($dataFields as $field) {
@ -1148,7 +1156,7 @@ class Form extends RequestHandler {
* *
* @return array * @return array
*/ */
function getData() { public function getData() {
$dataFields = $this->fields->dataFields(); $dataFields = $this->fields->dataFields();
$data = array(); $data = array();
@ -1170,7 +1178,7 @@ class Form extends RequestHandler {
* @param string $fieldName * @param string $fieldName
* @param mixed $fieldValue * @param mixed $fieldValue
*/ */
function resetField($fieldName, $fieldValue = null) { public function resetField($fieldName, $fieldValue = null) {
Deprecation::notice('3.0', 'Use Fields() and FieldList API instead'); Deprecation::notice('3.0', 'Use Fields() and FieldList API instead');
$dataFields = $this->fields->dataFields(); $dataFields = $this->fields->dataFields();
@ -1188,7 +1196,7 @@ class Form extends RequestHandler {
* @param fieldName The name of the field. Can be overridden by $_REQUEST[fieldName] * @param fieldName The name of the field. Can be overridden by $_REQUEST[fieldName]
* @param methodName The name of the field. Can be overridden by $_REQUEST[methodName] * @param methodName The name of the field. Can be overridden by $_REQUEST[methodName]
*/ */
function callfieldmethod($data) { public function callfieldmethod($data) {
$fieldName = $data['fieldName']; $fieldName = $data['fieldName'];
$methodName = $data['methodName']; $methodName = $data['methodName'];
$fields = $this->fields->dataFields(); $fields = $this->fields->dataFields();
@ -1218,7 +1226,7 @@ class Form extends RequestHandler {
* This is returned when you access a form as $FormObject rather * This is returned when you access a form as $FormObject rather
* than <% control FormObject %> * than <% control FormObject %>
*/ */
function forTemplate() { public function forTemplate() {
return $this->renderWith(array_merge( return $this->renderWith(array_merge(
(array)$this->getTemplate(), (array)$this->getTemplate(),
array('Form') array('Form')
@ -1229,7 +1237,7 @@ class Form extends RequestHandler {
* Return a rendered version of this form, suitable for ajax post-back. * Return a rendered version of this form, suitable for ajax post-back.
* It triggers slightly different behaviour, such as disabling the rewriting of # links * It triggers slightly different behaviour, such as disabling the rewriting of # links
*/ */
function forAjaxTemplate() { public function forAjaxTemplate() {
$view = new SSViewer(array( $view = new SSViewer(array(
$this->getTemplate(), $this->getTemplate(),
'Form' 'Form'
@ -1243,7 +1251,7 @@ class Form extends RequestHandler {
* Attaches 3 extra hidden files, _form_action, _form_name, _form_method, and _form_enctype. These are * Attaches 3 extra hidden files, _form_action, _form_name, _form_method, and _form_enctype. These are
* the attributes of the form. These fields can be used to send the form to Ajax. * the attributes of the form. These fields can be used to send the form to Ajax.
*/ */
function formHtmlContent() { public function formHtmlContent() {
$this->IncludeFormTag = false; $this->IncludeFormTag = false;
$content = $this->forTemplate(); $content = $this->forTemplate();
$this->IncludeFormTag = true; $this->IncludeFormTag = true;
@ -1260,7 +1268,7 @@ class Form extends RequestHandler {
* Render this form using the given template, and return the result as a string * Render this form using the given template, and return the result as a string
* You can pass either an SSViewer or a template name * You can pass either an SSViewer or a template name
*/ */
function renderWithoutActionButton($template) { public function renderWithoutActionButton($template) {
$custom = $this->customise(array( $custom = $this->customise(array(
"Actions" => "", "Actions" => "",
)); ));
@ -1274,12 +1282,12 @@ class Form extends RequestHandler {
* Sets the button that was clicked. This should only be called by the Controller. * Sets the button that was clicked. This should only be called by the Controller.
* @param funcName The name of the action method that will be called. * @param funcName The name of the action method that will be called.
*/ */
function setButtonClicked($funcName) { public function setButtonClicked($funcName) {
$this->buttonClickedFunc = $funcName; $this->buttonClickedFunc = $funcName;
return $this; return $this;
} }
function buttonClicked() { public function buttonClicked() {
foreach($this->actions as $action) { foreach($this->actions as $action) {
if($this->buttonClickedFunc == $action->actionName()) return $action; if($this->buttonClickedFunc == $action->actionName()) return $action;
} }
@ -1288,7 +1296,7 @@ class Form extends RequestHandler {
/** /**
* Return the default button that should be clicked when another one isn't available * Return the default button that should be clicked when another one isn't available
*/ */
function defaultAction() { public function defaultAction() {
if($this->hasDefaultAction && $this->actions) if($this->hasDefaultAction && $this->actions)
return $this->actions->First(); return $this->actions->First();
} }
@ -1298,7 +1306,7 @@ class Form extends RequestHandler {
* Ordinarily, when a form is processed and no action_XXX button is available, then the first button in the actions list * Ordinarily, when a form is processed and no action_XXX button is available, then the first button in the actions list
* will be pressed. However, if this is "delete", for example, this isn't such a good idea. * will be pressed. However, if this is "delete", for example, this isn't such a good idea.
*/ */
function disableDefaultAction() { public function disableDefaultAction() {
$this->hasDefaultAction = false; $this->hasDefaultAction = false;
return $this; return $this;
} }
@ -1310,7 +1318,7 @@ class Form extends RequestHandler {
* *
* Check for token state with {@link getSecurityToken()} and {@link SecurityToken->isEnabled()}. * Check for token state with {@link getSecurityToken()} and {@link SecurityToken->isEnabled()}.
*/ */
function disableSecurityToken() { public function disableSecurityToken() {
$this->securityToken = new NullSecurityToken(); $this->securityToken = new NullSecurityToken();
return $this; return $this;
} }
@ -1320,7 +1328,7 @@ class Form extends RequestHandler {
* *
* Check for token state with {@link getSecurityToken()} and {@link SecurityToken->isEnabled()}. * Check for token state with {@link getSecurityToken()} and {@link SecurityToken->isEnabled()}.
*/ */
function enableSecurityToken() { public function enableSecurityToken() {
$this->securityToken = new SecurityToken(); $this->securityToken = new SecurityToken();
return $this; return $this;
} }
@ -1335,7 +1343,7 @@ class Form extends RequestHandler {
* *
* @deprecated 2.5 Use SecurityToken::disable() * @deprecated 2.5 Use SecurityToken::disable()
*/ */
static function disable_all_security_tokens() { public static function disable_all_security_tokens() {
Deprecation::notice('2.5', 'Use SecurityToken::disable() instead.'); Deprecation::notice('2.5', 'Use SecurityToken::disable() instead.');
SecurityToken::disable(); SecurityToken::disable();
} }
@ -1348,7 +1356,7 @@ class Form extends RequestHandler {
* *
* @return bool * @return bool
*/ */
function securityTokenEnabled() { public function securityTokenEnabled() {
Deprecation::notice('2.5', 'Use Form->getSecurityToken()->isEnabled() instead.'); Deprecation::notice('2.5', 'Use Form->getSecurityToken()->isEnabled() instead.');
return $this->securityToken->isEnabled(); return $this->securityToken->isEnabled();
} }
@ -1360,7 +1368,7 @@ class Form extends RequestHandler {
* *
* @return SecurityToken|null * @return SecurityToken|null
*/ */
function getSecurityToken() { public function getSecurityToken() {
return $this->securityToken; return $this->securityToken;
} }
@ -1371,7 +1379,7 @@ class Form extends RequestHandler {
* *
* @return string * @return string
*/ */
static function single_field_required() { public static function single_field_required() {
if(self::current_action() == 'callfieldmethod') return $_REQUEST['fieldName']; if(self::current_action() == 'callfieldmethod') return $_REQUEST['fieldName'];
} }
@ -1379,14 +1387,14 @@ class Form extends RequestHandler {
* Return the current form action being called, if available. * Return the current form action being called, if available.
* This is useful for optimising your forms * This is useful for optimising your forms
*/ */
static function current_action() { public static function current_action() {
return self::$current_action; return self::$current_action;
} }
/** /**
* Set the current form action. Should only be called by Controller. * Set the current form action. Should only be called by Controller.
*/ */
static function set_current_action($action) { public static function set_current_action($action) {
self::$current_action = $action; self::$current_action = $action;
} }
@ -1395,7 +1403,7 @@ class Form extends RequestHandler {
* *
* @return string * @return string
*/ */
function extraClass() { public function extraClass() {
return implode(array_unique($this->extraClasses), ' '); return implode(array_unique($this->extraClasses), ' ');
} }
@ -1406,7 +1414,7 @@ class Form extends RequestHandler {
* @param string $class A string containing a classname or several class * @param string $class A string containing a classname or several class
* names delimited by a single space. * names delimited by a single space.
*/ */
function addExtraClass($class) { public function addExtraClass($class) {
$classes = explode(' ', $class); $classes = explode(' ', $class);
foreach($classes as $class) { foreach($classes as $class) {
@ -1424,13 +1432,13 @@ class Form extends RequestHandler {
* *
* @param string $class * @param string $class
*/ */
function removeExtraClass($class) { public function removeExtraClass($class) {
$classes = explode(' ', $class); $classes = explode(' ', $class);
$this->extraClasses = array_diff($this->extraClasses, $classes); $this->extraClasses = array_diff($this->extraClasses, $classes);
return $this; return $this;
} }
function debug() { public function debug() {
$result = "<h3>$this->class</h3><ul>"; $result = "<h3>$this->class</h3><ul>";
foreach($this->fields as $field) { foreach($this->fields as $field) {
$result .= "<li>$field" . $field->debug() . "</li>"; $result .= "<li>$field" . $field->debug() . "</li>";
@ -1452,7 +1460,7 @@ class Form extends RequestHandler {
* Test a submission of this form. * Test a submission of this form.
* @return SS_HTTPResponse the response object that the handling controller produces. You can interrogate this in your unit test. * @return SS_HTTPResponse the response object that the handling controller produces. You can interrogate this in your unit test.
*/ */
function testSubmission($action, $data) { public function testSubmission($action, $data) {
$data['action_' . $action] = true; $data['action_' . $action] = true;
return Director::test($this->FormAction(), $data, Controller::curr()->getSession()); return Director::test($this->FormAction(), $data, Controller::curr()->getSession());
@ -1465,7 +1473,7 @@ class Form extends RequestHandler {
* Test an ajax submission of this form. * Test an ajax submission of this form.
* @return SS_HTTPResponse the response object that the handling controller produces. You can interrogate this in your unit test. * @return SS_HTTPResponse the response object that the handling controller produces. You can interrogate this in your unit test.
*/ */
function testAjaxSubmission($action, $data) { public function testAjaxSubmission($action, $data) {
$data['ajax'] = 1; $data['ajax'] = 1;
return $this->testSubmission($action, $data); return $this->testSubmission($action, $data);
} }
@ -1478,7 +1486,7 @@ class Form extends RequestHandler {
class Form_FieldMap extends ViewableData { class Form_FieldMap extends ViewableData {
protected $form; protected $form;
function __construct($form) { public function __construct($form) {
$this->form = $form; $this->form = $form;
parent::__construct(); parent::__construct();
} }
@ -1486,11 +1494,11 @@ class Form_FieldMap extends ViewableData {
/** /**
* Ensure that all potential method calls get passed to __call(), therefore to dataFieldByName * Ensure that all potential method calls get passed to __call(), therefore to dataFieldByName
*/ */
function hasMethod($method) { public function hasMethod($method) {
return true; return true;
} }
function __call($method, $args = null) { public function __call($method, $args = null) {
return $this->form->Fields()->fieldByName($method); return $this->form->Fields()->fieldByName($method);
} }
} }

View File

@ -729,4 +729,39 @@ class FieldListTest extends SapphireTest {
'Field nested inside a TabSet and FieldList can be marked readonly by FieldList->makeFieldReadonly()' 'Field nested inside a TabSet and FieldList can be marked readonly by FieldList->makeFieldReadonly()'
); );
} }
/**
* Test VisibleFields and HiddenFields
*/
function testVisibleAndHiddenFields() {
$fields = new FieldList(
new TextField("A"),
new TextField("B"),
new HiddenField("C"),
new Tabset("Root",
new Tab("D",
new TextField("D1"),
new HiddenField("D2")
)
)
);
$hidden = $fields->HiddenFields();
// Inside hidden fields, all HiddenField objects are included, even nested ones
$this->assertNotNull($hidden->dataFieldByName('C'));
$this->assertNotNull($hidden->dataFieldByName('D2'));
// Visible fields are not
$this->assertNull($hidden->dataFieldByName('B'));
$this->assertNull($hidden->dataFieldByName('D1'));
$visible = $fields->VisibleFields();
// Visible fields exclude top level HiddenField objects
$this->assertNotNull($visible->dataFieldByName('A'));
$this->assertNull($visible->dataFieldByName('C'));
// But they don't exclude nested HiddenField objects. This is a limitation; you should
// put all your HiddenFields at the top level.
$this->assertNotNull($visible->dataFieldByName('D2'));
}
} }