yajra / laravel-datatables

jQuery DataTables API for Laravel
https://yajrabox.com/docs/laravel-datatables
MIT License
4.77k stars 858 forks source link

Laravel 8 components,laravel-breeze and yajra datatables #2693

Closed volnistii11 closed 2 years ago

volnistii11 commented 3 years ago

I made a table using yajra datatables, everything works fine (buttons, table title, table data, editing, etc.)

 <!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Format Documents</title>

    {{--    bootstrap   --}}
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet"
          integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.bundle.min.js"
            integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj"
            crossorigin="anonymous"></script>
    {{-- jquery --}}
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"
            integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>

    {{--    datatables --}}
    <link rel="stylesheet" href="https://cdn.datatables.net/1.11.0/css/dataTables.bootstrap5.min.css">
    <script src="https://cdn.datatables.net/1.11.0/js/jquery.dataTables.min.js"></script>
    <script src="https://cdn.datatables.net/1.11.0/js/dataTables.bootstrap5.min.js"></script>

    {{--    buttons--}}
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/2.0.0/css/buttons.bootstrap5.css"/>
    <script type="text/javascript" src="https://cdn.datatables.net/buttons/2.0.0/js/dataTables.buttons.js"></script>
    <script src="https://cdn.datatables.net/buttons/2.0.0/js/buttons.bootstrap5.min.js"></script>
    <script src="/vendor/datatables/buttons.server-side.js"></script>

    {{--    select--}}
    <link rel="stylesheet" href="https://cdn.datatables.net/select/1.3.3/css/select.bootstrap.min.css">
    <script src="https://cdn.datatables.net/select/1.3.3/js/dataTables.select.min.js"></script>

    <script src="{{asset('plugins/editor/js/dataTables.editor.js')}}"></script>
    <script src="{{asset('plugins/editor/js/editor.bootstrap5.min.js')}}"></script>

</head>
<body>
<section style="padding-top: 60px;">
    <div class="container">
        {!! $dataTable->table(['id' => 'format-table'], true) !!}
    </div>
</section>
<script>
    $(function () {

        var editor = new $.fn.dataTable.Editor({
            ajax: "/service/formats",
            table: "#format-table",
            display: "bootstrap",
            fields: [
                {label: "Formats name:", name: "name"},
            ]
        });

        $('#format-table').on('click', 'tbody td:not(:first-child)', function (e) {
            editor.inline(this);
        });

        {{$dataTable->generateScripts()}}
    })

</script>

</body>

Now I am trying to implement this using Laravel 8 components, but I do not understand how to do it correctly. I gave an example of one of my attempts below, but there I only display the column headings (there are no buttons, there is no data in the table).My attempt to go to Laravel 8 components only shows Laravel Breeze items and table column titles.

 <x-app-layout>
<x-slot name="header">

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet"
          integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdn.datatables.net/1.11.0/css/dataTables.bootstrap5.min.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/2.0.0/css/buttons.bootstrap5.css"/>
    <link rel="stylesheet" href="https://cdn.datatables.net/select/1.3.3/css/select.bootstrap.min.css">

    <h2 class="font-semibold text-xl text-gray-800 leading-tight">
        {{ __('Dashboard') }}
    </h2>
</x-slot>

<x-content-body>
    <section style="padding-top: 60px;">
        <div class="container">
            {!! $dataTable->table(['id' => 'format-table'], true) !!}
        </div>
    </section>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.bundle.min.js"
            integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj"
            crossorigin="anonymous"></script>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"
            integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
    <script src="https://cdn.datatables.net/1.11.0/js/jquery.dataTables.min.js"></script>
    <script src="https://cdn.datatables.net/1.11.0/js/dataTables.bootstrap5.min.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/buttons/2.0.0/js/dataTables.buttons.js"></script>
    <script src="https://cdn.datatables.net/buttons/2.0.0/js/buttons.bootstrap5.min.js"></script>
    <script src="/vendor/datatables/buttons.server-side.js"></script>
    <script src="https://cdn.datatables.net/select/1.3.3/js/dataTables.select.min.js"></script>
    <script src="{{asset('plugins/editor/js/dataTables.editor.js')}}"></script>
    <script src="{{asset('plugins/editor/js/editor.bootstrap5.min.js')}}"></script>

    <script>
        $(function () {

            var editor = new $.fn.dataTable.Editor({
                ajax: "/service/formats",
                table: "#format-table",
                display: "bootstrap",
                fields: [
                    {label: "Наименование формата:", name: "name"},
                ]
            });

            $('#format-table').on('click', 'tbody td:not(:first-child)', function (e) {
                editor.inline(this);
            });

            {{$dataTable->generateScripts()}}
        })

    </script>

</x-content-body>
</x-app-layout>

my DataTable Controller

<?php

namespace App\DataTables;

use App\Models\Format;
use Yajra\DataTables\Html\Button;
use Yajra\DataTables\Html\Column;
use Yajra\DataTables\Html\Editor\Editor;
use Yajra\DataTables\Html\Editor\Fields;
use Yajra\DataTables\Services\DataTable;

