diff --git a/src/TagField.php b/src/TagField.php index 5b74bc5..ba0250a 100644 --- a/src/TagField.php +++ b/src/TagField.php @@ -2,6 +2,7 @@ namespace SilverStripe\TagField; +use Exception; use SilverStripe\Control\Controller; use SilverStripe\Control\HTTPRequest; use SilverStripe\Control\HTTPResponse; @@ -12,6 +13,7 @@ use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\DataList; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObjectInterface; +use SilverStripe\ORM\Relation; use SilverStripe\ORM\SS_List; use SilverStripe\View\ArrayData; use SilverStripe\View\Requirements; @@ -64,13 +66,12 @@ class TagField extends DropdownField /** * @param string $name * @param string $title - * @param null|DataList $source + * @param null|DataList|array $source * @param null|DataList $value * @param string $titleField */ public function __construct($name, $title = '', $source = [], $value = null, $titleField = 'Title') { - $this->setSourceList($source); $this->setTitleField($titleField); parent::__construct($name, $title, $source, $value); } @@ -176,7 +177,9 @@ class TagField extends DropdownField } /** - * Get the DataList source. The 4.x upgrade for SelectField::setSource starts to convert this to an array + * Get the DataList source. The 4.x upgrade for SelectField::setSource starts to convert this to an array. + * If empty use getSource() for array version + * * @return DataList */ public function getSourceList() @@ -186,7 +189,8 @@ class TagField extends DropdownField /** * Set the model class name for tags - * @param DataList $className + * + * @param DataList $sourceList * @return self */ public function setSourceList($sourceList) @@ -293,6 +297,20 @@ class TagField extends DropdownField { $options = ArrayList::create(); $titleField = $this->getTitleField(); + + if ($this->getShouldLazyLoad()) { + // only render options that are selected as everything else should be lazy loaded, and or loaded by the form + foreach ($values as $value) { + $options->push( + ArrayData::create(array( + 'Title' => $value->$titleField, + 'Value' => $value->Title, + 'Selected' => true, // only values are iterated. + )) + ); + } + return $options; + } foreach ($source as $object) { $options->push( @@ -329,7 +347,41 @@ class TagField extends DropdownField } /** - * {@inheritdoc} + * Gets the source array if required + * + * Note: this is expensive for a SS_List + * + * @return array + */ + public function getSource() + { + if (is_null($this->source)) { + $this->source = $this->getListMap($this->getSourceList()); + } + return $this->source; + } + + /** + * Intercept DataList source + * + * @param mixed $source + * @return $this + */ + public function setSource($source) + { + // When setting a datalist force internal list to null + if ($source instanceof DataList) { + $this->source = null; + $this->setSourceList($source); + } else { + parent::setSource($source); + } + return $this; + } + + /** + * @param DataObject|DataObjectInterface $record DataObject to save data into + * @throws Exception */ public function saveInto(DataObjectInterface $record) { @@ -338,6 +390,8 @@ class TagField extends DropdownField $name = $this->getName(); $titleField = $this->getTitleField(); $values = $this->Value(); + + /** @var Relation $relation */ $relation = $record->$name(); $ids = []; @@ -376,6 +430,10 @@ class TagField extends DropdownField { // Check if existing record can be found $source = $this->getSourceList(); + if (!$source) { + return false; + } + $titleField = $this->getTitleField(); $record = $source ->filter($titleField, $term) @@ -422,6 +480,9 @@ class TagField extends DropdownField protected function getTags($term) { $source = $this->getSourceList(); + if (!$source) { + return []; + } $titleField = $this->getTitleField();