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?
https://symfony.com/doc/current/reference/forms/types/entity.html
zwroc uwage na opcje multiple :)
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?
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).
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ą.