Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 39 additions & 18 deletions Classes/Fusion/SelectOptionCollectionImplementation.php
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
<?php

namespace Neos\Form\Builder\Fusion;

use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
use Neos\Fusion\FusionObjects\AbstractArrayFusionObject;
use Neos\Utility\ObjectAccess;

class SelectOptionCollectionImplementation extends AbstractArrayFusionObject
{

protected $ignoreProperties = [
'prependOptionLabel',
'prependOptionValue',
'labelPropertyPath',
'valuePropertyPath'
'items',
'itemName',
'itemRenderer'
];

public function evaluate()
Expand All @@ -29,34 +31,32 @@ public function evaluate()
$options[$propertyName] = $propertyValue;
}
} else {
foreach ($items as $item) {
$value = ObjectAccess::getPropertyPath($item, $this->getValuePropertyPath());
$label = ObjectAccess::getPropertyPath($item, $this->getLabelPropertyPath());
$renderedItems = $this->renderItems($items);
foreach ($renderedItems as $renderedItem) {
$value = $renderedItem['value'] ?? null;
$label = $renderedItem['label'] ?? null;

if ($value === null) {
continue;
}

if (strlen($label) === 0) {
$label = $value;
}
$options[$value] = $label;
$options[(string)$value] = $label;
}
}
return $options;
}

/**
* @return array|\Traversable
*/
private function getItems()
private function getItems(): ?iterable
{
return $this->fusionValue('items');
}

private function getValuePropertyPath(): string
private function getItemName(): string
{
return $this->fusionValue('valuePropertyPath');
}

private function getLabelPropertyPath(): string
{
return $this->fusionValue('labelPropertyPath');
return $this->fusionValue('itemName');
}

private function getPrependOptionLabel(): string
Expand All @@ -68,4 +68,25 @@ private function getPrependOptionValue(): string
{
return $this->fusionValue('prependOptionValue') ?? '';
}

private function renderItems(iterable $items): array
{
$itemName = $this->getItemName();
$itemRenderPath = $this->path . '/itemRenderer';

$result = [];
if ($this->runtime->canRender($itemRenderPath) === true) {
foreach ($items as $item) {
$context = $this->runtime->getCurrentContext();
$context[$itemName] = $item;

$this->runtime->pushContextArray($context);

$result[] = $this->runtime->render($itemRenderPath);

$this->runtime->popContext();
}
}
return $result;
}
}
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,8 +376,17 @@ selectable:
properties {
options = Neos.Form.Builder:SelectOptionCollection {
items = ${q(site).children('[instanceof Some.Package:NewsletterCategory]')}
# we use the node identifier as value, we could use "name" or "label" instead for example
valuePropertyPath = 'identifier'
itemRenderer = Neos.Fusion:DataStructure {
value = ${item.aggregateId}
label = ${q(item).property('title')}
}
}
}
```

## Upgrade from to version 5
### Neos.Form.Builder:SelectOptionCollection
The `Neos.Form.Builder:SelectOptionCollection` prototype has been changed and uses now `items` instead of `collection`.

Also, the way how dynamic options got collected has been changed. Instead of defining the property path, you now need to
use a renderer to render the `value` and `label` of your option.
9 changes: 7 additions & 2 deletions Resources/Private/Fusion/SelectOptionCollection.fusion
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ prototype(Neos.Form.Builder:SelectOptionCollection) {

prependOptionLabel = ${null}
prependOptionValue = ${null}
valuePropertyPath = 'value'
labelPropertyPath = 'label'

items = null
itemName = 'item'
itemRenderer = Neos.Fusion:DataStructure {
value = null
label = null
}
}