Search code examples
javascriptonclickcrudsymfony5easyadmin

EasyAdmin3: clickable table-row (link to EDIT-page)


I don't like the "edit"-button at the end of each entity on the INDEX-Page (EasyAdmin 3 / symfony 5) and I would like to have the table-row clickable and it shall send me directly to the EDIT-page.

I guess the solution must be using Javascript, so I started:

PHP-file

class PersonCrudController extends AbstractCrudController {
   [...]
   
    public function configureFields(string $pageName): iterable {
        [...]
        yield TextField::new('fullName',  'Name')->onlyOnIndex()->setCssClass('js-row-action');
        [...]
    }

   [...]
}

javascript-file

// call functions once page is loaded
document.addEventListener("DOMContentLoaded", function() {
    makeTableRowClickable();
});

function makeTableRowClickable() {
    let elements = document.getElementsByClassName('js-row-action');

    for (let i = 0; i < elements.length; i++) {
        let td = elements[i];
        let tr = td.parentNode;

        tr.addEventListener("click", function (e) {
            alert('click the row, Jack!');
        });
    }
}

open questions

  1. How do I generate the URL of the EDIT-page?
  2. How can I set a data attribute with the URL into any (hidden) field so that I can use it in the javascript?

Any ideas? Many thanks!


Solution

  • Here is my solution (you have to update the twig-template)

    index.html.twig (my overriding file)

    identify the URL for the edit-page and add the link as href-attribute into the TR-tag

    {#
        EXAMPLES:
        templates/bundles/EasyAdminBundle/layout.html.twig      ===> extends '@!EasyAdmin/layout.html.twig'
        templates/bundles/EasyAdminBundle/crud/index.html.twig  ===> extends '@!EasyAdmin/crud/index.html.twig'
    #}
    
    {# DO THIS: the '!' symbol tells Symfony to extend from the original template #}
    {% extends '@!EasyAdmin/crud/index.html.twig' %}
    
    
    {% block table_body %}
    
        {% for entity in entities %}
            {% if not entity.isAccessible %}
                {% set some_results_are_hidden = true %}
            {% else %}
    
                {# generation of the EDIT-link #}
                {% set editUrl = ea_url()
                        .setController(ea.crud.controllerFqcn)
                        .setAction('edit')
                        .setEntityId(entity.primaryKeyValue) %}
    
    
                {# add href-attribute and insert the URL #}
                <tr data-id="{{ entity.primaryKeyValueAsString }}" href="{{ editUrl }}">
    
    [...]
    
    {% endblock table_body %}
    
    

    javasript-file

    identify the href-attribute and send user to url

    // call functions once page is loaded
    document.addEventListener("DOMContentLoaded", function() {
        makeTableRowClickable();
    });
    
    function makeTableRowClickable() {
        let elements = document.getElementsByClassName('js-row-action');
    
        for (let i = 0; i < elements.length; i++) {
            let td  = elements[i];
            let tr  = td.parentNode;
            let url = tr.getAttribute('href');
    
            tr.addEventListener("click", function (e) {
                location.href = url;
            });
        }
    }
    

    crud-controller (php)

    add a css-class that can be catched by javascript

    class PersonCrudController extends AbstractCrudController {
       [...]
       
        public function configureFields(string $pageName): iterable {
            [...]
            yield TextField::new('fullName',  'Name')->onlyOnIndex()->setCssClass('js-row-action');
            [...]
        }
    
       [...]
    }
    

    dashboard-controller (php)

    link the javascript-file to the dashboard-controller to have it as default everywhere

    class DashboardController extends AbstractDashboardController
    {
        [...]
        public function configureAssets(): Assets {
            $assets = parent::configureAssets();
            $assets->addJsFile('js/row_clickable.js');
    
            return $assets;
        }
        [...]
    }
    

    Have fun!