简体   繁体   中英

CRUD Backpack Laravel . Graph update, when Ajax Filter get changed

kindly avoid giving me negative reviews Thanks

in Laravel Backpack admin, when we click on Date Range filters , it's Filtering our table data, that is working fine, but I want Graph also get changed when we change ajax filters.

在此处输入图片说明

as per I know, ajax Date Range filter code in CrudConTroller :

 $this->crud->addFilter([
        'type'  => 'date_range',
        'name'  => 'created_at',
        'label' => 'Date range'
    ],
        false,
        function ($value) { // if the filter is active, apply these constraints
             $dates = json_decode($value);
             $this->crud->addClause('where', 'created_at', '>=', $dates->from);
             $this->crud->addClause('where', 'created_at', '<=', $dates->to . ' 23:59:59');
    });

and graph is coming in widget, blade templating file : list.blade.php .

 $widgets['before_content'][] = [
            'type' => 'div',
            'class' => 'row',
            'content' => [ // widgets
                [
                    'type' => 'chart',
                    'wrapperClass' => 'mt-4 col-md-12',
                    // 'class' => 'col-md-12',
                    'controller' => \App\Http\Controllers\Admin\Charts\UserChartController::class,
                    'content' => [
                        'header' => 'New Users', // optional
                         'body' => 'This chart should make it obvious', // optional
                    ]
                ],
            ],
        ]

There's many solution you can use php to generate the graph instead of the template. See the related section in the. documentation.

Then use the request parameter to filter the data for the graph. I ll try to post an example.

I needed this exact thing too. Quite hacky, but what I did was create a new filter, starting from the date_range filter, that instead of refreshing only the datatables, refreshes the entire page.

Here it is. If you place it in resources/views/vendor/backpack/crud/filters/date_range_refresh.blade.php you'll be able to use date_range_refresh instead of date_range as the filter type, and get the results you want:

{{-- Date Range Backpack CRUD filter --}}
<li filter-name="{{ $filter->name }}"
    filter-type="{{ $filter->type }}"
    filter-key="{{ $filter->key }}"
    class="nav-item dropdown {{ Request::get($filter->name)?'active':'' }}">
    <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{{ $filter->label }} <span class="caret"></span></a>
    <div class="dropdown-menu p-0">
        <div class="form-group backpack-filter mb-0">
            <div class="input-group date">
                <div class="input-group-prepend">
                  <span class="input-group-text"><i class="la la-calendar"></i></span>
                </div>
                <input class="form-control pull-right"
                        id="daterangepicker-{{ $filter->key }}"
                        type="text"
                        @if ($filter->currentValue)
                            @php
                                $dates = (array)json_decode($filter->currentValue);
                                $start_date = $dates['from'];
                                $end_date = $dates['to'];
                                $date_range = implode(' ~ ', $dates);
                                $date_range = str_replace('-', '/', $date_range);
                                $date_range = str_replace('~', '-', $date_range);

                            @endphp
                            placeholder="{{ $date_range }}"
                        @endif
                        >
                <div class="input-group-append daterangepicker-{{ $filter->key }}-clear-button">
                  <a class="input-group-text" href=""><i class="la la-times"></i></a>
                </div>
            </div>
        </div>
    </div>
</li>

