mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #10033 from creative-commoners/pulls/4/attributeshtml-trait
API Add an AttributesHTML trait
This commit is contained in:
commit
2d4b93883b
@ -20,6 +20,7 @@ use SilverStripe\ORM\FieldType\DBHTMLText;
|
||||
use SilverStripe\ORM\ValidationResult;
|
||||
use SilverStripe\Security\NullSecurityToken;
|
||||
use SilverStripe\Security\SecurityToken;
|
||||
use SilverStripe\View\AttributesHTML;
|
||||
use SilverStripe\View\SSViewer;
|
||||
use SilverStripe\View\ViewableData;
|
||||
|
||||
@ -66,10 +67,10 @@ use SilverStripe\View\ViewableData;
|
||||
*/
|
||||
class Form extends ViewableData implements HasRequestHandler
|
||||
{
|
||||
use AttributesHTML;
|
||||
use FormMessage;
|
||||
|
||||
/**
|
||||
* Default form Name property
|
||||
*/
|
||||
const DEFAULT_NAME = 'Form';
|
||||
|
||||
@ -816,33 +817,7 @@ class Form extends ViewableData implements HasRequestHandler
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @return $this
|
||||
*/
|
||||
public function setAttribute($name, $value)
|
||||
{
|
||||
$this->attributes[$name] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function getAttribute($name)
|
||||
{
|
||||
if (isset($this->attributes[$name])) {
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributes()
|
||||
protected function getDefaultAttributes(): array
|
||||
{
|
||||
$attrs = [
|
||||
'id' => $this->FormName(),
|
||||
@ -860,53 +835,9 @@ class Form extends ViewableData implements HasRequestHandler
|
||||
$attrs['class'] .= ' validationerror';
|
||||
}
|
||||
|
||||
$attrs = array_merge($attrs, $this->attributes);
|
||||
|
||||
return $attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the attributes of the form tag - used by the templates.
|
||||
*
|
||||
* @param array $attrs 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
|
||||
*/
|
||||
public function getAttributesHTML($attrs = null)
|
||||
{
|
||||
$exclude = (is_string($attrs)) ? func_get_args() : null;
|
||||
|
||||
$attrs = $this->getAttributes();
|
||||
|
||||
// Remove empty
|
||||
$attrs = array_filter((array)$attrs, function ($value) {
|
||||
return ($value || $value === 0);
|
||||
});
|
||||
|
||||
// Remove excluded
|
||||
if ($exclude) {
|
||||
$attrs = array_diff_key($attrs, array_flip($exclude));
|
||||
}
|
||||
|
||||
// Prepare HTML-friendly 'method' attribute (lower-case)
|
||||
if (isset($attrs['method'])) {
|
||||
$attrs['method'] = strtolower($attrs['method']);
|
||||
}
|
||||
|
||||
// Create markup
|
||||
$parts = [];
|
||||
foreach ($attrs as $name => $value) {
|
||||
if ($value === true) {
|
||||
$value = $name;
|
||||
}
|
||||
|
||||
$parts[] = sprintf('%s="%s"', Convert::raw2att($name), Convert::raw2att($value));
|
||||
}
|
||||
|
||||
return implode(' ', $parts);
|
||||
}
|
||||
|
||||
public function FormAttributes()
|
||||
{
|
||||
return $this->getAttributesHTML();
|
||||
|
@ -13,6 +13,7 @@ use SilverStripe\ORM\DataObjectInterface;
|
||||
use SilverStripe\ORM\FieldType\DBField;
|
||||
use SilverStripe\ORM\FieldType\DBHTMLText;
|
||||
use SilverStripe\ORM\ValidationResult;
|
||||
use SilverStripe\View\AttributesHTML;
|
||||
use SilverStripe\View\SSViewer;
|
||||
|
||||
/**
|
||||
@ -41,6 +42,7 @@ use SilverStripe\View\SSViewer;
|
||||
*/
|
||||
class FormField extends RequestHandler
|
||||
{
|
||||
use AttributesHTML;
|
||||
use FormMessage;
|
||||
|
||||
/** @see $schemaDataType */
|
||||
@ -214,17 +216,6 @@ class FormField extends RequestHandler
|
||||
*/
|
||||
protected $smallFieldHolderTemplate;
|
||||
|
||||
/**
|
||||
* All attributes on the form field (not the field holder).
|
||||
*
|
||||
* Partially determined based on other instance properties.
|
||||
*
|
||||
* @see getAttributes()
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $attributes = [];
|
||||
|
||||
/**
|
||||
* The data type backing the field. Represents the type of value the
|
||||
* form expects to receive via a postback. Should be set in subclasses.
|
||||
@ -659,59 +650,7 @@ class FormField extends RequestHandler
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an HTML attribute on the field element, mostly an input tag.
|
||||
*
|
||||
* Some attributes are best set through more specialized methods, to avoid interfering with
|
||||
* built-in behaviour:
|
||||
*
|
||||
* - 'class': {@link addExtraClass()}
|
||||
* - 'title': {@link setDescription()}
|
||||
* - 'value': {@link setValue}
|
||||
* - 'name': {@link setName}
|
||||
*
|
||||
* Caution: this doesn't work on most fields which are composed of more than one HTML form
|
||||
* field.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setAttribute($name, $value)
|
||||
{
|
||||
$this->attributes[$name] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an HTML attribute defined by the field, or added through {@link setAttribute()}.
|
||||
*
|
||||
* Caution: this doesn't work on all fields, see {@link setAttribute()}.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function getAttribute($name)
|
||||
{
|
||||
$attributes = $this->getAttributes();
|
||||
|
||||
if (isset($attributes[$name])) {
|
||||
return $attributes[$name];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows customization through an 'updateAttributes' hook on the base class.
|
||||
* Existing attributes are passed in as the first argument and can be manipulated,
|
||||
* but any attributes added through a subclass implementation won't be included.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributes()
|
||||
protected function getDefaultAttributes(): array
|
||||
{
|
||||
$attributes = [
|
||||
'type' => $this->getInputType(),
|
||||
@ -729,67 +668,9 @@ class FormField extends RequestHandler
|
||||
$attributes['aria-required'] = 'true';
|
||||
}
|
||||
|
||||
$attributes = array_merge($attributes, $this->attributes);
|
||||
|
||||
$this->extend('updateAttributes', $attributes);
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAttributesHTML($attributes = null)
|
||||
{
|
||||
$exclude = null;
|
||||
|
||||
if (is_string($attributes)) {
|
||||
$exclude = func_get_args();
|
||||
}
|
||||
|
||||
if (!$attributes || is_string($attributes)) {
|
||||
$attributes = $this->getAttributes();
|
||||
}
|
||||
|
||||
$attributes = (array) $attributes;
|
||||
|
||||
$attributes = array_filter($attributes, function ($v) {
|
||||
return ($v || $v === 0 || $v === '0');
|
||||
});
|
||||
|
||||
if ($exclude) {
|
||||
$attributes = array_diff_key(
|
||||
$attributes,
|
||||
array_flip($exclude)
|
||||
);
|
||||
}
|
||||
|
||||
// Create markup
|
||||
$parts = [];
|
||||
|
||||
foreach ($attributes as $name => $value) {
|
||||
if ($value === true) {
|
||||
$value = $name;
|
||||
} else {
|
||||
if (is_scalar($value)) {
|
||||
$value = (string) $value;
|
||||
} else {
|
||||
$value = json_encode($value);
|
||||
}
|
||||
}
|
||||
|
||||
$parts[] = sprintf('%s="%s"', Convert::raw2att($name), Convert::raw2att($value));
|
||||
}
|
||||
|
||||
return implode(' ', $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a version of a title suitable for insertion into an HTML attribute.
|
||||
*
|
||||
|
138
src/View/AttributesHTML.php
Normal file
138
src/View/AttributesHTML.php
Normal file
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\View;
|
||||
|
||||
use SilverStripe\Core\Convert;
|
||||
|
||||
/**
|
||||
* This trait can be applied to a ViewableData class to add the logic to render attributes in an SS template.
|
||||
*
|
||||
* When applying this trait to a class, you also need to add the following casting configuration.
|
||||
* ```
|
||||
* private static $casting = [
|
||||
* 'AttributesHTML' => 'HTMLFragment',
|
||||
* 'getAttributesHTML' => 'HTMLFragment',
|
||||
* ];
|
||||
* ```
|
||||
*/
|
||||
trait AttributesHTML
|
||||
{
|
||||
|
||||
/**
|
||||
* List of attributes to render on the frontend
|
||||
* @var array
|
||||
*/
|
||||
protected $attributes = [];
|
||||
|
||||
/**
|
||||
* Set an HTML attribute
|
||||
* @param $name
|
||||
* @param $value
|
||||
* @return $this
|
||||
*/
|
||||
public function setAttribute($name, $value)
|
||||
{
|
||||
$this->attributes[$name] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the value of an HTML attribute
|
||||
* @param string $name
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getAttribute($name)
|
||||
{
|
||||
$attributes = $this->getAttributes();
|
||||
|
||||
if (isset($attributes[$name])) {
|
||||
return $attributes[$name];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default attributes when rendering this object.
|
||||
*
|
||||
* Called by `getAttributes()`
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function getDefaultAttributes(): array;
|
||||
|
||||
/**
|
||||
* Allows customization through an 'updateAttributes' hook on the base class.
|
||||
* Existing attributes are passed in as the first argument and can be manipulated,
|
||||
* but any attributes added through a subclass implementation won't be included.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributes()
|
||||
{
|
||||
$defaultAttributes = $this->getDefaultAttributes();
|
||||
|
||||
$attributes = array_merge($defaultAttributes, $this->attributes);
|
||||
|
||||
if (method_exists($this, 'extend')) {
|
||||
$this->extend('updateAttributes', $attributes);
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAttributesHTML($attributes = null)
|
||||
{
|
||||
$exclude = null;
|
||||
|
||||
if (is_string($attributes)) {
|
||||
$exclude = func_get_args();
|
||||
}
|
||||
|
||||
if (!$attributes || is_string($attributes)) {
|
||||
$attributes = $this->getAttributes();
|
||||
}
|
||||
|
||||
$attributes = (array) $attributes;
|
||||
|
||||
$attributes = array_filter($attributes, function ($v) {
|
||||
return ($v || $v === 0 || $v === '0');
|
||||
});
|
||||
|
||||
if ($exclude) {
|
||||
$attributes = array_diff_key(
|
||||
$attributes,
|
||||
array_flip($exclude)
|
||||
);
|
||||
}
|
||||
|
||||
// Create markup
|
||||
$parts = [];
|
||||
|
||||
foreach ($attributes as $name => $value) {
|
||||
if ($value === true) {
|
||||
$value = $name;
|
||||
} else {
|
||||
if (is_scalar($value)) {
|
||||
$value = (string) $value;
|
||||
} else {
|
||||
$value = json_encode($value);
|
||||
}
|
||||
}
|
||||
|
||||
$parts[] = sprintf('%s="%s"', Convert::raw2att($name), Convert::raw2att($value));
|
||||
}
|
||||
|
||||
return implode(' ', $parts);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user