MedicOneSystems / livewire-datatables

Advanced datatables using Laravel, Livewire, Tailwind CSS and Alpine JS
https://livewire-datatables.com/
MIT License
1.19k stars 258 forks source link

Programmatic sorting with external data #316

Open jbirch8865 opened 3 years ago

jbirch8865 commented 3 years ago

Issue: Undefined property: stdClass::$if(JSON_EXTRACT('{"data":[]}',REPLACE(JSON_UNQUOTE(JSON_SEARCH('{"data":[]}',"one",People.person_id,NULL,"$.data[*].employee_id")),"employee_id","proximity")) IS NOT NULL,"yes","no")

[livewire_component.php] private string $proximity = '{"data":[]}';

public function columns() { Column::raw('if(JSON_EXTRACT(\''.$this->proximity.'\',REPLACE(JSON_UNQUOTE(JSON_SEARCH(\''.$this->proximity.'\',"one",People.person_id,NULL,"$.data[*].employee_id")),"employee_id","proximity")) IS NOT NULL,"yes","no")')->label('proximity'), }

I have a page that has two columns. The left column is a livewire-datatable that lists all our employees. The right column is a different livewire component that lists all of our jobs for a given day.

When one of our dispatchers selects a job I need to calculate the distance between the job and the people in the datatable and display that distance in the livewire-datatable. So I used a json array that I populate separately with the unique_id of the person and the proximity. Then I pass that array into the raw sql of the Column. Right now I'm just shooting for yes, no if there is proximity found but I would later would actually display the proximity integer found in the array.

The first time the page loads is fine. But when I select a job from a different livewire component on the page and dispatch the event to the livewire-datatables component which modifies the $this->proximity value. It seems as though the datatable is expecting the exact same raw query back and kicks the above error because the query is different.

My issue is that I need to control the sorting of the table by proximity based on changes to the job selection. It seems as though the sorting functionality is only available off of MySql select columns so I thought a raw query using a php json_array would be appropriate for coorolating this data which doesn't live in the database to the records.

Am I missing a feature that would help me accomplish my sorting goals?

jbirch8865 commented 3 years ago

After digging into the base component and views I figured out that there were two issues I had. One is that my json array was too long to be a column name, so in the databable view that I published in my resources folder I was able to substr() the column name down to 256 characters which eliminated the original error.

                @forelse($this->results as $row)
                    <div class="table-row p-1 {{ $this->rowClasses($row, $loop) }}">
                        @foreach($this->columns as $column)
                            @if($column['hidden'])
                                @if($hideable === 'inline')
                                <div class="table-cell w-5 overflow-hidden align-top"></div>
                                @endif
                            @elseif($column['type'] === 'checkbox')
                                @include('datatables::checkbox', ['value' => $row->checkbox_attribute])
                            @elseif($column['type'] === 'label')
                                @include('datatables::label')
                            @else
                                <div class="table-cell px-6 py-2 whitespace-no-wrap @if($column['align'] === 'right') text-right @elseif($column['align'] === 'center') text-center @else text-left @endif {{ $this->cellClasses($row, $column) }}">
                                    {!! $row->{substr($column['name'],0,256)} !!} <--- I modified this line.   line:147
                                </div>
                            @endif
                        @endforeach
                    </div>
                @empty

However, then I did seem to have an issue that the public function columns() was not continuously ran on livewire lifecycle updates. So I broke the problem up into two livewire-datables. Then if I had work selected I render table A that adds the proximity column correctly. Then I deselect work and it loads table B which looks identical except that instead of a raw proximity column I render a labelColumn called proximity and just have it read "Please select work". This is working find.

Now if I could just figure out how to get it to sort properly I'd be in business.