Back to all demos
DEMO

Up & Down Voting

src/Twig/FoodVoteComponent.php

use App\Entity\Food;
use App\Repository\FoodRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveAction;
use Symfony\UX\LiveComponent\Attribute\LiveArg;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\DefaultActionTrait;

#[AsLiveComponent('food_vote')]
class FoodVoteComponent 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)
    {
        if ('up' === $direction) {
            $this->food->upVote();
        } else {
            $this->food->downVote();
        }

        $this->foodRepository->add($this->food, true);
        $this->hasVoted = true;
    }
}

templates/components/food_vote.html.twig

<tr {{ attributes }}>
    <th>{{ food.name }}</th>
    <td>
        Votes: <span class="badge bg-secondary"></span>{{ food.votes }}
    </td>
    <td style="width: 250px;">
        {% if hasVoted %}
            <div class="alert alert-success">
                Thanks for voting! <i class="fa fa-check-circle"></i>
            </div>
        {% else %}
            <button
                type="button"
                class="btn btn-secondary"
                data-action="live#action"
                data-action-name="vote(direction=up)"
            >
                <i class="fa fa-arrow-up"></i>
            </button>
            <button
                type="button"
                class="btn btn-secondary"
                data-action="live#action"
                data-action-name="vote(direction=down)"
            >
                <i class="fa fa-arrow-down"></i>
            </button>
        {% endif %}
    </td>
</tr>
Banana 🍌 Votes: 34
Apple 🍎 Votes: 72
Hamburger 🍔 Votes: 41
Watermelon 🍉 Votes: 53
Cheese 🧀 Votes: 69
Pizza 🍕 Votes: 81
Pretzel 🥨 Votes: 47
Donut 🍩 Votes: 16
Pineapple 🍍 Votes: 44
Popcorn 🍿 Votes: 22
Egg 🍳 Votes: 41
Taco 🌮 Votes: 66
Ice Cream 🍦 Votes: 23
Cookie 🍪 Votes: 90