0

I'm trying to get more familiar with FieldPluginBase to create a new custom field for views. As an example I implemented a new field called 'dropdown list' that "wraps" other view-fields the user selects. Therefore I implemented a form in buildOptionsForm() that shows all currently displayed view fields and let's the user select multiple via checkboxes (kind of similar to the dropbutton behavior).

This works well and in render() I can see which fields the user checked via $this->options['field_types'].

Next I want to add the user-chosen fields to a renderarray and display them as an item list ('#theme' => 'item_list') to later add some custom css classes and style them. However, I have currently no way of accessing all fields that are shown in the view, only the entity fields via $entity->get('field_name')->getValue(). That gives me the standard entity fields like title, body, nid ... But I do have a Global: Custom text (id='nothing_2') that I need to access (that is excluded from display and output as a custom link). I found no way of accessing the value of such fields that do not directly belong to the entity (I tried $this->view->field[...] and $this->displayHandler->getValue(...) without success).

Any idea if what I'm trying to do is possible and what I'm missing ?

class DropDownList extends FieldPluginBase {

  public function query() {

  }

  protected function defineOptions() {
    $options = parent::defineOptions();
    $options['field_types'] = ['default' => []];
    return $options;
  }
  public function buildOptionsForm(&$form, FormStateInterface $form_state) {

    $fields = $this->displayHandler->getFieldLabels(TRUE);
    $pos = array_search('dropdown_list', $fields);
    unset($fields[$pos]);

    $form['field_types'] = array(
      '#title' => $this->t('Which fields should be included?'),
      '#type' => 'checkboxes',
      '#options' => $fields,
      '#default_value' => $this->options['field_types'],
    );
    parent::buildOptionsForm($form, $form_state);
  }

  public function render(ResultRow $values) {
    $items = [];
    if ($entity = $this->getEntity($values)) {
      // Dummy loop to show how I wanted to approach this
      // Checkboxes results are available like this (in this output
      // the user only checked the custom text 'nothing_2'):
      // nothing_2=>nothing_2 nid=>0 title=>0 body=>0 uid=>0
      foreach($this->options['field_types'] as $key=>$value) {
        if ( $value != '0') {
          // There is no field 'nothing_2'
          $items[] = $entity->get('field_name')->getValue();
        }
      }
    }
  $build['theme_element'] = [
      '#theme' => 'item_list',
      '#title' => $this->t(''),
      '#items' => $items,
    ];
    return $build;
  }
}

UPDATE

Using $this->view->field['nothing_2']->getValue($values) as also suggested by 4k4 returns an empty string, although I know that nothing_2 contains a link: <a href=....>Edit</a> but it does not seem to be directly contained in getValue()

  • try $this->view->field[...]->getValue($values), see drupal.stackexchange.com/questions/226514/… – 4k4 Nov 10 '17 at 11:18
  • then this specific field plugin doesn't support getValue(), I think the only method mandatory for a views field plugin is render(): $this->view->field[...]->render($values) – 4k4 Nov 10 '17 at 16:13
  • thanks a lot, you're right. $this->view->field[...]->render($values) does return the string "Edit" (from the <a href='...'>Edit</a>) As a plus: any idea how to retrieve the link part of that field ? – theuni Nov 10 '17 at 16:27
  • Yes, the link part is added in advancedRender(), which is what will later also be called on your plugin. So I'm not sure, if you are supposed to nest this. You can easily configure an infinite loop with such a field plugin. – 4k4 Nov 11 '17 at 16:12
1

As indicated by @4k4 the solution is using advancedRender() inside a for loop

public function render(ResultRow $values) {
  $items = [];
  foreach ($this->options['field_types'] as $key => $value) {
   if ($value != '0') {
    $items[] = $this->view->field[$key]->advancedRender($values);
   }
  }
$build['theme_element'] = [
  '#theme' => 'dropdownlist-theme',
  '#title' => $this->t('Dropdown List'),
  '#items' => $items,
 ];
 return $build;
}

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.