Open NoxzMSTR opened 2 days ago
Need the specific versions to be able to assist
Also an example of what you've got set in your table.
I'm not seeing this error in any of my demo tables. nor does it appear in any of the tests, so I'll need to understand how to reproduce it
livewire table vers v3.4.22
class QuoteLogsDatatable extends DataTableComponent {
public $showQuotations = 0;
public $hideQuotationTypeFilter = true;
public $status;
public $categories;
public $priceTemplate;
public $priceCategory;
public function mount()
{
$cat = Category::all();
foreach ($cat as $key => $value) {
$this->categories[$value->id] = $value->categoryTitle;
}
if (request('table-search') && request('type') == 'staffQuote') {
$this->showQuotations = 0;
}
$this->priceTemplate = OrderPriceTemplate::all();
foreach ($this->priceTemplate as $key => $value) {
$this->priceCategory[$value->zoneID] = ['category' => $value->category, 'color' => $value->zoneColor];
}
}
public function builder(): Builder
{
if ($this->showQuotations == 1) {
return Quotation::query();
} else {
$quoteLogs = QuotationLogs::query();
if ($this->status) {
return $quoteLogs->select([DB::raw('DISTINCT quotation_logs.id'), DB::raw("CAST(JSON_EXTRACT(data, '$.total') AS DECIMAL(10,2)) AS total")])->whereIn('status', explode(',', $this->status));
} else {
return $quoteLogs->select([DB::raw('DISTINCT quotation_logs.id'), DB::raw("CAST(JSON_EXTRACT(data, '$.total') AS DECIMAL(10,2)) AS total")])->whereNotIn('status', ['ArchiveQuote']);
}
}
}
public function configure(): void
{
if ($this->showQuotations == 1) {
$this->setPrimaryKey('id');
} else {
$this->setPrimaryKey('id');
}
// $this->setConfigurableAreas([
// 'toolbar-right-end' => 'livewire.admin.order.partials.quotation.list.custom-export-btn',
// ]);
$this->setDefaultSort('id', 'desc');
$this->setFilterLayout('slide-down');
}
public function columns(): array
{
$this->dispatch('load-quote-detail-script');
if ($this->showQuotations == 1) {
return $this->setQuotationColumns();
} else {
return $this->setQuotationLogsColumns();
}
}
private function setQuotationColumns(): array
{
return [
Column::make("Id", "id")
->sortable(),
Column::make("Collection PostCode", "collectionPostcode")->searchable()
->sortable()
->secondaryHeaderFilter('cpostcode')
->format(function ($value, $column, $row) {
// Use a Blade view for custom actions
return view('livewire.admin.order.partials.quotation.list.list-data-view', ['list' => 'quote', 'type' => 'collectionPostcode', 'value' => $value]);
}),
Column::make("Delivery PostCode", "deliveryPostcode")
->sortable()
->secondaryHeaderFilter('dpostcode')
->format(function ($value, $column, $row) {
// Use a Blade view for custom actions
return view('livewire.admin.order.partials.quotation.list.list-data-view', ['list' => 'quote', 'type' => 'deliveryPostcode', 'value' => $value]);
}),
Column::make("Items", "itemData")
->sortable()
->format(function ($value, $column, $row) {
// Use a Blade view for custom actions
return view('livewire.admin.order.partials.quotation.list.list-data-view', ['list' => 'quote', 'type' => 'items', 'value' => $value]);
})->collapseAlways(),
Column::make("Dates", "collectionDate")
->sortable()
->format(function ($value, $row, $column) {
// Use a Blade view for custom actions
return view('livewire.admin.order.partials.quotation.list.list-data-view', ['list' => 'quote', 'type' => 'dates', 'row' => $row]);
})->collapseAlways(),
Column::make("Status", "status")
->sortable()
->format(function ($value, $column, $row) {
// Use a Blade view for custom actions
return view('livewire.admin.order.partials.quotation.list.list-data-view', ['list' => 'quote', 'type' => 'status', 'value' => $value]);
})->collapseOnMobile(),
DateColumn::make("Created at", "created_at")
->sortable()->collapseOnMobile()->outputFormat('Y-m-d H:i:s'),
Column::make("Action", "id")->searchable()
->sortable()
->format(function ($value, $column, $row) {
// Use a Blade view for custom actions
return view('livewire.admin.order.partials.quotation.list.list-data-view', ['list' => 'quote', 'type' => 'action', 'id' => $value]);
}),
];
}
private function setQuotationLogsColumns(): array
{
return [
Column::make("Id", "id")
->sortable(fn(Builder $query, string $direction) => $query->orderBy('quotation_logs.id', $direction))->searchable(fn(Builder $query, $searchTerm) => $query->orWhere('quotation_logs.id', 'like', '%' . $searchTerm . '%')->orWhereIn('quotation_logs.id', explode(',', $searchTerm))),
Column::make("Collection PostCode", "data")->searchable()
->sortable()
->secondaryHeaderFilter('cpostcode')
->format(function ($value, $column, $row) {
// Use a Blade view for custom actions
return view('livewire.admin.order.partials.quotation.list.list-data-view', ['list' => 'logs', 'type' => 'collectionPostcode', 'value' => $value, 'ptCategory' => $this->priceCategory]);
}),
Column::make("Delivery PostCode", "data")
->sortable()
->secondaryHeaderFilter('dpostcode')
->format(function ($value, $column, $row) {
// Use a Blade view for custom actions
return view('livewire.admin.order.partials.quotation.list.list-data-view', ['list' => 'logs', 'type' => 'deliveryPostcode', 'value' => $value, 'ptCategory' => $this->priceCategory]);
}),
Column::make("Items", "data")
->sortable()
->format(function ($value, $column, $row) {
// Use a Blade view for custom actions
return view('livewire.admin.order.partials.quotation.list.list-data-view', ['list' => 'logs', 'type' => 'items', 'value' => $value, 'categories' => $this->categories]);
})->collapseOnMobile(),
Column::make("Dates", "data")
->sortable()
->format(function ($value, $column, $row) {
// Use a Blade view for custom actions
return view('livewire.admin.order.partials.quotation.list.list-data-view', ['list' => 'logs', 'type' => 'dates', 'value' => $value]);
})->collapseAlways(),
Column::make("Status", "status")
->sortable()
->format(function ($value, $column, $row) {
// Use a Blade view for custom actions
return view('livewire.admin.order.partials.quotation.list.list-data-view', ['list' => 'logs', 'type' => 'status', 'value' => $value]);
})->collapseOnMobile(),
Column::make("Total Amount")
->sortable(fn(Builder $query, string $direction) => $query->orderBy('total', $direction))
->label(
fn($row, Column $column) => view('livewire.admin.order.partials.quotation.list.list-data-view', ['list' => 'logs', 'type' => 'totalAmount', 'value' => $row['data']])
)->html()
->collapseOnMobile(),
Column::make("Submitted By", "user.name")->collapseOnMobile()
->sortable(),
DateColumn::make("Created at", "created_at")
->sortable()->collapseOnMobile()->outputFormat('Y-m-d H:i:s'),
Column::make("Action", "id")->searchable()
->sortable()
->format(function ($value, $column, $row) {
// Use a Blade view for custom actions
return view('livewire.admin.order.partials.quotation.list.list-data-view', ['list' => 'logs', 'type' => 'action', 'id' => $value]);
}),
];
}
public function filters(): array
{
if ($this->showQuotations == 1) {
return $this->setQuotationFilter();
} else {
return $this->setQuotationLogsFilter();
}
}
private function setQuotationFilter(): array
{
$quoteFilter = $this->setCustomFilterValue(1);
return [
MultiSelectFilter::make('Status', 'status')
->options(
Quotation::query()
->orderBy('status')
->get()
->keyBy('status')
->map(fn($logs) => $logs->status)
->toArray()
)
->filter(function (Builder $builder, array $values) {
$builder->whereIn('status', $values);
})
->setFirstOption('All Status'),
DateFilter::make('Date From')
->config([
'pillFormat' => 'F j, Y', // An aria-friendly date format
'min' => '1991-01-01', // The earliest acceptable date
'max' => Carbon::now()->addYear()->format('Y-m-d'), // The latest acceptable date
'placeholder' => 'Enter Date From', // A placeholder value
])
->filter(function (Builder $builder, $value) {
// Expects an array.
$builder->whereDate('created_at', '>=', $value);
}),
DateFilter::make('Date To')
->config([
'pillFormat' => 'F j, Y', // An aria-friendly date format
'min' => '1991-01-01', // The earliest acceptable date
'max' => Carbon::now()->addYear()->format('Y-m-d'), // The latest acceptable date
'placeholder' => 'Enter Date To', // A placeholder value
])
->filter(function (Builder $builder, $value) {
// Expects an array.
$builder->whereDate('created_at', '<=', $value);
}),
SelectFilter::make('Quote Logs')
->setFilterPillTitle('Quote Logs')
->setFilterPillValues([
'1' => 'Booking Form',
'0' => 'Staff Quotes',
])
->options([
'' => 'None',
'1' => 'Booking Form',
'0' => 'Staff Quotes',
])
->filter(function (Builder $builder, string $value) {
$previousStat = $this->showQuotations;
if ($value === '1') {
$this->showQuotations = 1;
} elseif ($value === '0') {
$this->showQuotations = 0;
}
$this->dispatch('refresh-quote-table', previousStat: $previousStat, showQuotations: $this->showQuotations);
}),
TextFilter::make('cpostcode')
->config([
'placeholder' => 'Search Collection Postcode...',
'maxlength' => '25',
])
->filter(function (Builder $builder, $value) {
$builder->whereRaw("REPLACE(UPPER(`collectionPostcode`), ' ', '') LIKE ?", ['%' . $value . '%']);
})->hiddenFromAll(),
TextFilter::make('dpostcode')
->config([
'placeholder' => 'Search Delivery Postcode...',
'maxlength' => '25',
])
->filter(function (Builder $builder, $value) {
$builder->whereRaw("REPLACE(UPPER(`deliveryPostcode`), ' ', '') LIKE ?", ['%' . $value . '%']);
})->hiddenFromAll()
];
}
private function setQuotationLogsFilter(): array
{
$quoteLogFilter = $this->setCustomFilterValue(0);
$ptc = [];
$ptc[''] = '';
foreach (range('A', 'Z') as $letter) {
$ptc[$letter] = $letter;
}
$filters = [
MultiSelectFilter::make('Status', 'status')
->setFirstOption('All Status')
->options(
$quoteLogFilter['status']
)
->filter(function (Builder $builder, array $values) {
$builder->whereIn('status', $values);
}),
DateFilter::make('Date From')
->config([
'pillFormat' => 'F j, Y', // An aria-friendly date format
'min' => '1991-01-01', // The earliest acceptable date
'max' => Carbon::now()->addYear()->format('Y-m-d'), // The latest acceptable date
'placeholder' => 'Enter Date From', // A placeholder value
])
->filter(function (Builder $builder, $value) {
// Expects an array.
$builder->whereDate('quotation_logs.created_at', '>=', $value);
}),
DateFilter::make('Date To')
->config([
'pillFormat' => 'F j, Y', // An aria-friendly date format
'min' => '1991-01-01', // The earliest acceptable date
'max' => Carbon::now()->addYear()->format('Y-m-d'), // The latest acceptable date
'placeholder' => 'Enter Date To', // A placeholder value
])
->filter(function (Builder $builder, $value) {
// Expects an array.
$builder->whereDate('quotation_logs.created_at', '<=', $value);
}),
SelectFilter::make('Zones')
->options($quoteLogFilter['collection_zone'])
->setFilterPillTitle('Zone')
->setFilterPillValues($quoteLogFilter['collection_zone'])
->filter(function (Builder $builder, string $value) {
$builder->where(function ($q) use ($value) {
$q->whereJsonContains('data->collection_zone', (int)$value)->orWhereJsonContains('data->delivery_zone', (int)$value);
});
}),
SelectFilter::make('Routes')
->options($quoteLogFilter['collection_route'])
->setFilterPillTitle('Route')
->setFilterPillValues($quoteLogFilter['collection_route'])
->filter(function (Builder $builder, string $value) {
$builder->where(function ($q) use ($value) {
$q->whereJsonContains('data->collection_route', $value)->orWhereJsonContains('data->delivery_route', $value);
});
}),
SelectFilter::make('Categories')
->options($quoteLogFilter['categories'])
->setFilterPillTitle('Categories')
->setFilterPillValues($quoteLogFilter['categories'])
->filter(function (Builder $builder, string $value) {
$builder->join(DB::raw('JSON_TABLE(data, "$.items[*]" COLUMNS (value JSON PATH "$")) AS item'), function ($join) {
$join->on('quotation_logs.id', '=', 'quotation_logs.id'); // Adjust the join condition if necessary
})->where(function ($q) use ($value) {
$q->where(DB::raw('JSON_EXTRACT(item.value, "$.item_category")'), '=', (int)$value);
});
}),
SelectFilter::make('Users')
->options($quoteLogFilter['user'])
->setFilterPillTitle('User')
->setFilterPillValues($quoteLogFilter['user'])
->filter(function (Builder $builder, string $value) {
$builder->where('userID', $value);
}),
SelectFilter::make('Collection Price Category')
->options($ptc)
->setFilterPillTitle('Collection Price Category')
->setFilterPillValues($ptc)
->filter(function (Builder $builder, string $value) use ($quoteLogFilter) {
if (isset($quoteLogFilter['price_categories'][$value])) {
$builder->where(function ($q) use ($value, $quoteLogFilter) {
foreach ($quoteLogFilter['price_categories'][$value] as $key => $value) {
if ($key == 0) {
$q->whereJsonContains('data->collection_zone', (int)$value);
} else {
$q->orWhereJsonContains('data->collection_zone', (int)$value);
}
}
});
}
}),
SelectFilter::make('Delivery Price Category')
->options($ptc)
->setFilterPillTitle('Delivery Price Category')
->setFilterPillValues($ptc)
->filter(function (Builder $builder, string $value) use ($quoteLogFilter) {
if (isset($quoteLogFilter['price_categories'][$value])) {
$builder->where(function ($q) use ($value, $quoteLogFilter) {
foreach ($quoteLogFilter['price_categories'][$value] as $key => $value) {
if ($key == 0) {
$q->whereJsonContains('data->delivery_zone', (int)$value);
} else {
$q->orWhereJsonContains('data->delivery_zone', (int)$value);
}
}
});
}
}),
TextFilter::make('cpostcode')
->config([
'placeholder' => 'Search Collection Postcode...',
'maxlength' => '25',
])
->filter(function (Builder $builder, $value) {
$value = str_replace(' ', '', strtoupper($value));
$builder->whereRaw("UPPER(REPLACE(JSON_EXTRACT(data, '$.collection_postcode'), ' ', '')) LIKE '%" . $value . "%'");
})->hiddenFromAll(),
TextFilter::make('dpostcode')
->config([
'placeholder' => 'Search Delivery Postcode...',
'maxlength' => '25',
])
->filter(function (Builder $builder, $value) {
$value = str_replace(' ', '', strtoupper($value));
$builder->whereRaw("UPPER(REPLACE(JSON_EXTRACT(data, '$.delivery_postcode'), ' ', '')) LIKE '%" . $value . "%'");
})->hiddenFromAll(),
];
if ((bool)$this->hideQuotationTypeFilter == false) {
$filters[] =
SelectFilter::make('Quote Logs')
->options([
'' => 'None',
'1' => 'Booking Form',
'0' => 'Staff Quotes',
])
->setFilterPillTitle('Quote Logs')
->setFilterPillValues([
'1' => 'Booking Form',
'0' => 'Staff Quotes',
])
->filter(function (Builder $builder, string $value) {
$previousStat = $this->showQuotations;
if ($value === '1') {
$this->showQuotations = 1;
} elseif ($value === '0') {
$this->showQuotations = 0;
}
$this->dispatch('refresh-quote-table', previousStat: $previousStat, showQuotations: $this->showQuotations);
});
}
return $filters;
}
private function setCustomFilterValue($showQuotations)
{
$exPostCode = [];
if ($showQuotations == 1) {
$exPostCode['collection_postcode'] = [];
$exPostCode['delivery_postcode'] = [];
return $exPostCode;
} else {
$collection_zone = Cache::store('file')->remember('collection_zone', 60 * 60, function () {
return QuotationLogs::select(['data->collection_zone as collection_zone'])->groupBy(['collection_zone'])->get()->toArray();
});
$collection_route = Cache::store('file')->remember('collection_route', 60 * 60, function () {
return QuotationLogs::select(['data->collection_route as collection_route'])->groupBy(['collection_route'])->get()->toArray();
});
$status = Cache::store('file')->remember('status', 60 * 60, function () {
return QuotationLogs::select(['status'])->groupBy(['status'])->get()->toArray();
});
$user = Cache::store('file')->remember('user', 60 * 60, function () {
return QuotationLogs::select(['userID'])->with(['user'])->groupBy(['userID'])->get()->toArray();
});
$categories = Cache::store('file')->remember('category', 60 * 60, function () {
return Category::select(['id', 'categoryTitle'])->whereNotIn('categoryTitle', ['Default'])->get()->toArray();
});
$exPostCode['collection_postcode'] = [];
$exPostCode['delivery_postcode'] = [];
$exPostCode['collection_zone'][''] = 'All Zones';
foreach ($collection_zone as $key => $value) {
$exPostCode['collection_zone'][cleanString(($value['collection_zone']))] = cleanString(($value['collection_zone']));
}
$exPostCode['collection_route'][''] = 'All Routes';
foreach ($collection_route as $key => $value) {
$exPostCode['collection_route'][cleanString(($value['collection_route']))] = cleanString(($value['collection_route']));
}
foreach ($status as $key => $value) {
$exPostCode['status'][cleanString(($value['status']))] = cleanString(($value['status']));
}
$exPostCode['user'][''] = 'All Users';
foreach ($user as $key => $value) {
if (isset($value['user'])) {
$exPostCode['user'][$value['user']['id']] = cleanString($value['user']['name']);
}
}
$exPostCode['categories'][''] = 'All Categories';
$exPostCode['categories'][0] = 'No Category Assigned';
foreach ($categories as $key => $value) {
if (isset($value['categoryTitle'])) {
$exPostCode['categories'][$value['id']] = cleanString($value['categoryTitle']);
}
}
if (isset($exPostCode['collection_zone'])) {
ksort($exPostCode['collection_zone']);
}
if (isset($exPostCode['collection_route'])) {
ksort($exPostCode['collection_route']);
}
$exPostCode['price_categories']['None'][] = '';
foreach ($this->priceTemplate as $key => $value) {
$exPostCode['price_categories'][$value->category][] = $value->zoneID;
}
return $exPostCode;
}
}
public function setCustomFilter($type, $data)
{
if ($type == 'collectionPostcode') {
foreach ($data as $key => $value) {
if ($key == 0) {
$this->builder->where('data', 'like', '%' . $value . '%');
} else {
$this->builder->orWhere('data', 'like', '%' . $value . '%');
}
}
}
if ($type == 'deliveryPostcode') {
foreach ($data as $key => $value) {
if ($key == 0) {
$this->builder->where('data', 'like', '%' . $value . '%');
} else {
$this->builder->orWhere('data', 'like', '%' . $value . '%');
}
}
}
}
public function bulkActions(): array
{
return [
'exportExcel' => 'Export',
];
}
public function exportExcel()
{
$logs = $this->getSelected();
$this->clearSelected();
if ($this->showQuotations == 1) {
return Excel::download(new QuotationsExport($logs), 'quotations.xlsx');
} else {
return Excel::download(new QuotationLogsExport($logs), 'quotation-logs.xlsx');
}
}
}
What happened?
htmlspecialchars(): Argument #1 ($string) must be of type string, array given {"view":{"view":"/var/www/vhosts/Laravel/vendor/rappasoft/laravel-livewire-tables/resources/views/components/tools/filter-pills.blade.php","data":[]}
How to reproduce the bug
Dont know why it is creating this error but it is saying this on production not on local
Package Version
No response
PHP Version
None
Laravel Version
No response
Alpine Version
No response
Theme
None
Notes
No response
Error Message
No response