Symfony 4 - Form collecion jako lista checkboxów.

0

Cześć!
Jedno z pól formularza ma być przypisanymi użytkownikami (relacja ManyToMany). Chciałbym aby było to na zasadzie checkboxów, tz. przy wyświetlaniu formularza mam listę checkboxów z imieniem i nazwiskiem usera, i tak dla wszystkich userów.
Niestety kompletnie nie mam pomysł jak się do tego zabrać. Mogli byście pomóc?

0

EDIT
Problem rozwiązany. Entity usera musi implementować JsonSerializable -.-'

Coś robię nie tak, ale za nic nie wiem co.
W formie dodaję:

->add('AssignedUser', UsersInputType::class, [
                'label' => 'label.assigned_users',
            ])

Klasa UsersInputType:

<?php

namespace App\Form\Type;

use App\Form\DataTransformer\UserArrayToStringTransformer;
use App\Repository\UserRepository;
use Symfony\Bridge\Doctrine\Form\DataTransformer\CollectionToArrayTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;

class UsersInputType extends AbstractType
{
    private $users;

    public function __construct(UserRepository $users)
    {
        $this->users = $users;
    }

    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            // The Tag collection must be transformed into a comma separated string.
            // We could create a custom transformer to do Collection <-> string in one step,
            // but here we're doing the transformation in two steps (Collection <-> array <-> string)
            // and reuse the existing CollectionToArrayTransformer.
            ->addModelTransformer(new CollectionToArrayTransformer(), true)
            ->addModelTransformer(new UserArrayToStringTransformer($this->users), true)
        ;
    }

    /**
     * {@inheritdoc}
     */
    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        $view->vars['users'] = $this->users->findAll();
    }

    /**
     * {@inheritdoc}
     */
    public function getParent()
    {
        return TextType::class;
    }
}

Klasa UserArrayToStringTransformer:

<?php

namespace App\Form\DataTransformer;

use App\Entity\User;
use App\Repository\UserRepository;
use Symfony\Component\Form\DataTransformerInterface;

class UserArrayToStringTransformer implements DataTransformerInterface
{
    private $users;

    public function __construct(UserRepository $users)
    {
        $this->users = $users;
    }

    /**
     * {@inheritdoc}
     */
    public function transform($users): string
    {
        return implode(',', $users);
    }

    /**
     * {@inheritdoc}
     */
    public function reverseTransform($string): array
    {
        if ('' === $string || null === $string) {
            return [];
        }

        $username = array_filter(array_unique(array_map('trim', explode(',', $string))));

        $users = $this->users->findBy([
            'username' => $username,
        ]);

        return $users;
    }
}

Dodałem nowy twigowy blok:

{% block users_input_widget %}
    <div class="input-group">
        {{ form_widget(form, {'attr': {'data-toggle': 'usersinput', 'data-users': users|json_encode}}) }}
        <span class="input-group-addon">
            <span class="fa fa-tags" aria-hidden="true"></span>
        </span>
    </div>
{% endblock %}

Oraz, w entity usera dodałem:

public function jsonSerialize(): string
    {
        return $this->username;
    }

    public function __toString(): string
    {
        return $this->username;
    }

Finał jest taki że w html'u, w atrybucie 'data-users' mam 3 puste tablice:

data-users="[{},{},{}]"

Widzi ktoś może jakiś głupi błąd?

1

Próbowałeś z ChoiceType? W choice_label ustawiasz jaka ma być etykieta. Pomysł z JsonSerialize, __toString etc. jest słaby, ponieważ możesz potrzebować tego w innym miejscu w innej formie (np. samo nazwisko).

2

Jeśli masz w encji, dla której robisz formularz, kolekcję z użytkownikami np. users z ustawionym związkiem ManyToMany, to niepotrzebne te kombinacje, wystarczy zrobić wspomniane pole EntityType:

$builder->add('users', EntityType::class, array(
                    'class' => User::class,
                    'choice_label' => 'firstName'. '  '.'lastName',
                    'label' => ' Lista użytkowników',
                    'expanded' => true,
                    'multiple' => true, 
                    }))

Doctrine pobierze wszytko co potrzebne i będziesz miał odhaczonych userów należących do encji formularza. No chyba, że związek robiłeś na "piechotę" i sam tworzyłeś tabelę asocjacyjną.

1 użytkowników online, w tym zalogowanych: 0, gości: 1