Add Category Title Search

In every grid page, there is a search field to search database fields, currently we can only search title and alias. Let's add foreign fields search to articles page.

Open Form/articles/GridDefinition.php and add two new options in search group. It means we told model to search category.title and category.alias two more fields.

The category. is what you set in ListRepository::configureTable(), please see Grid section to know how it works.

// src/Blog/Admin/Articles/GridDefinition.php

// ...

class GridDefinition extends AbstractFieldDefinition
{
    public function doDefine(Form $form)
    {
        $this->group('search', function (Form $form)
        {
            // Search Field
            $form->list('field')
                ->label(Translator::translate('phoenix.grid.search.field.label'))
                ->set('display', false)
                ->defaultValue('*')
                ->option(Translator::translate('phoenix.core.all'), '*')
                ->option(Translator::translate('admin.article.field.title'), 'article.title')
                ->option(Translator::translate('admin.article.field.alias'), 'article.alias');

                // Add these two lines
                ->option('Category Title', 'category.title')
                ->option('Category Alias', 'category.alias');

            // ...
        });

        // ...

Back to articles page and search some keyword.

Imgur

You can see the category field is able to search. Let's add simple highlight in ArticlesHtmlView.

// src/Blog/Admin/View/Articles/ArticlesHtmlView.php

// ...

class ArticlesHtmlView extends GridView
{
    // ...

    protected function prepareScripts()
    {
        // ...

        // Add Highlight script
        JQueryScript::highlight('.grid-table', trim($this->data->state['input.search.content']));
    }

This is highlight result.

Imgur

Disable Fuzzing Searching

By default, windwalker will separate search text by space and use fuzzing search, if you want to compare whole string, set fuzzy_searching to false in List GetController.

// src/Flower/Controller/Sakuras/GetController.php

namespace Flower\Controller\Sakuras;

class GetController extends ListDisplayController
{
    // ...

    protected $fuzzingSearching = false;

    // ...

Add More Filters

Currently, articles page has only one filter: state, we can add a category filter and a date filter to help us manage articles.

Add Category Filter

// src/Blog/Admin/Articles/GridDefinition.php

// ...

class GridDefinition extends AbstractFieldDefinition
{
        // ...

        $this->group('filter', function(Form $form)
        {
            // ...

            // Category
            $form->add('category.id', new CategoryListField)
                ->label('Category')
                ->option('', '')
                ->option('-- Select Category --', '')
                ->onchange('this.form.submit()');

        // ...

This is the result that we can filter by category ID.

Imgur

The category. is what you set in ListRepository::configureTable(), please see Grid section to know how it works.

Add Date Filter

We add Start Date and End Date to filter a time period.

// src/Blog/Admin/Articles/GridDefinition.php

// ...

class GridDefinition extends AbstractFieldDefinition
{
       use PhoenixFieldTrait;

        // ...

        $this->group('filter', function(Form $form)
        {
            // ...

            // Category
            $this->add('category.id', new CategoryListField)
                ->label('Category')
                ->option('', '')
                ->option('-- Select Category --', '')
                ->onchange('this.form.submit()');

            // Start Date
            $this->calendar('start_date')
                ->label('Start Date')
                ->format('Y-m-d')
                ->placeholder('Start Date');

            // End Date
            $this->calendar('end_date')
                ->label('End Date')
                ->format('Y-m-d')
                ->placeholder('End Date');

        // ...

The start and end date use >= and <= to filter items, not =, so we must configure it in ArticlesRepository.


class ArticlesRepository extends ListRepository
{
    // ...

    // This is an important security setting.
    // Add these two fields that will able to pass the fields checking.
    // Otherwise anyone can try your database.
    protected $allowFields = array(
        'start_date', 'end_date'
    );

    // ...

    protected function configureFilters(FilterHelperInterface $filterHelper)
    {
        // Override start_date action
        $filterHelper->setHandler('start_date', function(Query $query, $field, $value)
        {
            if ((string) $value !== '')
            {
                $query->where('article.created >= ' . $query->quote($value));
            }
        });

        // Override end_date action
        $filterHelper->setHandler('end_date', function(Query $query, $field, $value)
        {
            if ((string) $value !== '')
            {
                $query->where('article.created <= ' . $query->quote($value));
            }
        });
    }

OK, you can try to filter the date.

Imgur

Go to debugger, you will see the SQL is:

SELECT
-- ...

WHERE article.created >= '1970-09-10' AND article.created <= '1973-09-09'

-- ...

Disable Filter or Search

In template, you will see this line includes filter & search bar:

{{-- FILTER BAR --}}
<div class="filter-bar">
    {!! $filterBar->render(array('form' => $form, 'show' => $showFilterBar)) !!}
</div>

Add options to hide filter or search:

{{-- FILTER BAR --}}
<div class="filter-bar">
    {!! $filterBar->render(array('form' => $form, 'show' => $showFilterBar, 'search' => false, 'filter' => false)) !!}
</div>

If you found a typo or error, please help us improve this document.