Skip to content

Commit

Permalink
Fix #211: ListView::itemViewAttributes() accepts Closure as parameter. (
Browse files Browse the repository at this point in the history
#212)

Co-authored-by: Alexander Makarov <[email protected]>
  • Loading branch information
glpzzz and samdark authored Sep 10, 2024
1 parent b504e0c commit e9eec42
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 5 deletions.
34 changes: 29 additions & 5 deletions src/ListView.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ final class ListView extends BaseListView
* @psalm-var non-empty-string|null
*/
private ?string $itemViewTag = 'li';
private array $itemViewAttributes = [];
private array|Closure $itemViewAttributes = [];
private string $separator = "\n";
private array $viewParams = [];
private ?View $view = null;
Expand Down Expand Up @@ -166,11 +166,25 @@ public function itemViewTag(?string $tag): self
}

/**
* return new instance with the HTML attributes for the container of item view.
* Return new instance with the HTML attributes for the container of item view.
*
* @param array $values Attribute values indexed by attribute names.
* @param array|Closure $values Attribute values indexed by attribute names.
* If this property is specified as a function, it must return an array of attributes and have the following
* signature:
*
* ```php
* function ($data, $key, $index, $widget)
* ```
* Also, each attribute value can be a function too, with the same signature as in:
*
* ```php
* [
* 'class' => static fn($data, $key, $index, $widget) => "custom-class-{$data['id']}",
* ]
* ```
* @return ListView
*/
public function itemViewAttributes(array $values): self
public function itemViewAttributes(array|Closure $values): self
{
$new = clone $this;
$new->itemViewAttributes = $values;
Expand Down Expand Up @@ -242,10 +256,20 @@ protected function renderItem(array|object $data, mixed $key, int $index): strin
$content = (string)call_user_func($this->itemView, $data, $key, $index, $this);
}

$itemViewAttributes = is_callable($this->itemViewAttributes)
? (array)call_user_func($this->itemViewAttributes, $data, $key, $index, $this)
: $this->itemViewAttributes;

foreach ($itemViewAttributes as $i => $attribute) {
if (is_callable($attribute)) {
$itemViewAttributes[$i] = $attribute($data, $key, $index, $this);
}
}

return $this->itemViewTag === null
? $content
: Html::tag($this->itemViewTag)
->attributes($this->itemViewAttributes)
->attributes($itemViewAttributes)
->content("\n" . $content)
->encode(false)
->render();
Expand Down
83 changes: 83 additions & 0 deletions tests/ListView/BaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -407,4 +407,87 @@ public function testNoItemViewTagNoItemsWrapperTag(): void
->render(),
);
}

public function testClosureForItemViewAttributes(): void
{
Assert::equalsWithoutLE(
<<<HTML
<div>
<ul>
<li data-item-id="1" data-item-key="0" data-item-index="0">
<div>Id: 1</div><div>Name: John</div><div>Age: 20</div>
</li>
<li data-item-id="2" data-item-key="1" data-item-index="1">
<div>Id: 2</div><div>Name: Mary</div><div>Age: 21</div>
</li>
</ul>
<div>Page <b>1</b> of <b>1</b></div>
</div>
HTML,
ListView::widget()
->itemView(dirname(__DIR__) . '/Support/view/_listview.php')
->itemViewAttributes(static fn (array $data, $key, $index, $widget) => [
'data-item-id' => $data['id'],
'data-item-key' => $key,
'data-item-index' => $index,
])
->dataReader($this->createOffsetPaginator($this->data, 10))
->separator(PHP_EOL)
->render(),
);
}

public function testItemViewAttributesWithClosure(): void
{
Assert::equalsWithoutLE(
<<<HTML
<div>
<ul>
<li class="id-1-key-0-index-0">
<div>Id: 1</div><div>Name: John</div><div>Age: 20</div>
</li>
<li class="id-2-key-1-index-1">
<div>Id: 2</div><div>Name: Mary</div><div>Age: 21</div>
</li>
</ul>
<div>Page <b>1</b> of <b>1</b></div>
</div>
HTML,
ListView::widget()
->itemView(dirname(__DIR__) . '/Support/view/_listview.php')
->itemViewAttributes([
'class' => static fn(array $data, $key, $index) => "id-{$data['id']}-key-{$key}-index-{$index}",
])
->dataReader($this->createOffsetPaginator($this->data, 10))
->separator(PHP_EOL)
->render(),
);
}

public function testClosureForItemViewAttributesWithClosure(): void
{
Assert::equalsWithoutLE(
<<<HTML
<div>
<ul>
<li class="id-1-key-0-index-0">
<div>Id: 1</div><div>Name: John</div><div>Age: 20</div>
</li>
<li class="id-2-key-1-index-1">
<div>Id: 2</div><div>Name: Mary</div><div>Age: 21</div>
</li>
</ul>
<div>Page <b>1</b> of <b>1</b></div>
</div>
HTML,
ListView::widget()
->itemView(dirname(__DIR__) . '/Support/view/_listview.php')
->itemViewAttributes(static fn (array $data, $key, $index) => [
'class' => static fn(array $data, $key, $index) => "id-{$data['id']}-key-{$key}-index-{$index}",
])
->dataReader($this->createOffsetPaginator($this->data, 10))
->separator(PHP_EOL)
->render(),
);
}
}

0 comments on commit e9eec42

Please sign in to comment.