Laravel-datatables: So rendern Sie 2 Daten auf einer Seite auf verschiedenen Registerkarten

Erstellt am 12. Juni 2017  ·  9Kommentare  ·  Quelle: yajra/laravel-datatables

Zusammenfassung des Problems oder der Funktionsanforderung


Hallo, guten Tag dir.
Ich möchte etwas fragen und brauche Ihre Hilfe. Ich habe eine Seite mit 2 Registerkarten erstellt. Die Registerkarte #one zeigt Daten pro Tag an. Die Registerkarte #two zeigt Daten pro Stunde an. Ich versuche, dieselbe Tabelle in diesen beiden Registerkarten zu erstellen, aber es ist nur eine wird in tab #one angezeigt, in tab # zwei zeigt nur den Namen der Spalte an, warum passiert das?

Code-Snippet des Problems

Ich habe vermutet, dass das Falsche in meinem Controller ist. Dies ist der Code:

public function index(InsightDataTable $dataTable)
    {
        return $dataTable->render('admin.report.insight.index');
    }

Also möchte ich fragen, wie mehrere Daten in Controller gerendert werden können.
Dankeschön.
Oh und das ist der Code in meiner index.blade.php

@section('content')
    @include('admin.notification')
    <div class="row">
            <div class="col-xs-12">

                <div class="nav-tabs-custom">
                    <ul class="nav nav-tabs">
                        <li class="hari"><a href="#hari" data-toggle="tab">Hari</a></li>
                        <li class="jam"><a href="#jam" data-toggle="tab">Jam</a></li>
                    </ul>
                    <div class="tab-content">

                        <div class="hari tab-pane" id="hari">
                        <div class="row">
                <div class="btn-group pull-right" style="margin: 0 15px 15px 0;">
                    <a href="" class="btn btn-primary btn-header" id="export_file">{{ trans('label.download_excel') }}</a> 
                </div>
            </div>
                <div class="box">
                <div class="box-body">
                <table border="0" cellspacing="5" cellpadding="5">
                        <tbody>
                            <tr>
                                <td>Period:&nbsp;</td>
                                <td>
                                    <input type="text" class="form-control date-range" id="" style="width: 180px;text-align: center;">
                                </td>
                            </tr>
                        </tbody>
                    </table>
                    <br/>
                    {!! $dataTable->table(['class' => 'datatable table table-striped', 'cellspacing'=>"0", 'width'=>"100%"]) !!}
                </div>
            </div>
                        </div>

                      <div class="jam tab-pane" id="jam">
                            <div class="row">
                <div class="btn-group pull-right" style="margin: 0 15px 15px 0;">
                    <a href="" class="btn btn-primary btn-header" id="export_file">{{ trans('label.download_excel') }}</a> 
                </div>
            </div>
                <div class="box">
                <div class="box-body">
                <table border="0" cellspacing="5" cellpadding="5">
                        <tbody>
                            <tr>
                                <td>Period:&nbsp;</td>
                                <td>
                                    <input type="text" class="form-control date-range" id="" style="width: 180px;text-align: center;">
                                </td>
                            </tr>
                        </tbody>
                    </table>
                    <br/>
                    {!! $dataTable->table(['class' => 'datatable table table-striped', 'cellspacing'=>"0", 'width'=>"100%"]) !!}
                </div>
            </div>
                      </div>

                    </div>
                  </div>
                </div>

            </div>
<strong i="16">@endsection</strong>

@section('custom_js')
    <script> 
        dateSelection = false;
        $('.date-range').daterangepicker();
        $('.date-range').on('apply.daterangepicker', function(ev, picker) {
            $('#dataTableBuilder').on('preXhr.dt', function ( e, settings, data ) {
                data.firstDate = picker.startDate.format('YYYY-MM-DD');
                data.lastDate = picker.endDate.format('YYYY-MM-DD');
                merge_date = data.firstDate+'_'+data.lastDate;
            });       
            var table = $('#dataTableBuilder').DataTable();
           table.ajax.reload();
           dateSelection =true;                 
        });

        $("#export_file").click(function() {
            if(dateSelection == false) {
                window.location.href = "{{ url('admin/report/insight/export/all') }}";
            } else {
                window.location.href = "{{ url('admin/report/insight/export') }}/"+merge_date;
            }
            return false;
        });

    </script>
    {!! $dataTable->scripts() !!}
<strong i="17">@endsection</strong>

Systemdetails

Bitte geben Sie diese Angaben zu Ihrem System an! Wenn sie weggelassen werden, wird das Ticket gegenüber den Anforderungen / Tickets anderer Benutzer priorisiert.
  • Betriebssystem: Ubuntu 16.04
  • PHP-Version: 7
  • Laravel Version: 5.2
  • Laravel-Datatables Version: 6.0
question

Hilfreichster Kommentar

"Einzeiler:

    public function show(PrimaryDataTable $primaryDataTable, SecondDataTable $secondDataTable)
    {
        /**  Depend request we need to match proper class */
        return ${request()->get('table', 'primary') . 'DataTable'}->render(
            'resource.show',
            compact('primaryDataTable', 'secondDataTable')
        );
    }

Seien Sie auch vorsichtig mit minimiertem Ajax. Fügen Sie nach dem Aufrufen dieser Methode Ajax-Daten hinzu.

Alle 9 Kommentare