{{-- ########################################### --}}
{{-- Extra CSS and JS for this particular filter --}}

{{-- FILTERS EXTRA CSS  --}}
{{-- push things in the after_styles section --}}

@push('crud_list_styles')
    <!-- include select2 css-->
    <link rel="stylesheet" type="text/css" href="{{ asset('packages/bootstrap-daterangepicker/daterangepicker.css') }}" />
    <style>
        .input-group.date {
            width: 320px;
            max-width: 100%; }
        .daterangepicker.dropdown-menu {
            z-index: 3001!important;
        }
    </style>
@endpush


{{-- FILTERS EXTRA JS --}}
{{-- push things in the after_scripts section --}}

@push('crud_list_scripts')
    <script type="text/javascript" src="{{ asset('packages/moment/min/moment.min.js') }}"></script>
    <script type="text/javascript" src="{{ asset('packages/bootstrap-daterangepicker/daterangepicker.js') }}"></script>
  <script>

        function applyDateRangeFilter{{$filter->key}}(start, end) {
            if (start && end) {
                var dates = {
                    'from': start.format('YYYY-MM-DD'),
                    'to': end.format('YYYY-MM-DD')
                };
                var value = JSON.stringify(dates);
            } else {
                //this change to empty string,because addOrUpdateUriParameter method just judgment string
                var value = '';
            }
            var parameter = '{{ $filter->name }}';

            // behaviour for ajax table
            var ajax_table = $('#crudTable').DataTable();
            var current_url = ajax_table.ajax.url();
            var new_url = addOrUpdateUriParameter(current_url, parameter, value);

            // replace the datatables ajax url with new_url and reload it
            new_url = normalizeAmpersand(new_url.toString());
            ajax_table.ajax.url(new_url).load();

            // add filter to URL
            crud.updateUrl(new_url);

            // mark this filter as active in the navbar-filters
            if (URI(new_url).hasQuery('{{ $filter->name }}', true)) {
                $('li[filter-key={{ $filter->key }}]').removeClass('active').addClass('active');
            }
            else
            {
                $('li[filter-key={{ $filter->key }}]').trigger('filter:clear');
            }

            // ---------------------------------------------------------------
            // THIS is where it's different from the regular date_range filter
            // ---------------------------------------------------------------
            // When the filter is changed, refresh the page,
            // so that the NPS widget up-top get reloaded.
            
            document.location.reload();
        }

        jQuery(document).ready(function($) {
            var dateRangeInput = $('#daterangepicker-{{ $filter->key }}').daterangepicker({
                timePicker: false,
                ranges: {
                    'Last Year': [moment().startOf('year').subtract(1, 'year'), moment().endOf('year').subtract(1, 'year')],
                    'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
                    'Last Week': [moment().subtract(1, 'week').startOf('week'), moment().subtract(1, 'week').endOf('week')],
                    'This Year': [moment().startOf('year'), moment().endOf('year')],
                    'This Month': [moment().startOf('month'), moment().endOf('month')],
                    'This Week': [moment().startOf('week'), moment().endOf('week')]
                },
                @if ($filter->currentValue)
                startDate: moment("{{ $start_date }}"),
                endDate: moment("{{ $end_date }}"),
                @endif
                alwaysShowCalendars: true,
                autoUpdateInput: true
            });

            dateRangeInput.on('apply.daterangepicker', function(ev, picker) {
                applyDateRangeFilter{{$filter->key}}(picker.startDate, picker.endDate);
            });

            $('li[filter-key={{ $filter->key }}]').on('hide.bs.dropdown', function () {
                if($('.daterangepicker').is(':visible'))
                return false;
            });

            $('li[filter-key={{ $filter->key }}]').on('filter:clear', function(e) {
                // console.log('daterangepicker filter cleared');
                //if triggered by remove filters click just remove active class,no need to send ajax
                $('li[filter-key={{ $filter->key }}]').removeClass('active');

                // ---------------------------------------------------------------
                // THIS is where it's different from the regular date_range filter
                // ---------------------------------------------------------------
                // When the filter is changed, refresh the page,
                // so that the NPS widget up-top get reloaded.
                document.location.reload();
            });

            // datepicker clear button
            $(".daterangepicker-{{ $filter->key }}-clear-button").click(function(e) {
                e.preventDefault();
                applyDateRangeFilter{{$filter->key}}(null, null);
            })
        });
  </script>
@endpush
{{-- End of Extra CSS and JS --}}
{{-- ########################################## --}}

It's not pretty... but... it's a solution 😀

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM