In generale vogliamo creare un'interfaccia CRUD, 1N, con la quale, quando il’si è sul’édition d’un
élément, si aggiunge un pannello per gérer tutti
i élémenti figli.
Qui abbiamo una tabella wtype, con una tabella wconf che contiene una série d’registrazione collegataés a un elemento wtype.
Proprio come per l’esempio di’impléimplementazione di sortable con trascinamento’ndrop ( disponibile qui ) useremo i seguenti componenti:pixassociates/sortable-behavior-bundle e
stof/doctrine-extensions-bundle
Dovrete quindi avere préalablement créé un'entitàés che contiene un legame 1N con un dueècon
entitàé.
La manipolazione consiste unicamente à
iniettare il dueiècon entitàés nella chiamata della dédichiarazione del servizio della première con
l’argomento « aggiungiFiglio » e la
réfépresenza del servizio genitore.
Quando il’vogliamo fare référiferimento a un servizio si usa la chaînon utilizzareée per la dédichiarazione (che è libera), e si aggiunge « @ » per dire che c’è una référence.
#config/services.yaml
services:
admin.wconf:
class: App\Admin\WconfAdmin
tags:
- { name: sonata.admin, manager_type: orm, label: "Configuration des types" }
public: true
arguments: [~, App\Entity\Wconf, 'PixSortableBehaviorBundle:SortableAdmin']
calls:
- [setPositionService, ["@pix_sortable_behavior.position"]]
admin.wtype:
class: App\Admin\WtypeAdmin
arguments: [~, App\Entity\Wtype, ~]
calls:
- [addChild, ["@admin.wconf"]]
tags:
- { name: sonata.admin, manager_type: orm, label: "Types de contrats" }
public: true
Nei 2 controller admin, sarà necessario aggiungere i référiferimenti alle seguenti librerie:
use Knp\Menu\ItemInterface as MenuItemInterface;
use Sonata\AdminBundle\Admin\AdminInterface;
use Sonata\AdminBundle\Route\RouteCollection;
use Pix\SortableBehaviorBundle\Services\PositionORMHandler as PositionHandler;
Poi in l’interfaccia Parent, si aggiungono i pulsanti.
Per l’url di l’interfaccia fili, bisogna
dargli la référence del servizio per che’il
créé le strade. Poiché il nostro servizio è
« admin.wconf », la référence per la lista sarà quindi ‘admin.wconf.elenco’
protected function configureSideMenu(MenuItemInterface $menu, $action, AdminInterface $childAdmin = null): void
{
if (!$childAdmin && !\in_array($action, ['edit'], true)) {
return;
}
$admin = $this->isChild() ? $this->getParent() : $this;
$id = $admin->getRequest()->get('id');
$label=$this->hasSubject() && null !== $this->getSubject()->getLabel() ? $this->getSubject()->getLabel():null;
$menu->addChild(
'Configuration du contrat '.$label,
$admin->generateMenuUrl('edit', ['id' => $id])
);
$menu->addChild( 'Configuration des interfaces '.$label,
[
'uri' => $admin->generateUrl('admin.wconf.list', ['id' => $id])
]);
}
Poiché ora la nostra interfaccia CRUD figlia è limitata all'ambito del nostro sélezione genitore, e che desideriamo gérer l’ordine in drag’n drop, elimineremo la possibilitàé di ordinare la lista.
Basta
solo di’aggiungere l’argomento sortable=false (predefinito true), durante la définizione dei campi della lista.
protected function configureListFields(ListMapper $listMapper)
{
$listMapper->add('_action', null, array(
'actions' => array(
'move' => array(
'template' => '@PixSortableBehavior/Default/_sort_drag_drop.html.twig',
'enable_top_bottom_buttons' => false, //optional
),
),
))
;
$listMapper->addIdentifier('etape', null, ['label' => 'Etape','sortable'=>false]);
$listMapper->addIdentifier('position', null, ['label' => 'position','sortable'=>false]);
//$listMapper->addIdentifier('id', null, ['label' => 'id','sortable'=>false]);
$listMapper->addIdentifier('label', null, ['label' => 'Label','sortable'=>false]);
$listMapper->addIdentifier('synchro_field', null, ['label' => 'Destination du champs','sortable'=>false]);
$listMapper->add('actif', null, ['editable' => true,'sortable'=>false]);
}
Vogliamo anche conservare l’ordine per déoccorre, affinché l’l'utente ritrova sempre il mêil mio ordine
à ogni ricarica.
Ci sono due manières.
La premiaère, consiste à sovrascrivere la
configurazione per débisogna :
public function __construct( $code, $class, $baseControllerName ) {
parent::__construct( $code, $class, $baseControllerName );
}
protected $datagridValues = array(
'_page' => 1,
'_sort_by' => 'position',
'_sort_order' => 'ASC',
);
La seconda méthode, permette di fare una selezione più fine, per esempio su 2 campi sovraccaricando la richiestaêti usiée per la lista.
public function createQuery($context = 'list')
{
$proxyQuery = parent::createQuery('list');
$proxyQuery->addOrderBy($proxyQuery->getRootAlias().'.etape', 'ASC');
$proxyQuery->addOrderBy($proxyQuery->getRootAlias().'.position', 'ASC');
return $proxyQuery;
}
E lì ci si rende conto che se si déattivo l’ordine delle colonne, il nostro ordine configuratoé nella nostra
richiestaênon ti funziona più.
Quindi, quello che’andiamo a fare, c’è sovraccaricare il template solo per questa lista, e togliere il codice che gère le entêtè di colonne, ma conservare tutto il resto.
L'elenco si trova in vendor/sonata-project/admin-bundle/src/Resources/views/CRUD/base_list.html.twig e il nostro block interessatoé est « intestazione_tabella »
Aggiungeremo il nostro template nel dédichiarazione del nostro servizio.
Per questo dobbiamo prendere la référence del template, dégrida in questa pagina
: https://symfony.com/doc/master/bundles/SonataAdminBundle/reference/templates.html#global-templates
Dans
il nostro caso c’è
E aggiungeremo semplicemente una chiamata di tipo setTemplate con la nostra configurazione
admin.wconf:
class: App\Admin\WconfAdmin
tags:
- { name: sonata.admin, manager_type: orm, label: "Configuration des types" }
public: true
arguments: [~, App\Entity\Wconf, 'PixSortableBehaviorBundle:SortableAdmin']
calls:
- [setPositionService, ["@pix_sortable_behavior.position"]]
- [ setTemplate, [list, "Admin/wconf-list.html.twig"]]
Abbiamo messo :
« Admin/wconf-list.html.twig »
Ciò che significa che il sistèMi vai a cercare il file /templates/Admin/wconf-list.html.twig
Questo file deve
étendere la vista iniziale della lista, e redéfinire il blocco che gère l’entêsolo a te. Vogliamo davvero conservare tutto il resto.
Dunque, noi démetti il nostro file dando la référence del modello maître, e rossoéfinisci poi il nostro blocco
#/templates/Admin/wconf-list.html.twig
{% extends '@SonataAdmin/CRUD/base_list.html.twig' %}
{% block table_header %}
<thead>
<tr class="sonata-ba-list-field-header">
{% for field_description in admin.list.elements %}
{% if admin.hasRoute('batch') and field_description.getOption('code') == '_batch' and batchactions|length > 0 %}
<th class="sonata-ba-list-field-header sonata-ba-list-field-header-batch">
<input type="checkbox" id="list_batch_checkbox">
</th>
{% elseif field_description.getOption('code') == '_select' %}
<th class="sonata-ba-list-field-header sonata-ba-list-field-header-select"></th>
{% elseif field_description.name == '_action' and app.request.isXmlHttpRequest %}
{# Action buttons disabled in ajax view! #}
{% elseif field_description.getOption('ajax_hidden') == true and app.request.isXmlHttpRequest %}
{# Disable fields with 'ajax_hidden' option set to true #}
{% else %}
{% set sortable = false %}
{% apply spaceless %}
<th class="sonata-ba-list-field-header-{{ field_description.type }}{% if sortable %} sonata-ba-list-field-header-order-{{ sort_by|lower }} {{ sort_active_class }}{% endif %}{% if field_description.options.header_class is defined %} {{ field_description.options.header_class }}{% endif %}"{% if field_description.options.header_style is defined %} style="{{ field_description.options.header_style }}"{% endif %}>
{% if field_description.getOption('label_icon') %}
<i class="sonata-ba-list-field-header-label-icon {{ field_description.getOption('label_icon') }}" aria-hidden="true"></i>
{% endif %}
{{ field_description.label|trans({}, field_description.translationDomain) }}
</th>
{% endapply %}
{% endif %}
{% endfor %}
</tr>
</thead>
{% endblock %}
Poi abbiamo la nostra entête senza i collegamenti per poter ordinare i contenuti.
Siamo sûr che l’utente non vaérer l’ordine in drag’un drop con una selezione mal configurataé e chiamarci ogni 5 minuti per dirci che ça non funziona.
Adattare l’esempio alla versione installata
Gli esempi Symfony e Sonata rimangono legati alle versioni indicate nell’articolo. Symfony 4.x e Symfony 6.2 non sono più supportati: per un progetto attuale, utilizzate un ramo mantenuto e la documentazione corrispondente esattamente alle vostre dipendenze.
php bin/console about
composer show symfony/framework-bundle sonata-project/admin-bundle
Prima di riprendere il codice, controllate le firme, i servizi, le rotte e i template interessati. Aggiungete poi un test funzionale che copra le autorizzazioni, il codice HTTP e il risultato visibile.
Riferimento : versioni di Symfony supportate.