Laravel-datatables: Search: Retrieving attribute via id

Created on 1 Jun 2016  ·  3Comments  ·  Source: yajra/laravel-datatables

Summary of problem or feature request

One-To-Many Relationship asserted via storing id of owning entity in table of many entity. E.g.: coordinator manages one or many centers. After setting the columns via the html builder, I edit the coodinator_id column and apply an accessor method to retrieve the coordinators full name:

public function getFullNameAttribute()
{
    return $this->first_name . ", " . $this->last_name;
}

My aim is to allow only the centers that belong to the authenticated coordinator to be displayed on the datatable unless the authenticated user is an admin as shown in my queries.
However, if I enter the value of the Coordinator column that appears on the datatable it says no matching records found.

How do I achieve this?

Code snippet of problem

<?php

namespace App\DataTables;
use Auth;
use App\Center;
use App\Coordinator;
use Yajra\Datatables\Services\DataTable;

class CentersDataTable extends DataTable
{
    // protected $printPreview  = 'path.to.print.preview.view';

    /**
     * Display ajax response.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function ajax()
    {
        return $this->datatables
            ->eloquent($this->query())
            ->editColumn('action', function ($center) {
                return '<a href="edit-center/'.$center->id.'" <i class="material-icons sideicons-tables">create</i>'; 
               // <a href="field-technician-delete/'.$user->id.'" <i class="material-icons sideicons-tables">delete</i>
            })
            ->editColumn('coordinator_id', function ($user) {
                return Coordinator::find($user->coordinator_id)->full_name;
                })
            ->editColumn('gps_lat', function ($center) {
                    return $center->gps_location ;
                })
            ->make(true);
    }

    /**
     * Get the query object to be processed by datatables.
     *
     * @return \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder
     */
    public function query()
    {
        if(Auth::user()->hasRole('admin')){
        $centers = Center::query();
        return $this->applyScopes($centers);
        }
        else{
            $centers = Center::query()->where('coordinator_id',Auth::user()->userable->id);
            return $this->applyScopes($centers);
        }
    }

    /**
     * Optional method if you want to use html builder.
     *
     * @return \Yajra\Datatables\Html\Builder
     */
    public function html()
    {
        return $this->builder()
             ->columns([
                'id' => ['title' => 'ID'],
                'center_name' => ['title' => 'Name'], 
                'gps_lat' => ['title' => 'Coordinates'],
                'contact_no' => ['title' => 'Contact Number'],
                'coordinator_id' => [
                            'title' => 'Coordinator',
                            'searchable' => true
                ],
                'created_at' => [ 'title' => 'Created'],
                 'updated_at' => ['title' => 'Updated'], 
                'action' => [
                             'data'           => 'action',
                            'name'           => 'action',
                            'render'         => null,
                            'orderable'      => false,
                            'searchable'     => false,
                            'exportable'     => false,
                            'printable'      => false
                             ]
             ])
             ->parameters([
                 'dom' => 'Bfrtip',
                 'buttons' => ['csv', 'excel', 'print','reload'],
             ]);
    }

    /**
     * Get columns.
     *
     * @return array
     */
    private function getColumns()
    {
        return [
            'id',
            // add your columns
            'created_at',
            'updated_at',
        ];
    }

    /**
     * Get filename for export.
     *
     * @return string
     */
    protected function filename()
    {
        return 'centers';
    }
}

System details

  • Operating System : OS X El Capitan 10.11.5
  • PHP Version : 7.0.0
  • Laravel Version : 5.1.36 (LTS)
  • Laravel-Datatables Version : 6.11.5

Regards,

question

Most helpful comment

A trick you can do is add both columns on js but them so they can still be searchable:

'last_name' => [
    'data' => 'coordinator.last_name',
    'visible' => false,
    'name' => 'coordinator.last_name',
],
'coordinator' => [
    'data' => 'coordinator',
    'name' => 'coordinator.first_name',
],

->addColumn('coordinator', function ($user) {
    return Area_Coordinator::find($user->area_coordinator_id)->full_name;
})

All 3 comments

Are you trying to search on coordinator's name? If that is the case then you can use eager loading or join queries for it work.

I tried eager loading,modified as per the tutorial on your site. However, now my issue is I am not storing the coordinators' full name, rather their first and last name separately. What I have currently:
query

$centers = Center::query()->with('coordinator')->where('coordinator_id',Auth::user()->userable->id);
            return $this->applyScopes($centers);

columns

'first_name' => [
                'data' => 'coordinator.first_name',
                'name' => 'coordinator.first_name',
                            'title' => 'Coordinator',
                            'searchable' => true,
                ],

edit method

->editColumn('first_name', function ($user) {
                return Area_Coordinator::find($user->area_coordinator_id)->full_name;
                })

I can search via the coordinators first name, however, since I want to search by that and the last name is there a way to concatenate both into one column? Or rather, apply my accessor method, or should I just include the last name column in the datatable?

Regards,

A trick you can do is add both columns on js but them so they can still be searchable:

'last_name' => [
    'data' => 'coordinator.last_name',
    'visible' => false,
    'name' => 'coordinator.last_name',
],
'coordinator' => [
    'data' => 'coordinator',
    'name' => 'coordinator.first_name',
],

->addColumn('coordinator', function ($user) {
    return Area_Coordinator::find($user->area_coordinator_id)->full_name;
})
Was this page helpful?
0 / 5 - 0 ratings

Related issues

SGarridoDev picture SGarridoDev  ·  3Comments

hohuuhau picture hohuuhau  ·  3Comments

macnux picture macnux  ·  3Comments

techguydev picture techguydev  ·  3Comments

Abdulhmid picture Abdulhmid  ·  3Comments