class FormatDataTable extends DataTable
{
    /**
     * Build DataTable class.
     *
     * @param mixed $query Results from query() method.
     * @return \Yajra\DataTables\DataTableAbstract
     */
    public function dataTable($query)
    {
        return datatables()
            ->eloquent($query)
            ->setRowId('id');
    }

    /**
     * Get query source of dataTable.
     *
     * @param \App\Models\Format $model
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function query(Format $model)
    {
        return $model->newQuery();
    }
    /*
     * HERERERE
     */
    /**
     * Optional method if you want to use html builder.
     *
     * @return \Yajra\DataTables\Html\Builder
     */
    public function html()
    {
        return $this->builder()
            ->setTableId('format-table')
            ->columns($this->getColumns())
            ->minifiedAjax()
            ->select()
            ->initComplete("function () {
                                    this.api().columns().every(function () {
                                        var column = this;
                                        var input = document.createElement(\"input\");
                                        $(input).appendTo($(column.footer()).empty())
                                        .on('change', function () {
                                                column.search($(this).val(), false, false, true).draw();
                                            });
                                    });
                           }")
            ->serverSide()
            ->dom('B<"top"i>rt<"bottom"flp><"clear">')
            ->orderBy(1, 'asc')
            ->buttons(
                Button::make('create')->editor('editor'),
                Button::make('edit')->editor('editor'),
                Button::make('remove')->editor('editor'),
                Button::make('export'),
                Button::make('print'),
                Button::make('reset'),
                Button::make('reload')
            )
            ->editor(
                Editor::make()
                    ->fields([
                        Fields\Text::make('name')
                    ])
            );
    }

    /**
     * Get columns.
     *
     * @return array
     */
    protected function getColumns()
    {
        return [
            Column::checkbox(),
            Column::make('id'),
            Column::make('name'),
        ];
    }

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

I also attach two pictures, the first one shows the working state. The second is how it looks when I try to implement it using components. 1 image 2 image

volnistii11 commented 3 years ago

There was a thought that maybe i need to add csrf_token somewhere?

volnistii11 commented 3 years ago

I thought it was because of this that the breeze was blocking

volnistii11 commented 3 years ago

Hmm, I decided to look into the console, and saw warnings and an error, which are not present in the version without laravel-breeze. image

yajra commented 3 years ago

When you say component, is it livewire, blade, or Vue? I currently use blade components too and it works for me. Also tried Livewire and Vue but it's a bit buggy. For livewire, you need to use wire:ignore if I recall correctly.

Anyways, you should fix the console error first cause it seems like just a js issue since you already have a working state.

Here is an example blade component that uses AlpineJs too, you might get some idea. I removed some markup but I think you get the idea here. This is a very custom dataTable as global search is being handled via AlpineJS.

@props(['dataTable'])

<div {{ $attributes->merge(['class' => 'card']) }} x-data="{}">
    <div class="card-header">
        <div class="row justify-content-between align-items-center flex-grow-1 mt-2">
            <div class="col-sm-4 col-md-3 mb-3 mb-sm-0">
                <form @submit.prevent>
                    <div class="input-group input-group-merge input-group-flush">
                        <div class="input-group-prepend">
                            <div class="input-group-text">
                                <i class="tio-search"></i>
                            </div>
                        </div>
                        <input id="{{$dataTable->getTableAttribute('id')}}_search"
                               type="search"
                               class="form-control"
                               @keydown.debounce.750ms="LaravelDataTables['{{$dataTable->getTableAttribute('id')}}'].search($refs.search.value).draw();"
                               x-ref="search"
                               placeholder="Search..."
                               aria-label="Search...">
                    </div>
                </form>
            </div>
        </div>
    </div>

    <div class="card-body" id="{{$dataTable->getTableAttribute('id')}}_infoContainer"></div>

    <div class="table-responsive datatable-custom datatable-custom-centered">
        {{ $table ?? $dataTable->table() }}
    </div>

    <x-data-table-footer :id="$dataTable->getTableAttribute('id')" />
</div>

@push('scripts')
    {{ $scripts ?? $dataTable->scripts() }}
@endpush

Usage

<x-data-table :dataTable="$dataTable">
// some stuffs
</x-data-table>

Output

image

volnistii11 commented 3 years ago

Yes, blade components. How do you connect all the necessary js scripts? I was given the idea that it might have something to do with the namespace in js, but I don't understand anything in js. Maybe you have a mini project (on github for example) so that I can see what I'm doing wrong ... Because I have been suffering with this for almost a month, and so I did not find an answer (there are no examples on the Internet at all) ...

volnistii11 commented 3 years ago

Here's another one of my attempts ... https://github.com/volnistii11/archive/blob/master/resources/views/service/format/index.blade.php

volnistii11 commented 3 years ago

That is, apparently, I do not understand how to properly connect the required js ...

yajra commented 2 years ago

That is, apparently, I do not understand how to properly connect the required js ...

Try using https://datatables.net/download/ and build your requirements there.