Ich mag es jedoch nicht sehr, einen service-basierten Ansatz für eine Tabelle zu verwenden, der sich von einem anderen unterscheidet. Aus Gründen der Konsistenz möchte ich wissen, wie man sich noch weiter trennt. Ist es möglich, eine solche Struktur zu erstellen?:

UsersDatatableController
kümmert sich ausschließlich um die Datentabelle für Benutzer
Die Ansicht dient nur zum Rendern der Daten und zur Verarbeitung von Ajax-Anforderungen

PostsDatatableController
kümmert sich ausschließlich um die Datentabelle für Beiträge (allgemein oder benutzerbezogen)
Die Ansicht dient nur zum Rendern der Daten und zur Verarbeitung von Ajax-Anforderungen

UsersController
Verwenden Sie den UsersDatatableController und den PostsDatatableController zum Rendern und platzieren Sie sie in derselben Ansicht, in Registerkarten, Over-Under, was auch immer. Ajax-Aufrufe der Datentabellen würden von diesem Controller nicht verarbeitet. Wenn Sie sich diesen Controller vorstellen, kann er auch für ein Bearbeitungsformular anstelle einer normalen Seite mit einer Datentabelle verwendet werden.

Da mein Anwendungsfall darin besteht, serverseitige Daten datierbar zu machen, möchte ich mit kombinieren
https://github.com/imanghafoori1/laravel-widgetize
und das
https://stackoverflow.com/questions/41857905/using-laravel-controllers-as-components-to-build-a-view

@yajra
Lass mich deine Gedanken kennen

@isometriq atm, ich denke, Sie können standardmäßig nicht zwei DataTable-Klassen innerhalb derselben Route für die Ajax-Behandlung verwenden. Möglicherweise können Sie jedoch zusätzliche Parameter hinzufügen, mit denen Sie ermitteln können, welche Ajax-Antwort angefordert wird.

public function index(UsersDatatable $udt, PostsDatatable $pdt) {
  if (request()->get('table') == 'posts') {
    return $udt->render('my.view', compact('udt', 'pdt'));
  }

  return $pdt->render('my.view', compact('udt', 'pdt'));
}

Sie können dann den Builder für beide DT in Ihrer Ansicht verwenden.

{!! $udt->html()->table() !!} // users table
{!! $pdt->html()->table() !!} // posts table

{!! $udt->scripts() !!} // users table scripts
{!! $pdt->scripts() !!} // posts table scripts

Nur eine Idee, die Sie ausprobieren können. Vielen Dank!

Danke @yajra, ich werde ein paar Dinge ausprobieren

Danke für diese Frage. Ich habe das gerade zum Laufen gebracht , wie

{!! $udt->html()->table(['id' => 'udt']) !!} // users table
{!! $pdt->html()->table(['id' => 'pdt']) !!} // posts table

{!! $udt->html()->scripts() !!} // users table scripts
{!! $pdt->html()->scripts() !!} // posts table scripts

Sie müssen jeder Tabelle ein eindeutiges ID-Attribut übergeben, damit das js ordnungsgemäß funktioniert. Hoffe das hilft jemandem!

Und in Ihrer DataTable-Klasse haben Sie den zusätzlichen Parameter in der html () -Methode übergeben:

public function html() {

    return $this->builder()
        ->ajax(['data' => 'function(d) { d.table = "posts"; }'])
        ->parameters($this->getBuilderParameters());
}

@yajra , wäre schön, wenn die neueste Dokumentation unter https://datatables.yajrabox.com/services/two-datatables stattdessen dieses Beispiel enthält.

@benlwong danke für das Feedback. Der Demo-Quellcode ist hier verfügbar. Wenn Sie können, zögern Sie bitte nicht, eine PR einzureichen. Vielen Dank!

Hallo zusammen, ich habe die Lösung in diesem Beitrag verfolgt und meine beiden Datentabellen gleichzeitig ausgeführt!
Aber .. ich möchte nicht, dass beide gleichzeitig geladen werden, wenn die allgemeine Seite geladen wird.

Ich möchte, dass die 2. Datentabelle geladen wird, wenn ich auf eine bestimmte Registerkarte / Schaltfläche klicke.
Ich habe das auf der Seite gesehen: https://datatables.yajrabox.com/services/two-datatables

function postsDataTables() {
    if (!$.fn.dataTable.isDataTable('#postsTable')) {
        $('#postsTable').DataTable({
            dom: 'Bfrtip',
            processing: true,
            serverSide: true,
            order: [[0, 'desc']],
            buttons: [
                'csv', 'excel', 'pdf', 'print', 'reset', 'reload'
            ],
            ajax: '/services/two-datatables/posts',
            columns: [
                {data: 'id', name: 'posts.id'},
                {data: 'title', name: 'posts.title'},
                {data: 'created_by', name: 'users.name', width: '110px'},
                {data: 'created_at', name: 'posts.created_at', width: '120px'},
                {data: 'updated_at', name: 'posts.updated_at', width: '120px'},
            ],
            order: [[0, 'desc']]
        });
    }
}

Das besteht im Wesentlichen darin, eine if-Anweisung hinzuzufügen, die das JS von datatable umschließt, aber ich möchte eine Lösung durch die Implementierung von DataTable Service, wie Sie es in diesem Beitrag getan haben. Etwas wie das:

function postsDataTables() {
    if (!$.fn.dataTable.isDataTable('#postsTable')) {

        {!! $secondDataTable->html()->scripts() !!}

    }
}

Dies ist jedoch nicht möglich, da die Funktion "scripts ()" die Tags druckt