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/FilterDefinition.php and add two new options in search group. It means we told model to search category.title and category.alias two more fields.

// src/Blog/Admin/Articles/FilterDefinition.php

// ...

class FilterDefinition implements FieldDefinitionInterface
{
    public function define(Form $form)
    {
        $form->wrap(null, 'search', function (Form $form)
        {
            // Search Field
            $form->add('field', new ListField)
                ->label(Translator::translate('phoenix.grid.search.field.label'))
                ->set('display', false)
                ->defaultValue('*')
                ->addOption(new Option(Translator::translate('phoenix.core.all'), '*'))
                ->addOption(new Option(Translator::translate('admin.article.field.title'), 'article.title'))
                ->addOption(new Option(Translator::translate('admin.article.field.alias'), 'article.alias'))

                // Add these two lines
                ->addOption(new Option('Category Title', 'category.title'))
                ->addOption(new 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

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/FilterDefinition.php

// ...

class FilterDefinition implements FieldDefinitionInterface
{
        // ...

        $form->wrap(null, 'filter', function(Form $form)
        {
            // ...

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

        // ...

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

Imgur

Add Date Filter

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

// src/Blog/Admin/Articles/FilterDefinition.php

// ...

class FilterDefinition implements FieldDefinitionInterface
{
        // ...

        $form->wrap(null, 'filter', function(Form $form)
        {
            // ...

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

            // Start Date
            $form->add('start_date', new CalendarField)
                ->label('Start Date')
                ->set('format', 'YYYY-MM-DD')
                ->set('placeholder', 'Start Date');

            // End Date
            $form->add('end_date', new CalendarField)
                ->label('End Date')
                ->set('format', 'YYYY-MM-DD')
                ->set('placeholder', 'End Date');

        // ...

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


class ArticlesModel extends ListModel { // ... // 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 ($value !== null && $value !== '') { $query->where('article.created >= ' . $query->quote($value)); } }); // Override end_date action $filterHelper->setHandler('end_date', function(Query $query, $field, $value) { if ($value !== null && $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'

-- ...

Found a typo? Help us improve this document.

This document is for Windwalker Joomla RAD, if you are finding Windwalker PHP framework, please see: Windwalker Framework