Open tabacitu opened 2 years ago
Hi @tabacitu
According to @pxpm's proposal in the issue https://github.com/Laravel-Backpack/CRUD/issues/2200. I modified the code of datatables_logic.blade.php
to add the widget update in the datatable draw callback.
This is a workaround, because it will not work for widgets used javascript load on before
or after
scripts (e.g. charts). Also, previous JS instances are not destroyed and cleaned from the browser memory.
To propose a viable and effective solution, we should, in my opinion, review the functioning of widgets so that they load their data through independent API routes. What do you think of this idea?
I put the modified code below to help developers like me who need to find a stopgap solution (for widgets without JS) while waiting for an evolution.
Change :
$('#crudTable').on('draw.dt', function () {
crud.functionsToRunOnDataTablesDrawEvent.forEach(function (functionName) {
crud.executeFunctionByName(functionName);
});
if ($('#crudTable').data('has-line-buttons-as-dropdown')) {
formatActionColumnAsDropdown();
}
}).dataTable();
With :
let firstUrl = window.location.href;
$('#crudTable').on('draw.dt', function () {
let currentUrl = window.location.href;
let widgets = $('div[data-element="widget"]');
if (firstUrl !== currentUrl) {
if (widgets.length > 0) {
widgets.fadeTo(200, 0.20);
$.get(currentUrl, function (data) {
let newWidgets = $(data).find('div[data-element="widget"]');
newWidgets.each(function () {
let widgetSection = $(this).attr('section');
let widgetContent = $(this).html();
$('div[section="' + widgetSection + '"]').html(widgetContent);
});
widgets.fadeTo(200, 1);
});
}
}
crud.functionsToRunOnDataTablesDrawEvent.forEach(function (functionName) {
crud.executeFunctionByName(functionName);
});
if ($('#crudTable').data('has-line-buttons-as-dropdown')) {
formatActionColumnAsDropdown();
}
}).dataTable();
Change :
@php
$widget['wrapper']['element'] = $widget['wrapper']['element'] ?? 'div';
$widget['wrapper']['class'] = $widget['wrapper']['class'] ?? "col-sm-6 col-md-4";
// each wrapper attribute can be a callback or a string
// for those that are callbacks, run the callbacks to get the final string to use
foreach($widget['wrapper'] as $attribute => $value) {
$widget['wrapper'][$attribute] = (!is_string($value) && is_callable($value) ? $value() : $value) ?? '';
}
@endphp
With :
@php
$widget['wrapper']['element'] = $widget['wrapper']['element'] ?? 'div';
$widget['wrapper']['class'] = $widget['wrapper']['class'] ?? "col-sm-6 col-md-4";
$widget['wrapper']['data-element'] = "widget";
// each wrapper attribute can be a callback or a string
// for those that are callbacks, run the callbacks to get the final string to use
foreach($widget['wrapper'] as $attribute => $value) {
$widget['wrapper'][$attribute] = (!is_string($value) && is_callable($value) ? $value() : $value) ?? '';
}
@endphp
cc @oddvalue
When widgets are used on CRUD pages, it's annoying that they don't update along with the DataTable, as you filter/search/etc. For example in https://github.com/Laravel-Backpack/CRUD/issues/2200
If you use Widgets there... as a user... you expect them to update. And it's not very easy to implement as a Dev. You have to refresh the page with all GET parameters in order to force the recalculation of the widgets.
Not sure what solution we should implement for this, but I do think we should think of one.