2

I have a view, and I want the users to be able to filter on an Integer field. String fields allow for filtering by 'Starts with'. I would like to do the same but with an integer.

If the user enters "10" it would match 100, 1010, etc, but not 210.

1
  • 1
    Then write your own custom views filter plugin.
    – No Sssweat
    Commented Feb 28, 2020 at 6:18

2 Answers 2

2

You can do this with a combine fields filter.

You first need to include the field you want to filter on. Once the field is in you add the filter combine fields filter and set it to exposed. Change the operator to "begins with" and select the integer field.

Save the changes and you should have the filtering option with the begins with option on an iteger field.

3
  • Unfortunately I need to do this with multiple number fields, and the UI allows the user to filter on each column/field. Commented Feb 28, 2020 at 14:15
  • You should be able to add multiple combined filter fields. One for each numeric field you want to use.
    – Rick B
    Commented Feb 28, 2020 at 18:17
  • I think your solution is better because it works out of the box. I am comparing the performance between the combined field filter and the custom filter plugin. Commented Feb 28, 2020 at 20:46
2

I was hoping for a way to do this without a custom filter, but after some research it clear why this is not available out of the box. 'Starts with' is implemented as field LIKE $value . '%' which contains both an implicit cast and a LIKE. There may be issues on databases other than MySQL due to the implicit casting.

src/Plugin/views/filter/StartsWithFilter.php

<?php

namespace Drupal\startswith\Plugin\views\filter;

use Drupal\views\Plugin\views\filter\NumericFilter;
use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\display\DisplayPluginBase;

/**
 * My custom numeric filter.
 *
 * @ingroup views_filter_handlers
 *
 * @ViewsFilter("starts_with_filter")
 */
class StartsWithFilter extends NumericFilter {
  /**
   * {@inheritdoc}
   */
  public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
    parent::init($view, $display, $options);
  }

  public function operators() {
    $operators = parent::operators();
    $operators += [
      'starts' => [
        'title' => $this
          ->t('Starts with'),
        'short' => $this
          ->t('begins'),
        'method' => 'opStartsWith',
        'values' => 1,
      ]
    ];

    return $operators;
  }

  protected function opStartsWith($field) {
    $group = $this->options['group'];

    $this->query->where[$group]['conditions'][] = array(
      'field' => $field ,
      'value' => db_like($this->value['value']) . '%',
      'operator' => 'LIKE',
    );

  }
}

Replaces the standard NumericFilter with our custom Filter.

startswith.module


function startswith_views_data_alter(&$data) {

  foreach($data as $k1 => $v1) {
    foreach($v1 as $k2 => $v2) {
      $has_filter = isset($v2['filter']) && isset($v2['filter']['id']);

      if ($has_filter) {
        $numeric_filter = $v2['filter']['id'] == 'numeric';

        if ($numeric_filter) {
          $data[$k1][$k2]['filter']['id'] = 'starts_with_filter';
        }

      }
    }
  }

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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