1

I am attempting to send two instances of DataTables to my view. The scenario involves having a tab menu with each tab containing a corresponding table. Here is the approach I have taken.

My controller

    public function show(AuthorityPage $authorityPage, 
        AuthorityPageGuideContentDataTable $authorityPageGuideContentDataTable, 
        AuthorityPageAccordionDataTable $authorityPageAccordionDataTable
        )
    {
       
        $blogPosts = BlogPost::where('domain_id', getCurrentDomain())->where('is_active',true)
        ->select(['id','name'])->get();
        $tours = Tour::where('domain_id', getCurrentDomain())
            ->with('generalDetail')->get();
        $destinations = Destination::where('domain_id', getCurrentDomain())
            ->select(['id','name'])->get();
        $keywordIntents = [
            'i' => 'Informational',
            'n' => 'Navigational',
            't' => 'Transactional',
            'c' => 'Commercial',
        ];

$accordionDt = $authorityPageAccordionDataTable->with([
            'authorityPage' => $authorityPage
        ])->html();
$authorityContentDt = $authorityPageGuideContentDataTable->with([
            'authorityPage' => $authorityPage
        ])->html();

return view('pages.authority-pages.show', compact(
            'authorityPage', 
            'blogPosts', 
            'tours', 
            'destinations', 
            'keywordIntents', 
            'authorityContentDt', // first dt
            'accordionDt' //2nd dt
        ));

in my first tab view i render the datatable by

    <div class="card-body py-4">
        <div class="table-responsive">
            {{ $authorityContentDt->table()}}
        </div>
    </div>

in my second tab

  <div class="card-body py-4">
            <div class="table-responsive">
                {{ $accordionDt->table() }}
            </div>
        </div>

one of my datatable class (similar to all of my datatable classes)

class AuthorityPageGuideContentDataTable extends DataTable
{
    public function dataTable(QueryBuilder $query): EloquentDataTable
    {
        return (new EloquentDataTable($query))
        ->editColumn('guide_type', function (DestinationGuideDetails $destinationGuideDetails) {
            return DestinationGuideType::byValue($destinationGuideDetails->guide_type)->name;
        })
        ->editColumn('content', function (DestinationGuideDetails $destinationGuideDetails) {
            return strip_tags($destinationGuideDetails->content);
        })
        ->addColumn('action', function (DestinationGuideDetails $destinationGuideDetails) {
            return '<button class="btn btn-icon btn-active-light-primary w-30px h-30px" onclick="deletedestinationGuideContent('.$this->authorityPage->id.' , '.$destinationGuideDetails->id.')"> '.getIcon("trash","fs-3").'</button>
            <button data-bs-toggle="modal" data-bs-target="#kt_modal_1" class="btn btn-icon btn-active-light-primary w-30px h-30px" onclick="getContent('.$this->authorityPage->id.','.$destinationGuideDetails->id.')"> '.getIcon("notepad-edit","fs-3").'</button>';
        })
        ->rawColumns(['action'])
        ->setRowId(function ($destinationGuideDetails) {
            return "destination-guide-details-{$destinationGuideDetails->id}";
        });
    }

    public function query(DestinationGuideDetails $model): QueryBuilder
    {
        $query = $model->newQuery()
        ->join('destination_guides', 'destination_guide_details.destination_guide_id', '=', 'destination_guides.id')
        ->where('destination_guides.guideable_id', $this->authorityPage->id)
        ->where('destination_guides.guideable_type', 'App\Models\AuthorityPage')
        ->select('destination_guide_details.*');
        return $query;
    }

    public function html(): HtmlBuilder
    {
        return $this->builder()
        ->setTableId('destination-guide-table')
        ->columns($this->getColumns())
        ->minifiedAjax()
        ->dom('rt' . "<'row'<'col-sm-12 col-md-5'l><'col-sm-12 col-md-7'p>>",)
        ->addTableClass('table align-middle table-row-dashed fs-6 gy-5 dataTable no-footer text-gray-600 fw-semibold')
        ->setTableHeadClass('text-start text-muted fw-bold fs-7 text-uppercase gs-0');
    }


    public function getColumns(): array
    {
        return [
            Column::make('guide_type')->name('guide_type'),
            Column::make('content')->name('Content'),
            Column::make('action')->name('Action')->width('10%'),
        ];
    }

    protected function filename(): string
    {
        return 'AuthorityPageGuideContent_' . date('YmdHis');
    }
}

The problem is it returns an alert saying

DataTables warning: table id=destination-guide-table - Invalid JSON response. 
For more information about this error, please see http://datatables.net/tn/1
3
  • 1
    And whats the problem? Commented Feb 10, 2024 at 22:25
  • Oh sorry @Brandon I havent included the error i forgot. I updated the question. Thanks :) Commented Feb 10, 2024 at 22:53
  • 1
    can you include the response @draw134 Commented Feb 11, 2024 at 16:35

1 Answer 1

1

Firstly, set up routes that invoke your DataTable classes:

Route::get('/authority-pages/{authorityPage}/destination-guide', [AuthorityPageController::class, 'getAuthorityPageGuideContentData'])->name('authority-pages-get-destination-guide-content');
Route::get('/authority-pages/{authorityPage}/accordions', [AuthorityPageController::class, 'getAuthorityPageAccordionData'])->name('authority-pages-get-accordions');

In your controller, ensure the methods look like this:

public function getAuthorityPageAccordionData(AuthorityPage $authorityPage, AuthorityPageAccordionDataTable $authorityPageAccordionDataTable)
{
    return $authorityPageAccordionDataTable->with([
        'authorityPage' => $authorityPage
    ])->render('pages.authority-pages.show');
}

public function getAuthorityPageGuideContentData(AuthorityPage $authorityPage, AuthorityPageGuideContentDataTable $authorityPageGuideContentDataTable)
{
    return $authorityPageGuideContentDataTable->with([
        'authorityPage' => $authorityPage
    ])->render('pages.authority-pages.show');
}

Now, in your show method, call the html() method from the DataTable instance. You can use the resulting variables in your view like this:

$accordionDt = $authorityPageAccordionDataTable->with([
    'authorityPage' => $authorityPage
])->html();

$authorityContentDt = $authorityPageGuideContentDataTable->with([
    'authorityPage' => $authorityPage
])->html();

return view('pages.authority-pages.show', [
    'authorityPage' => $authorityPage,
    'blogPosts' => $blogPosts,
    'tours' => $tours,
    'destinations' => $destinations,
    'keywordIntents' => $keywordIntents,
    'authorityContentDt' => $authorityContentDt,
    'accordionDt' => $accordionDt
]);

Now, within your view, you can use {{$authorityContentDt->table()}} and {{$authorityContentDt->scripts()}} to include the DataTable HTML and scripts.

Sign up to request clarification or add additional context in comments.

1 Comment

Yeah thank you for this. Isnt it kinda redundant? But this works as expected. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.