Replies: 7 comments
-
Geia sou @kolydart, I believe you can use the method I tried to replicate your scenario the best I could. My {"title":"\u0395\u03c5\u03c4\u03c5\u03c7\u03ce\u03c2","singer":"\u0398\u03ac\u03bd\u03bf\u03c2 \u03a0\u03b5\u03c4\u03c1\u03ad\u03bb\u03b7\u03c2"} My PowerGrid component looks like this. I am able to search for Greek singers. As well as searching for songs with Latin words. I can search other fields too, they were not affected. ImplementationDisclaimer: My implementation is very "hacky" and not elegant at all, but it is all I could think of this late at night 🙃 I use the What happens is:
The idea here was to match pieces of the JSON, you could probably change the Component codefinal class MusicTable extends PowerGridComponent
{
public function addColumns(): PowerGridColumns
{
return PowerGrid::columns()
->addColumn('id')
->addColumn('name')
->addColumn('song_title', function (User $user) {
return empty($user->songs) ? '' : html_entity_decode(json_decode($user->songs)->title);
})
->addColumn('song_singer', function (User $user) {
return empty($user->songs) ? '' : html_entity_decode(json_decode($user->songs)->singer);
});
}
public function columns(): array
{
return [
Column::make('Id', 'id'),
Column::make('Name', 'name')
->sortable()
->searchable(),
Column::make('Song Title', 'song_title', 'songs') // dataField is set to the db column songs
->searchable(),
Column::make('Singer', 'song_singer', 'songs') // dataField is set to the db column songs
->searchable(),
Column::action('Action'),
];
}
public function beforeSearch(string $field = null, string $search = null)
{
if ($field === 'songs') {
// Encode to Unicode and remove json enclosing.
$search = trim(ltrim(rtrim(json_encode([$search]), '"]'), '["'));
//Triple scape backlashes
$search = preg_replace('/\\\\/', '\\\\\\\\\\', $search);
return $search;
}
return $search;
}
//....
} I hope I have helped a bit! |
Beta Was this translation helpful? Give feedback.
-
That was a great idea, @dansysanalyst! Unfortunately I was not able to make it work in my installation. I tried all day yesterday to no avail. Thanks again. I appreciate it! |
Beta Was this translation helpful? Give feedback.
-
This is embarassing. It is impossible for me to run |
Beta Was this translation helpful? Give feedback.
-
@kolydart Could you share your code in a public repository? If not possible, just paste here the component code and your |
Beta Was this translation helpful? Give feedback.
-
There you are: |
Beta Was this translation helpful? Give feedback.
-
Hi @kolydart, Sorry, you have to use One unrelated question, though. Did you consider registering user songs in a table, instead of a JSON field? I, personally, find JSON fields unpractical when it comes to "daily usage". <?php
namespace App\Http\Livewire;
use App\User;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Builder;
use PowerComponents\LivewirePowerGrid\Rules\{Rule, RuleActions};
use PowerComponents\LivewirePowerGrid\Traits\{ActionButton, WithExport};
use PowerComponents\LivewirePowerGrid\Filters\Filter;
use PowerComponents\LivewirePowerGrid\{Button, Column, Exportable, Footer, Header, PowerGrid, PowerGridComponent, PowerGridColumns};
final class MusicTable extends PowerGridComponent
{
use ActionButton;
use WithExport;
/*
|--------------------------------------------------------------------------
| Features Setup
|--------------------------------------------------------------------------
| Setup Table's general features
|
*/
public function setUp(): array
{
$this->showCheckBox();
return [
Exportable::make('export')
->striped()
->type(Exportable::TYPE_XLS, Exportable::TYPE_CSV),
Header::make()->showSearchInput(),
Footer::make()
->showPerPage()
->showRecordCount(),
];
}
/*
|--------------------------------------------------------------------------
| Datasource
|--------------------------------------------------------------------------
| Provides data to your Table using a Model or Collection
|
*/
/**
* PowerGrid datasource.
*
* @return Builder<\App\User>
*/
public function datasource(): Builder
{
return User::query();
}
/*
|--------------------------------------------------------------------------
| Relationship Search
|--------------------------------------------------------------------------
| Configure here relationships to be used by the Search and Table Filters.
|
*/
/**
* Relationship search.
*
* @return array<string, array<int, string>>
*/
public function relationSearch(): array
{
return [];
}
/*
|--------------------------------------------------------------------------
| Add Column
|--------------------------------------------------------------------------
| Make Datasource fields available to be used as columns.
| You can pass a closure to transform/modify the data.
|
| ❗ IMPORTANT: When using closures, you must escape any value coming from
| the database using the `e()` Laravel Helper function.
|
*/
public function addColumns(): PowerGridColumns
{
return PowerGrid::columns()
->addColumn('id')
->addColumn('name')
/** Example of custom column using a closure **/
->addColumn('name_lower', fn(User $model) => strtolower(e($model->name)))
->addColumn('songs', fn($model) => json_encode($model->songs))
->addColumn('song_name', function (User $model) {
return empty($model->songs) ? '' : html_entity_decode(json_decode($model->songs)->name);
})
->addColumn('email')
->addColumn('locale')
->addColumn('created_at_formatted', fn(User $model) => Carbon::parse($model->created_at)->format('d/m/Y H:i:s'));
}
/*
|--------------------------------------------------------------------------
| Include Columns
|--------------------------------------------------------------------------
| Include the columns added columns, making them visible on the Table.
| Each column can be configured with properties, filters, actions...
|
*/
/**
* PowerGrid Columns.
*
* @return array<int, Column>
*/
public function columns(): array
{
return [
Column::make('Id', 'id'),
Column::make('Name', 'name')
->sortable()
->searchable(),
Column::make('Song Title', 'song_name', 'songs')
->sortable()
->searchable(),
Column::make('Email', 'email')
->sortable()
->searchable(),
Column::make('Locale', 'locale')
->sortable()
->searchable(),
Column::make('Created at', 'created_at_formatted', 'created_at')
->sortable(),
];
}
/**
* PowerGrid Filters.
*
* @return array<int, Filter>
*/
public function filters(): array
{
return [
Filter::inputText('name')->operators(['contains']),
Filter::inputText('songs', 'songs')->operators(['contains']),
Filter::inputText('email')->operators(['contains']),
Filter::inputText('locale')->operators(['contains']),
Filter::datetimepicker('created_at'),
];
}
public function beforeSearchSongs(string $search)
{
// Encode to Unicode and remove json enclosing.
$search = trim(ltrim(rtrim(json_encode([$search]), '"]'), '["'));
//Triple escape backlashes
$search = preg_replace('/\\\\/', '\\\\\\\\\\', $search);
return $search;
}
} |
Beta Was this translation helpful? Give feedback.
-
Ok, thanks. Maybe this should reflected in the docs also. Should I go on and change it?
Certainly. The case I am trying to deal with contains data coming from a 3rd party, thus it is not my DB design. It is an audit log containing eloquent events log. One of the fields is in array/json format. The source code I shared was for demonstration purpose only. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
On a field containg array data, I cannot filter non ascii characters.
Array data are by default converted to json and saved in the database as encoded utf.
Using this eloquent query
$model->properties = ["title" => "ελληνικά", "comments" => "Aliquam"]; $model->save();
saves data in the database as
{"title":"\u03b5\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac","comments":"Aliquam"}
So, it is not searchable by powergrid.
I am not interested in key=>value resolution. Searching as plain text for "ελληνικά" is fine.
Is there a way to tell powergrid to decode json data before filtering?
thanks
Beta Was this translation helpful? Give feedback.
All reactions