EasyAdmin 3.X - How to see related entities `toString` instead of the number of association in the list?

Viewed 4281

I have an entity Product with a ManyToMany relation to an entity Category

/**
 * @ORM\ManyToMany(targetEntity="App\Domain\Category", inversedBy="stalls")
 */
private $categories;

//...

/**
 * @return Collection|Category[]
 */
public function getCategories(): Collection
{
    return $this->categories;
}

In the ProductCrudController class I have the following configureFields method:

public function configureFields(string $pageName): iterable
{
    return [
        Field::new('name'),
        Field::new('description'),
        AssociationField::new('categories'),
    ];
}

When creating/editing a Product everything works as expected in the relation, but in the list of products instead of showing the related categories I see the number of categories the product has. How can I change this behaviour?

In the following image the first product has 1 category and the second one in the list has 2 different categories. I would like the name of the categories to be shown here.

enter image description here

As a side note: Category class has a __toString method returning the name of the category.

EDIT:

The behaviour I am looking for is the same as the Tags column in the following image:

enter image description here

5 Answers

You can make a template for that like so:

// somewhere here templates/admin/field/category.html.twig
{% for category in field.value %}
  {%- set url = ea_url()
    .setController('Path\\To\\Your\\CategoryCrudController')
    .setAction('detail')
    .setEntityId(category.id)
  -%}
  <a href="{{ url }}">
    {{ category.name }}{% if not loop.last %}, {% endif %}
  </a>
{% else %}  
  <span class="badge badge-secondary">None</span>
{% endfor %}

And just add it to the field

// in ProductCrudController
AssociationField::new('categories')->setTemplatePath('admin/field/category.html.twig'),

You can format the value using the method formatValue like this :

->formatValue(function ($value, $entity) {
                $str = $entity->getCategories()[0];
                for ($i = 1; $i < $entity->getCategories()->count(); $i++) {
                    $str = $str . ", " . $entity->getCategories()[$i];
                }
                return $str;
              })

I had the same issue on my detail page. So instead of a template, I change the field type depending on the pagename

if (Crud::PAGE_DETAIL === $pageName) {
   $field = ArrayField::new('field')->setLabel('label');
} else {
   $field = AssociationField::new('field')->setLabel('label');
}

I will do that way :

->formatValue(function ($value, $entity) {
    return implode(",",$entity->getCategories()->toArray());
})

Use ArrayField::new('categories'), instead of AssociationField::new('categories'), in the crud controller.

When creating/editing a product now the display is different, but good enough

Related