2

We have a view of committee memberships (= custom entity). The committee memberships hold references to the committee and the politician and have a field "role". 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:

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("sort_committee_membership")
 */
class SortCommitteeMembership extends SortPluginBase {

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

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

}

Is there something missing which is needed to implement when the sorting is exposed?!

3
  • 2
    Tablesort is not the same as an exposed sort critera (see also drupal.org/project/drupal/issues/3059961) - I guess you'll need to create your own table display respecting your formula.
    – rémy
    Sep 29 '20 at 21:40
  • I am not sure if the linked issue really covers my problem. Do you have an idea how other sortings like title or entity id do still work in view tables when set as sortable columns? How can view tables handle these sortings when view is not using these plugins? Sep 30 '20 at 14:18
  • For reference on TableSort that @rémy referred to: api.drupal.org/api/drupal/… (I've never used it, but it may be useful!)
    – Mrweiner
    Oct 1 '20 at 0:49
3

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("committee_role")
 */
class CommitteeRole extends EntityField {

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

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

    $this->query->addOrderBy(NULL, $formula, $order, $this->tableAlias . '_' . $this->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.

1
  • Nicely done! It cannot the same, tableSort sorts according to the column selected, and an exposed filter according to the provided argument ;)
    – rémy
    Oct 2 '20 at 22:28
-1

A solution could be, to take use of the search_api module. After you've indexed the entities you want to display in the view, you can create a view based of the indexed items. That way you can get rid of the key, and only use the values. And no programming required.

As a bonus you get all kinds of sorts and facets to play around with.

3
  • I do not see how this solves my problem?! Sep 30 '20 at 14:18
  • It could be, I am not clear. But if the essence of your problem is that your table sort is now sorting on the key instead of the value and you want that to be turned around. This method is a good workaround which I have used several times in my projects to overcome these kinds of problems. If I didn’t understand your question right then I am sorry.
    – Rick B
    Sep 30 '20 at 21:55
  • No problem. The problem is not that the column is sorted by key and should be sorted by value. The sorting is not numeric or alphabetical neither by key nor by value. The sorting is implemented in a logical / fixed way. And as described - it is working for any view except for table views when the table should be sorted by the column. Oct 1 '20 at 10:52

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.