Up & Down Voting
With each row as its own component, it's easy to add up & down voting + keep track of which items have been voted on. This uses a LiveAction to save everything with Ajax.
| Banana ๐ | Votes: 92 | |
|---|---|---|
| Apple ๐ | Votes: 42 | |
| Hamburger ๐ | Votes: 51 | |
| Watermelon ๐ | Votes: 55 | |
| Cheese ๐ง | Votes: 73 | |
| Pizza ๐ | Votes: 83 | |
| Pretzel ๐ฅจ | Votes: 28 | |
| Donut ๐ฉ | Votes: 21 | |
| Pineapple ๐ | Votes: 14 | |
| Popcorn ๐ฟ | Votes: 3 | |
| Egg ๐ณ | Votes: 61 | |
| Taco ๐ฎ | Votes: 46 | |
| Ice Cream ๐ฆ | Votes: 99 | |
| Cookie ๐ช | Votes: 65 |
// ... use statements hidden - click to show
#[AsLiveComponent]
final class FoodVote extends AbstractController
{
use DefaultActionTrait;
#[LiveProp]
public Food $food;
#[LiveProp]
public bool $hasVoted = false;
public function __construct(private FoodRepository $foodRepository)
{
}
#[LiveAction]
public function vote(#[LiveArg] string $direction): void
{
if ('up' === $direction) {
$this->food->upVote();
} else {
$this->food->downVote();
}
$this->foodRepository->add($this->food, true);
$this->hasVoted = true;
}
}
<tr {{ attributes }}>
<th>{{ food.name }}</th>
<td>
Votes: {{ food.votes }}
</td>
<td style="width: 250px;">
{% if hasVoted %}
<div class="alert alert-success">
Thanks for voting! <twig:ux:icon name="circle-check" />
</div>
{% else %}
<button
type="button"
class="btn btn-secondary"
data-action="live#action"
data-live-action-param="vote"
data-live-direction-param="up"
>
<twig:ux:icon name="arrow-up" />
</button>
<button
type="button"
class="btn btn-secondary"
data-action="live#action"
data-live-action-param="vote"
data-live-direction-param="down"
>
<twig:ux:icon name="arrow-down" />
</button>
{% endif %}
</td>
</tr>
Author
weaverryan
Published
2022-06-17