Customising filter for ModelAdmin to support date range in SilverStripe

Viewed 322

I am developing a SilverStripe project. I am now struggling with customizing the filter/ search for the ModelAdmin entities, https://silverstripe.org/learn/lessons/v4/introduction-to-modeladmin-1. I am trying to add a date range filter as follows.

enter image description here

As you can see there are from and to fields. I have a class called Property and I am trying to customize the search/ filter for the CMS as follow to support the date range filtering.

class Property extends DataObject
{
    public function searchableFields()
    {
        return [
            //other fields go here
            'Created' => [
                'filter' => 'GreaterThanOrEqualFilter',
                'title' => 'From',
                'field' => DateField::class
            ],
            'Created' => [
                'filter' => 'To',
                'title' => 'Decision date until',
                'field' => DateField::class
            ],
        ];
    }
}

Only one field is added to the pop up because the array key is overridden. How can I configure it to have the two date fields to specify the date range for the search form?

2 Answers

It might not be relevant now but I bumped to this issue today and I tried your code, you are right, only one field is created I think because you are using single DateField::class. I tried to look for a module that creates a Date Range field and I only can find this one but it looks like it's a project specific.

In my case I have 2 date fields (created and ended), using your code I can get good results by tweaking it to something like this:

 public function searchableFields()
{
    return [
        //other fields go here
        'StartDate' => [
            'filter' => 'GreaterThanOrEqualFilter',
            'title' => 'From',
            'field' => DateField::class
        ],
        'EndDate' => [
            'filter' => 'LessThanOrEqualFilter',
            'title' => 'To',
            'field' => DateField::class
        ],
    ];
}

Hope it helps someone.

Using this example DataObject create a custom update function updateAdminSearchFields...

app/src/Test/MyDataObject.php

namespace MyVendor\MyNamespace;

use SilverStripe\Forms\DateField;
use SilverStripe\ORM\DataObject;

class MyDataObject extends DataObject {

    private static $db = [
        'Title'           => 'Varchar',
        'MyDateTimeField' => 'DBDatetime'
    ];

    private static $summary_fields = ['Title','MyDateTimeField'];

    public function updateAdminSearchFields($fields) {
        $fields->removeByName('MyDateTimeField');//needed as added in summary field
        $fields->push(DateField::create('MyDateTimeField:GreaterThanOrEqual', 'MyDateTimeField (Start)'));
        $fields->push(DateField::create('MyDateTimeField:LessThanOrEqual', 'MyDateTimeField (End)'));
    }
}

Then create an extension that can link that to a ModelAdmin...

app/src/Test/MyAdminExtension.php

namespace MyVendor\MyNamespace;

use SilverStripe\ORM\DataExtension;

class MyAdminExtension extends DataExtension {
    public function updateSearchContext($context) {
        $class = $context->getQuery([])->dataClass();
        if (method_exists($class, 'updateAdminSearchFields'))
            (new $class)->updateAdminSearchFields($context->getFields());

        return $context;
    }
}

app/_config/mysite.yml

MyVendor\MyNamespace\MyAdmin:
  extensions:
    - MyVendor\MyNamespace\MyAdminExtension

Lastly on the ModelAdmin apply these filters...

app/src/Test/MyAdmin.php

namespace MyVendor\MyNamespace;

use SilverStripe\Admin\ModelAdmin;

class MyAdmin extends ModelAdmin {

    private static $menu_title = 'MyAdmin';
    private static $url_segment = 'myadmin';
    private static $managed_models = [MyDataObject::class];

    public function getList() {
        $list = parent::getList();
        if ($params = $this->getRequest()->requestVar('filter'))
            if ($filters = $params[$this->sanitiseClassName($this->modelClass)])
                return $list->filter($filters);

        return $list;
    }
}

This example is working on latest stable version 4.7.2

Related