0

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();
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.