Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display a list of associations as a table #4126

Closed
tpformybh opened this issue Jan 15, 2021 · 9 comments
Closed

Display a list of associations as a table #4126

tpformybh opened this issue Jan 15, 2021 · 9 comments
Labels

Comments

@tpformybh
Copy link

Instead of outputting the count of the relations or a comma-separated string if there's a __toString method implemented on the related class, it'd be nice to be able to show the relations as a row of cells, using, if necessary a CrudController to display what fields to show rather than have to define a custom template for each use.

e.g.

AssociationsToTableField::new('products')->setCrudController(ProductCrudController::class)

which would output a nice table with one row for each product, where the fields to be displayed could be defined somewhere, presumably in the ProductCrudController here.

@nschmoyer
Copy link

In the meantime, you can do the following, for example:

CollectionField::new('products')->setTemplatePath('admin/fields/products.html.twig')

And then create a twig file:

{# @var ea \EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext #}
{# @var field \EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto #}
{# @var entity \EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto #}
{% if ea.crud.currentAction == 'detail' %}
    <table class="table table-striped">
        <tr><th>Name</th><th>Price</th></tr>
        {% for value in field.value %}
        <tr>
            <td>{{ value.name }}</td>
            <td>{{ value.price }}</td>
        </tr>
        {% endfor %}
    </table>
{% else %}
    <span class="badge badge-secondary">{{ field.formattedValue }}</span>
{% endif %}

@daffoxdev
Copy link

daffoxdev commented Mar 16, 2021

In own project needed something similar, but I needed it in many places and to avoid boilerplate I have chosen the way to create field that can show table with records from another controller inside of detail page of current controller.
It show 5 (can be configured) records, if there are more, then you can use pagination for each block of records, it loads next page with xhr, also the same works for sorting by columns. You can setup any difficulty for filter by EasyAdmin native filtering system and show any records by filtering them, by id or any other field.

Here is gist to this implementation: https://gist.github.com/daffoxdev/eff74f0606bb4889d270756fec15e4b0

You can use it as a base for you own project. It's pretty universal, but maybe you will want to upgrade something for your version.

Very sad that EasyAdmin uses:

  • finals classes,
  • services that hold state,
  • uses request stack on low levels,
  • uses some arrays that are used and created in the same method and can't be reconfigured from outside
  • and more things that not allowing to implement such feature without hacking

For sure you will find some strange decisions on my implementation, you are welcome to give advice. Cause I'm very new in the EasyAdmin and some critical points could be missed in code.

<?php

namespace App\Controller\Admin;

use App\Controller\Admin\AbstractAdminCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use App\Entity\User;

/**
 * example of usage
 */
class UserController extends AbstractAdminCrudController
{
    public static function getEntityFqcn(): string
    {
        return User::class;
    }

    public function configureFields(string $pageName): iterable
    {
        $adminContext = $this->adminContextProvider->getContext();
        $userId = $adminContext->getEntity()->getPrimaryKeyValue();
        
        $field = [
            $this->newField('id'),
            $this->newField('loginName'),
            $this->newField('name'),
        ];
        
        if ($this->isDetailPage($pageName)) {
            $fields[] = FormField::addPanel('User activity')
                ->onlyOnDetail();
            $fileds[] = $this->createUserActivityListField($userId)
                ->onlyOnDetail();
        }
        
        return $fields;
    }
    
    private function createUserActivityListField(int $userId): ControllerIndexField
    {
        return ControllerIndexField::new('user_activity_list')
                ->setControllerFqcn(UserActivityController::class)
                ->setFilter('user_id', $userId)
        ;
    }
}

Here is screenshot that abstractly shows how it will look like. Such block can be how many you wants for any controller.
image

@Tadek888
Copy link

@nschmoyer why this doesn't work in edit action?
Can I change html in twig of edit fields?

@javiereguiluz
Copy link
Collaborator

Closing as a duplicate of #3352.

@finnef
Copy link

finnef commented Jun 27, 2022

if you only need a comma separated list you can use

        $expertiseAreas = AssociationField::new('expertiseAreas')
          ->onlyOnForms()
        ;
        $expertiseAreasList = CollectionField::new('expertiseAreas')
          ->hideOnForm()
        ;

@Aziz403
Copy link

Aziz403 commented Dec 11, 2022

In the meantime, you can do the following, for example:

CollectionField::new('products')->setTemplatePath('admin/fields/products.html.twig')

And then create a twig file:

{# @var ea \EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext #}
{# @var field \EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto #}
{# @var entity \EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto #}
{% if ea.crud.currentAction == 'detail' %}
    <table class="table table-striped">
        <tr><th>Name</th><th>Price</th></tr>
        {% for value in field.value %}
        <tr>
            <td>{{ value.name }}</td>
            <td>{{ value.price }}</td>
        </tr>
        {% endfor %}
    </table>
{% else %}
    <span class="badge badge-secondary">{{ field.formattedValue }}</span>
{% endif %}

Hi,
First thanks u its works.
But in this way we can't use the EasyAdmin table(with her pagination,sorting,filters,..)
Is there a way to use the EasyAdminBundle datatable layout ?

@MGDev-FR
Copy link

MGDev-FR commented Dec 17, 2022

In the meantime, you can do the following, for example:

CollectionField::new('products')->setTemplatePath('admin/fields/products.html.twig')

And then create a twig file:

{# @var ea \EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext #}
{# @var field \EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto #}
{# @var entity \EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto #}
{% if ea.crud.currentAction == 'detail' %}
    <table class="table table-striped">
        <tr><th>Name</th><th>Price</th></tr>
        {% for value in field.value %}
        <tr>
            <td>{{ value.name }}</td>
            <td>{{ value.price }}</td>
        </tr>
        {% endfor %}
    </table>
{% else %}
    <span class="badge badge-secondary">{{ field.formattedValue }}</span>
{% endif %}

Thank you very much for that example that helps lot !!!!

I tried to display it in the list view changing : ea.crud.currentAction == 'detail' by ea.crud.currentAction == 'list' but it doesn't work.

How we can customize the field in the list view ?

@Aziz403
Copy link

Aziz403 commented Dec 30, 2022

In the meantime, you can do the following, for example:

CollectionField::new('products')->setTemplatePath('admin/fields/products.html.twig')

And then create a twig file:

{# @var ea \EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext #}
{# @var field \EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto #}
{# @var entity \EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto #}
{% if ea.crud.currentAction == 'detail' %}
    <table class="table table-striped">
        <tr><th>Name</th><th>Price</th></tr>
        {% for value in field.value %}
        <tr>
            <td>{{ value.name }}</td>
            <td>{{ value.price }}</td>
        </tr>
        {% endfor %}
    </table>
{% else %}
    <span class="badge badge-secondary">{{ field.formattedValue }}</span>
{% endif %}

Thank you very much for that example that helps lot !!!!

I tried to display it in the list view changing : ea.crud.currentAction == 'detail' by ea.crud.currentAction == 'list' but it doesn't work.

How we can customize the field in the list view ?

Why do you want to add it in list (in easyadmin its name is index)??!
For example, if you have two entities: post and comment
Why would you want to display the comment list inside the posts list?
And how would you like the UI to be?

@MGDev-FR
Copy link

MGDev-FR commented Jan 4, 2023

Thank you very much for your answer !
I use Easyadmin since few time. I will try with "index".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants