sleeping-owl / admin

Administrative interface builder for Laravel
http://sleeping-owl.github.io/
MIT License
503 stars 259 forks source link

My solution to search column from a joined table (DisplayDatatablesAsync) #264

Open s6carlo opened 8 years ago

s6carlo commented 8 years ago

I wrote a custom display to search column from a joined table, it need a custom column and a custom display model

In app/Admin/boostrap.php custom column and registrations

class MultiSearchString extends String
{
    /**
     * @return View
     */
    protected $searchTable='';
    /**
     * Get or set table 
     * @param string|null $searchTable 
     * @return $this|string
     */
    public function searchTable($searchTable = null)
    {
        if (is_null($searchTable))
        {
            return $this->searchTable;
        }
        $this->searchTable = $searchTable;
        return $this;
    }
}
// register the new column
Column::register('multiSearchString', 'MultiSearchString');
// register the new display class
AdminDisplay::register('datatablesAsyncMultiSearch', '\s6c\DatatablesAsyncMultiSearch');

I create a folder inside /app/Admin called s6c with a DatatablesAsyncMultiSearch.php file , it is used to override the applySearch method

<?php
namespace s6c;
use AdminTemplate;
use Carbon\Carbon;
use Input;
use Route;
use SleepingOwl\Admin\ColumnFilters\Date;
use SleepingOwl\Admin\Columns\Column\DateTime;
use SleepingOwl\Admin\Columns\Column\NamedColumn;
use SleepingOwl\Admin\Columns\Column\String;
use SleepingOwl\Admin\Interfaces\WithRoutesInterface;

class DatatablesAsyncMultiSearch extends  \SleepingOwl\Admin\Display\DisplayDatatablesAsync {

     protected function applySearch($query)
    {

        $search = Input::get('search.value');
        if (is_null($search))
        {
            return;
        }
           $query->where(function ($query) use ($search)
        {
            $columns = $this->columns();
            foreach ($columns as $column)
            {
                           if (get_class($column)== 'MultiSearchString')
                {
                    $name = $column->name();
                    $table = $column->searchTable();
                    $query->orWhere($table.'.'.$name, 'like', '%' . $search . '%');

                }
                elseif ($column instanceof String)
                {
                    $name = $column->name();
                    if ($this->repository->hasColumn($name))
                    {
                        $query->orWhere($name, 'like', '%' . $search . '%');
                    }
                }
            }
        });
    }

}

Now in the my model (Exampe.php) I add the method

// main table of this model
 protected $table = 'tableA';
// joined table
    public function newQuery(){
        $query = parent::newQuery();
        $query=$query->where('isEva', '=','1');
        $query=$query->join('tableB', 'tableB.id', '=', 'tableA.key_B');
        return $query;
    }

Finally in app\Example.php

Admin::model('App\Exampe')->title('ExampeA')
    ->display(function ()
    {
       $display = AdminDisplay::datatablesAsyncMultiSearch();
       $display->columns([
             // other string columns...
Column::multiSearchString('columnFromB')->label('B Searchable')->searchTable('tableB'),

Now if you try to search a text the input is used also in the columng from the second table (in the example tableB, thanks to the new applySearch method of the custom display.

My two cents for this project! ( #112, #63, #237 )

mapeveri commented 8 years ago

@s6carlo this is for v3?. This has méthod display that I not use. For the last version, you know how to do?

Thanks!

s6carlo commented 8 years ago

Yes is for v3, because I have to manage a lot of data and datatableasync is the best way, so I exend it. For other versione you should check if the display method you use have a method applysearch to be overridden in a subclass.

mapeveri commented 8 years ago

@s6carlo Could you explain a little more as it would in the others version?. Thanks!

s6carlo commented 8 years ago

@mapeveri You should follow these steps:

Sorry but I am using the dev version and I don't have the code for v3.

mapeveri commented 8 years ago

@s6carlo thanks!!