Custom view sort plugin not working only when used in table sorting We have a view of committee memberships (= custom entity). The committee memberships hold references to the committee and the politician and have a field &quot;role&quot;. In a view we want to output all committee memberships in a logical order: chairperson first, the vice chairperson, foreperson, spokesperson and member. As you can see alphabetical order is not suitable.
We defined a custom view sort plugin which is playing nice on simple views where the sorting is set in the views configuration. However on a table view when selecting the column for the sorting by role it is not called.
Examples:

https://www.abgeordnetenwatch.de/bundestag/19/ausschuesse/1-untersuchungsausschuss-terroranschlag-auf-dem-breitscheidplatz - the sorting is correct
https://www.abgeordnetenwatch.de/bundestag/19/ausschuesse/1-untersuchungsausschuss-terroranschlag-auf-dem-breitscheidplatz/tabelle#filterbar the committee members are sorted by last name by default (we will change this)... when you click on the last column heading &quot;Rolle im Ausschuss&quot; it should be the same order as the first example. But it is sorted by the key of the role stored in database. &quot;Stellv. Mitglied&quot; has the key &quot;alternate_member&quot; in database that is why these members come first in this table

We defined the plugin in the following way in a class extending EntityViewsData:
$data['committee_membership']['committee_role']['sort']['id'] = 'sort_committee_membership';

The plugin is that:
/**
 * Sort handler for sorting committee memberships by list key position.
 *
 * @ingroup views_sort_handlers
 *
 * @ViewsSort(&quot;sort_committee_membership&quot;)
 */
class SortCommitteeMembership extends SortPluginBase {

  public function query() {
    $this-&gt;ensureMyTable();
    $field_storage = \Drupal::service('entity_field.manager')-&gt;getFieldStorageDefinitions('committee_membership')[$this-&gt;field];
    $allowed_values = array_keys(options_allowed_values($field_storage));
    $formula = 'FIELD(' . $this-&gt;tableAlias . '.' . $this-&gt;field . ', ' . implode(', ', array_map(array(Database::getConnection(), 'quote'), $allowed_values)) . ')';

    $this-&gt;query-&gt;addOrderBy(NULL, $formula, $this-&gt;options['order'], $this-&gt;tableAlias . '_' . $this-&gt;field . '_keys');
  }

}

Is there something missing which is needed to implement when the sorting is exposed?!
The problem is that for click sorting it seems that not the view sort plugin is used but the field handler which holds a method clickSort
So here is the solution:
1.) I defined a custom field handler. This can be done in hook_views_data or hook_views_data_alter. I did it in my custom views EntityViewsData extending class:
$data['custom_entity']['committee_role']['field']['id'] = 'committee_role';

2.) Then I defined the field handler class where clickSort can be overwritten.
use Drupal\Core\Database\Database;
use Drupal\views\Plugin\views\field\EntityField;

/**
 * @ingroup views_field_handlers
 *
 * @ViewsField(&quot;committee_role&quot;)
 */
class CommitteeRole extends EntityField {

  public function clickSort($order) {
    // No column selected, can't continue.
    if (empty($this-&gt;options['click_sort_column'])) {
      return;
    }

    $this-&gt;ensureMyTable();
    $field_storage = \Drupal::service('entity_field.manager')-&gt;getFieldStorageDefinitions('committee_membership')[$this-&gt;field];
    $allowed_values = array_keys(options_allowed_values($field_storage));
    $formula = 'FIELD(' . $this-&gt;tableAlias . '.' . $this-&gt;field . ', ' . implode(', ', array_map(array(Database::getConnection(), 'quote'), $allowed_values)) . ')';

    $this-&gt;query-&gt;addOrderBy(NULL, $formula, $order, $this-&gt;tableAlias . '_' . $this-&gt;field . '_keys');
  }
}

After clearing the caching the results in the table are sorted the same way as in the other view. Strange that there is an additional sorting logic in views when a table display is used and the sorting is done via column headers.