Magento 2 - champ de grille d'administration personnalisé - erreur lors du tri ou du filtrage

9

J'ai ajouté une colonne personnalisée à la grille d'administration, comme ceci

<column name="customer_name" class="Vendor\Module\Ui\Component\Listing\Columns\CustomerName">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="filter" xsi:type="string">text</item>
                <item name="editor" xsi:type="string">text</item>
                <item name="sortable" xsi:type="string">true</item>
                <item name="label" xsi:type="string" translate="true">Customer Name</item>
                <item name="sortOrder" xsi:type="number">30</item>
            </item>
        </argument>
    </column>

Dans ma classe CustomerName, je crée des valeurs pour cette colonne:

public function prepareDataSource(array $dataSource)
{
    $fieldName = $this->getData('name');
    foreach ($dataSource['data']['items'] as & $item) {
        $customer = $this->customerRepository->getById($item['customer_id']);
        $name = $customer ? $customer->getFirstName().' <'.$customer->getEmail().'>' : '';
        $item[$fieldName] = $name;
    }
    return $dataSource;
}

Il apparaît dans la grille comme prévu. Mais quand j'essaye de trier par cette colonne ou filtre - une erreur se produit

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'customer_name' in 'order clause'

Comment puis-je réparer cela?

MISE À JOUR

Maintenant, j'essaie de résoudre ce problème en supprimant la classe CustomerName (et en supprimant la référence dans la balise de colonne en xml) et à la place, j'ai ajouté la fonction _renderFiltersBefore () dans ma classe de collection

 protected function _renderFiltersBefore() {
     $joinTable = $this->getTable('customer_entity');
     $this->getSelect()->join($joinTable.' as customer_entity','main_table.customer_id = customer_entity.entity_id', array('*'));
     $this->getSelect()->columns('CONCAT(firstname," <",email,">") as customer_name');
     parent::_renderFiltersBefore();
}

Le tri fonctionne maintenant, mais pas le filtrage (obtenez la même erreur)

Anna
la source

Réponses:

13

Il existe une méthode d'usine que vous pouvez utiliser, et c'est la addFilterToMap(). Où le filtre de rendu Magento 2 remplace simplement les sujets des conditions en fonction des champs mappés

vous pouvez l'appeler dans la méthode _initSelect ou _renderFiltersBefore .

pour une simple colonne qui existe déjà dans la sélection (bon pour résoudre les erreurs ambiguës)

$this
     ->addFilterToMap('customer_id', 'ce.entity_id');

mais dans votre cas, vous devez mapper une expression comme

$this
    ->addFilterToMap(
       'customer_name ', 
       new \Zend_Db_Expr('CONCAT(ce.firstname," <",ce.email,">")')
    ); 

donc la partie condition de la requête sera ... WHERE (CONCAT(ce.firstname," <",ce.email,">") LIKE '%@yippie.com%') ... au lieu de ... WHERE (customer_name LIKE '%@yippie.com%') ...

vous pouvez également utiliser une autre méthode d'usine liée à une collection pour utiliser des expressions dans une SELECTpartie de la requête

$this
    ->addExpressionFieldToSelect(
        'firstname',
        new \Zend_Db_Expr('CONCAT(ce.firstname," <",ce.email,">")'),
        []
    )

au lieu de

$this->getSelect()->columns('CONCAT(ce.firstname," <",ce.email,">") as firstname');
Mammouth
la source
Merci beaucoup! Je me battais avec ça pendant une demi-journée. Où avez-vous trouvé / appris cela? Sûrement pas dans les documents?
Jānis Elmeris
comme le message d'origine l'a mentionné: a dû ajouter une colonne personnalisée à la grille d'administration - avec des options de filtre et de tri. Il a fallu environ 1,5 jour pour le comprendre (souvent avec le moins d'empreinte)
Mammouth
J'essaie d'afficher à la fois la facture et l'ordre de vente increment_ids sur ma grille d'administration de module personnalisé avec l'ID d'incrément de l'ordre de vente est rebaptisé 'ordincrementid'. Même moi, j'avais utilisé addFilterToMap (); je ne peux pas filtrer l'incrément_id de l'ordre de vente. Il renvoie cette erreur => Colonne 'increment_id' dans la clause where est ambiguë
Ask Bytes
6

Cela a pris du temps, mais j'ai compris

Dans ma liste xml:

<column name="firstname">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="filter" xsi:type="string">text</item>
                <item name="editor" xsi:type="string">text</item>
                <item name="sortable" xsi:type="string">true</item>
                <item name="label" xsi:type="string" translate="true">Customer Name</item>
                <item name="sortOrder" xsi:type="number">30</item>
            </item>
        </argument>
    </column>

Dans Vendor \ Module \ Model \ ResourceModel \ SomeCustomModel \ Grid:

/**
 * adding email to customer name column
 */
protected function _initSelect()
{
    parent::_initSelect();
    $this->getSelect()->joinLeft(
        ['ce' => $this->getTable('customer_entity')],
        'main_table.customer_id = ce.entity_id',
        ['*']
    );

    $this->getSelect()->columns('CONCAT(ce.firstname," <",ce.email,">") as firstname');
    return $this;
}

Dans Vendor \ Module \ Model \ ResourceModel \ SomeCustomModel

/**
 * addding ability to filter by column with customer name and email
 */
protected function _renderFiltersBefore()
{
    $wherePart = $this->getSelect()->getPart(\Magento\Framework\DB\Select::WHERE);
    foreach ($wherePart as $key => $cond) {
        $wherePart[$key] = str_replace('`firstname`', 'CONCAT(firstname," <",email,">")', $cond);
    }
    $this->getSelect()->setPart(\Magento\Framework\DB\Select::WHERE, $wherePart);
    parent::_renderFiltersBefore();
}
Anna
la source