TransWikia.com

Order by dynamic field in custom Element Type

Craft CMS Asked by Matt Jenkins on June 1, 2021

In my module, I have a custom Element Type with three fields (firstName, lastName, email) that are dispalyed on an element index page in the CP.

I have the first column as a full name by concating the first and last which works fine but I’d like to be able to sort this when selecting the heading but firstName and then lastName e.g. "…ORDER BY firstName ASC, lastName ASC"

I have an element query class however I’m not sure how to affect the ordering for the element in there (or even if that’s where I’m supposed to do it).

The Element Type:

class Subscriber extends Element
{

    public $firstName;
    public $lastName;
    public $email;

    ...

    public function __toString()
    {
        $firstName = trim($this->firstName);
        $lastName = trim($this->lastName);
        return $firstName . ($firstName && $lastName ? ' ' : '') . $lastName;
    }

    public static function find(): ElementQueryInterface
    {
        return new SubscriberQuery(static::class);
    }

    protected static function defineTableAttributes(): array
    {
        return [
            'fullName' => Craft::t('app', 'Full Name'),
            'firstName' => Craft::t('app', 'First Name'),
            'lastName' => Craft::t('app', 'Last Name'),
            'email' => Craft::t('app', 'Email'),
        ];
    }

}

The Element Query:

class SubscriberQuery extends ElementQuery
{

    public $firstName;
    public $lastName;
    public $email;

    public function firstName(string $firstName) {
        $this->firstName = $firstName;
        return $this;
    }

    public function lastName(string $lastName) {
        $this->lastName = $lastName;
        return $this;
    }

    public function email(string $email) {
        $this->email = $email;
        return $this;
    }

    protected function beforePrepare(): bool
    {
        $this->joinElementTable('na_subscriber');

        $this->query->select([
            'na_subscriber.firstName',
            'na_subscriber.lastName',
            'na_subscriber.email',
        ]);

        if ($this->firstName) {
            $this->subQuery->andWhere(Db::parseParam('na_subscriber.firstName', $this->firstName));
        }

        if ($this->lastName) {
            $this->subQuery->andWhere(Db::parseParam('na_subscriber.lastName', $this->lastName));
        }

        if ($this->email) {
            $this->subQuery->andWhere(Db::parseParam('na_subscriber.email', $this->email));
        }

        return parent::beforePrepare();
    }
}

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP