diff --git a/src/Forms/LookupField.php b/src/Forms/LookupField.php index 1e1bdbee7..a2018d999 100644 --- a/src/Forms/LookupField.php +++ b/src/Forms/LookupField.php @@ -8,9 +8,9 @@ use SilverStripe\ORM\DataObjectInterface; use SilverStripe\ORM\FieldType\DBField; /** - * Read-only complement of {@link DropdownField}. + * Read-only complement of {@link MultiSelectField}. * - * Shows the "human value" of the dropdown field for the currently selected + * Shows the "human value" of the MultiSelectField for the currently selected * value. */ class LookupField extends MultiSelectField diff --git a/src/Forms/SingleLookupField.php b/src/Forms/SingleLookupField.php new file mode 100644 index 000000000..a8dfc47bb --- /dev/null +++ b/src/Forms/SingleLookupField.php @@ -0,0 +1,134 @@ +value; + $source = $this->getSource(); + $source = ($source instanceof Map) ? $source->toArray() : $source; + + if (array_key_exists($value, $source)) { + return $source[$value]; + } + + return null; + } + + /** + * Ignore validation as the field is readonly + * + * @param Validator $validator + * @return bool + */ + public function validate($validator) + { + return true; + } + + /** + * Stubbed so invalid data doesn't save into the DB + * + * @param DataObjectInterface $record DataObject to save data into + */ + public function saveInto(DataObjectInterface $record) + { + } + + /** + * @return SingleLookupField + */ + public function performReadonlyTransformation() + { + $clone = clone $this; + + return $clone; + } + + /** + * @return bool + */ + public function getHasEmptyDefault() + { + return false; + } + + /** + * @return string + */ + public function Type() + { + return 'single-lookup readonly'; + } + + /** + * Note: we need to transform value in here becaue React fields do not use Field() to display value + * + * @return mixed + */ + public function Value() + { + $label = $this->valueToLabel(); + if (!is_null($label)) { + return $label; + } + + return $value; + } + + /** + * @return string + */ + public function getTemplate() + { + // this field uses the same default template as LookupField + return parent::getTemplate() ?: LookupField::class; + } + + /** + * Returns a readonly span containing the correct value. + * + * @param array $properties + * + * @return string + */ + public function Field($properties = []) + { + $label = $this->valueToLabel(); + if (!is_null($label)) { + $attrValue = Convert::raw2xml($label); + $inputValue = $this->value; + } else { + $attrValue = '(' . _t('SilverStripe\\Forms\\FormField.NONE', 'none') . ')'; + $inputValue = ''; + } + + $properties = array_merge($properties, array( + 'AttrValue' => DBField::create_field('HTMLFragment', $attrValue), + 'InputValue' => $inputValue + )); + + return parent::Field($properties); + } +} diff --git a/src/Forms/SingleSelectField.php b/src/Forms/SingleSelectField.php index 69dd6a99b..7fad88036 100644 --- a/src/Forms/SingleSelectField.php +++ b/src/Forms/SingleSelectField.php @@ -160,4 +160,17 @@ abstract class SingleSelectField extends SelectField } return $field; } + + /** + * @return SingleLookupField + */ + public function performReadonlyTransformation() + { + /** @var SingleLookupField $field */ + $field = $this->castedCopy(SingleLookupField::class); + $field->setSource($this->getSource()); + $field->setReadonly(true); + + return $field; + } } diff --git a/tests/php/Forms/SingleLookupFieldTest.php b/tests/php/Forms/SingleLookupFieldTest.php new file mode 100644 index 000000000..9550689f3 --- /dev/null +++ b/tests/php/Forms/SingleLookupFieldTest.php @@ -0,0 +1,47 @@ + 'Member 1', 'member2' => 'Member 2', 'member3' => 'Member 3'] + )->performReadonlyTransformation(); + + $this->assertInstanceOf(SingleLookupField::class, $testField); + + $testField->setValue('member1'); + preg_match('/Member 1/', $testField->Field(), $matches); + $this->assertEquals($matches[0], 'Member 1'); + } + + public function testValueNotFromSource() + { + /** @var SingleLookupField $testField */ + $testField = DropdownField::create( + 'FirstName', + 'FirstName', + ['member1' => 'Member 1', 'member2' => 'Member 2', 'member3' => 'Member 3'] + )->performReadonlyTransformation(); + + $this->assertInstanceOf(SingleLookupField::class, $testField); + + $testField->setValue('member123'); + preg_match('/\(none\)/', $testField->Field(), $matches); + $this->assertEquals($matches[0], '(none)'); + } +}