Skip to content

Commit 2cae053

Browse files
committed
WIP: nullable colour input field
1 parent fb30d88 commit 2cae053

File tree

1 file changed

+240
-0
lines changed

1 file changed

+240
-0
lines changed

src/Forms/NullableColorField.php

+240
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
<?php
2+
3+
namespace Codem\Utilities\HTML5;
4+
5+
use Silverstripe\Forms\CheckboxField;
6+
use Silverstripe\Forms\CompositeField;
7+
use Silverstripe\Forms\ReadonlyField;
8+
use Silverstripe\Forms\FieldList;
9+
use SilverStripe\ORM\DataObjectInterface;
10+
11+
/**
12+
* Provides a composite field that adds a colour field
13+
* and a checkbox to set an option for "no colour provided"
14+
*
15+
* Use this field if you allow a "no colour selection" option
16+
*/
17+
class NullableColorField extends CompositeField
18+
{
19+
20+
21+
/**
22+
* @var ColorField|null
23+
*/
24+
protected $colourField = null;
25+
26+
/**
27+
* @var ColorField|null
28+
*/
29+
protected $checkboxField = null;
30+
31+
/**
32+
* @var string
33+
*/
34+
protected $checkboxLabel = '';
35+
36+
/**
37+
* @var array
38+
*/
39+
protected $colourValue = [];
40+
41+
/**
42+
* @var bool
43+
*/
44+
protected $isSubmittingValue = false;
45+
46+
/**
47+
* Nullable Colour Field creation
48+
*
49+
* @param string $name
50+
* @param string $title
51+
* @param string $value
52+
*/
53+
public function __construct($name, $title = null, $value = null)
54+
{
55+
56+
// Base setup before buildFields is called
57+
$this->setName($name);
58+
$this->setTitle($title);
59+
$this->setValue($value);
60+
61+
$this->children = $this->buildFields();
62+
parent::__construct($this->children);
63+
64+
// Ensure name/title set after main field created
65+
$this->setName($name);
66+
$this->setTitle($title);
67+
}
68+
69+
/**
70+
* Return a prefixed field name
71+
*/
72+
public function getPrefixedFieldName(string $suffix) : string {
73+
$fieldName = $this->getName() . "[{$suffix}]";
74+
return $fieldName;
75+
}
76+
77+
/**
78+
* Get the checkbox field
79+
*/
80+
public function getCheckboxField() : CheckboxField {
81+
return $this->checkboxField;
82+
}
83+
84+
/**
85+
* Get the colour field
86+
*/
87+
public function getColourField() : ColorField {
88+
return $this->colourField;
89+
}
90+
91+
/**
92+
* This field has data
93+
*/
94+
public function hasData()
95+
{
96+
return true;
97+
}
98+
99+
/**
100+
* @inheritdoc
101+
* @param array $value
102+
*/
103+
public function setSubmittedValue($value, $data = null)
104+
{
105+
$this->isSubmittingValue = true;
106+
return parent::setSubmittedValue($value, $data);
107+
}
108+
109+
/**
110+
* @inheritdoc
111+
* When Form::loadDataFrom() is called, the value is set, child fields need to be set
112+
* when this occurs
113+
*/
114+
public function setValue($value, $data = null)
115+
{
116+
$noValue = true;
117+
$colourValue = '';
118+
if(is_array($value)) {
119+
// value is being submitted
120+
$this->isSubmittingValue = true;
121+
$colourValue = isset($value['colour']) && is_string($value['colour']) ? $value['colour'] : '';
122+
$noValue = isset($value['none']) && $value['none'] == 1;
123+
} else if(is_string($value)) {
124+
$colourValue = $value;
125+
$noValue = ($colourValue == '');
126+
}
127+
128+
// Determine setting of value
129+
if($noValue) {
130+
$colourValue = '';
131+
}
132+
133+
$this->colourValue = [
134+
'colour' => $colourValue,
135+
'none' => $noValue ? 1 : 0
136+
];
137+
138+
// Create fields with the values found
139+
$this->buildFields();
140+
141+
return parent::setValue($value, $data);
142+
}
143+
144+
/**
145+
* Create fields and return them
146+
* Note that setValue sets colourValue
147+
*/
148+
protected function buildFields() : FieldList {
149+
150+
// set up colour field
151+
$this->colourField = ColourField::create(
152+
$this->getPrefixedFieldName('colour'),
153+
'', // title is set on the main field not the colour field
154+
$this->colourValue['colour']
155+
);
156+
157+
// set up checkbox field
158+
$this->checkboxField = CheckboxField::create(
159+
$this->getPrefixedFieldName('none'),
160+
_t(
161+
'Codem\\Utilities\\HTML5\\NullableColorField.NO_COLOUR_LABEL',
162+
'None'
163+
),
164+
$this->colourValue['none']
165+
);
166+
167+
$fields = FieldList::create(
168+
$this->colourField,
169+
$this->checkboxField
170+
);
171+
172+
return $fields;
173+
}
174+
175+
/**
176+
* Save the data value into the record
177+
* @inheritdoc
178+
*/
179+
public function saveInto(DataObjectInterface $record)
180+
{
181+
$dataValue = $this->dataValue();
182+
return parent::saveInto($record);
183+
}
184+
185+
/**
186+
* Get the data value, which will either be null, if no string is
187+
*/
188+
public function dataValue() {
189+
$noValue = $this->checkboxField->dataValue();
190+
$colourValue = $this->colourField->dataValue();
191+
if($noValue == 1) {
192+
$this->value = "";
193+
} else {
194+
$this->value = $colourValue;
195+
}
196+
return $this->value;
197+
}
198+
199+
/**
200+
* @inheritdoc
201+
* Set child fields to be disabled as well
202+
*/
203+
public function setDisabled($disabled)
204+
{
205+
foreach($this->children as $child) {
206+
$child->setDisabled($disabled);
207+
}
208+
return parent::setDisabled($disabled);
209+
}
210+
211+
/**
212+
* @inheritdoc
213+
* Set child fields to be readonly as well
214+
*/
215+
public function setReadonly($readonly)
216+
{
217+
foreach($this->children as $child) {
218+
$child->setReadonly($readonly);
219+
}
220+
return parent::setReadonly($readonly);
221+
}
222+
223+
/**
224+
* The readonly version of this field
225+
*/
226+
public function performReadonlyTransformation()
227+
{
228+
$value = $this->Value();
229+
$field = ReadonlyField::create(
230+
$this->getName(),
231+
$this->Title(),
232+
$value
233+
);
234+
$field->setDescription( $this->getDescription() );
235+
$field->setRightTitle( $this->RightTitle() );
236+
return $field;
237+
}
238+
239+
240+
}

0 commit comments

Comments
 (0)