Comments (4)
I've played around with extracting table headers to a Blade component.
My first thought was to use a Livewire component, and to extend LivewireModelTable
in order to have access to current $sortField and $sortDir. However this was not a great idea as it then broke the sorting mechanism - it wasn't extending UsersTable
and thus the $fields array was empty when sort was triggered from the header cell component.
We just really needed a Blade component with a slot, to hide some of the ugly if statements shown in my initial comment.
This is what I have come up with at this time:
users-table.blade.php
<tr class="table-row">
@component('livewire-tables::th-cell', ['colNum' => 0, 'field' => $fields[0], 'css' => $css, 'sortField' => $sortField, 'sortDir' => $sortDir])
ID
@endcomponent
@component('livewire-tables::th-cell', ['colNum' => 1, 'field' => $fields[1], 'css' => $css, 'sortField' => $sortField, 'sortDir' => $sortDir])
Name
@endcomponent
@component('livewire-tables::th-cell', ['colNum' => 2, 'field' => $fields[2], 'css' => $css, 'sortField' => $sortField, 'sortDir' => $sortDir])
City
@endcomponent
</tr>
th-cell.blade.php
(component)
<th
@if (array_key_exists('sortable', $field) && $field['sortable'] && !is_null($sortField) && $sortField == $field['name'])
@if ($sortDir == 'asc')
class="{{ trim($css['th'] . ' ' . $css['sorted'] . ' ' . $css['sorted_asc']) }}"
@elseif ($sortDir == 'desc')
class="{{ trim($css['th'] . ' ' . $css['sorted'] . ' ' . $css['sorted_desc']) }}"
@else
class="{{ trim($css['th'] . ' ' . $css['sorted']) }}"
@endif
@else
@if ($css['th'])
class="{{ $css['th'] }}"
@endif
@endif
>
@if (array_key_exists('sortable', $field) && $field['sortable'])
<button wire:click="$emit('sortColumn', {{ $colNum }})">
{{ $slot }}
@if (!is_null($sortField) && $sortField == $field['name'])
@if ($sortDir == 'asc')
▲
@elseif ($sortDir == 'desc')
▼
@endif
@endif
</button>
@else
{{ $slot }}
@endif
</th>
Thoughts
Need to provide prepared $css
to the view (users-table)
Previously we could just pass $rowData
as $css
was only used during the view scaffolding. We now need to also pass a prepared $css
(i.e. merged config/livewire-tables CSS and component $css).
Sort button
If the column is sortable we provide a button that has emits the sort even when clicked. I think this is more semantically correct than only clicking the . However I'm thinking we now need to provide style options for the button.
Why don't we extract the entire header into a component, and loop over $fields?
While this would be visually preferable, my reasoning against this is to provide the user the ability to edit the $slot (where column name is currently entered), if need be. This way it can be wrapped in a or what have you. Or even to insert cells in between others if necessary.
from livewire-tables.
Update on the header view components.
th-cell.blade.php
<th
@if (array_key_exists('sortable', $field) && $field['sortable'])
@if (!is_null($sortField) && $sortField == $field['name'])
class="{{ trim($field['header_class'] . ' ' . $css['th'] . ' ' . $css['sorted']) }}"
@else
class="{{ trim($field['header_class'] . ' ' . $css['th']) }}"
@endif
style="cursor: pointer;"
wire:click="$emit('sortColumn', {{ $colNum }})"
@else
class="{{ trim($field['header_class'] . ' ' . $css['th']) }}"
@endif
>
{{ $slot }}
@if (array_key_exists('sortable', $field) && $field['sortable'] && !is_null($sortField) && $sortField == $field['name'])
@if ($sortDir == 'asc')
<span style="float: right">▲</span>
@elseif ($sortDir == 'desc')
<span style="float: right">▼</span>
@endif
@endif
</th>
users-table.blade.php
<tr class="table-row">
@component('livewire-tables::th-cell', ['colNum' => 0, 'field' => $fields[0], 'css' => $css, 'sortField' => $sortField, 'sortDir' => $sortDir])
ID
@endcomponent
@component('livewire-tables::th-cell', ['colNum' => 1, 'field' => $fields[1], 'css' => $css, 'sortField' => $sortField, 'sortDir' => $sortDir])
Name
@endcomponent
@component('livewire-tables::th-cell', ['colNum' => 2, 'field' => $fields[2], 'css' => $css, 'sortField' => $sortField, 'sortDir' => $sortDir])
City
@endcomponent
</tr>
UsersTable.php
public function render()
{
return view('livewire.tables.users-table', [
'rowData' => $this->query(),
'css' => $this->prepareCssForTemplate(),
]);
}
I tried to simplify it as much as possible by:
- Removing sorted asc / desc classes. I think a general "sorted" class should suffice, and icons can provide context rather than a class.
- Remove the button. This way the column header text and such can be directly controlled with classes rather than having to have extra styles if the column is sortable. Use
cursor: pointer;
style on sortable<th>
Any thoughts? Is this a good direction / addition to this package?
from livewire-tables.
Hey!
I like this! Abstracting it out is definitely a good call... although I feel it can go further, even if I am not sure how that works just yet!
i.e.
@component('livewire-tables::th-cell', ['colNum' => 2, 'field' => $fields[2], 'css' => $css, 'sortField' => $sortField, 'sortDir' => $sortDir])
City
@endcomponent
To something like...
@component('livewire-tables::th-cell', $fields)
City
@endcomponent
or...
@livewire('livewire-tables::th-cell', $field)
Or even better could the entire header row be livewire generated?
@livewire('th-row', $fields)
Doing as much of the logic as possible inside a php class would be nice too, almost like a view composer model (https://stitcher.io/blog/laravel-view-models).
I have been playing around with changing the @component
to a @livewire
and emitting a sort events however, so far no luck.
I believe there may be a bug within livewire that is preventing livewire logic from working insde a <th>
tag. I have opened an issue here if you are interested.
from livewire-tables.
Hey @booni3 ,
I went down the same route and tried to make a Livewire component that handled the table header row / cells. The issue I ran into was that the sort configuration is set in the generated PHP component i.e. UsersTable.php
that extends LivewireTable.php
. AFAIK unless the header Livewire component extends UsersTable.php
it does not have access to the set sort.
I've also been having conversation on the new Livewire forum on the direction of this package. See this discussion thread:
https://forum.laravel-livewire.com/t/on-building-the-ideal-livewire-tables-package/40
iAmKevinMcKee on that forum has a great addition to Livewire with customizable stubs. This kind of blew my mind. Maybe the Livewire Tables package should leverage this, ship with one or many table "stubs" that can also be generated by the end user to have completely configurable pre-made table views. Maybe we can even break up the stubs, i.e. include a default table header stub. I really need to wrap my head around how this would work in addition to the scaffolding that takes place.
This core idea here has really halted me on this project until I can figure out the best way to move forward, as I think it could affect how the entirety of the package works.
from livewire-tables.
Related Issues (15)
- To provide asc/desc sort icons, and staying style agnostic? HOT 1
- Feature Idea: Filters HOT 2
- Feature Idea: Search/Sort parameter via route parameter
- Class not found on composer install HOT 1
- Suggestions/recommendations
- Nested table support
- Can no longer be sortable if added additional listeners
- Cannot install by composer HOT 2
- How can I use custom pagination view
- multi search bars
- Issue/Conflict with Livewire\HasPagination trait HOT 1
- hasMany relationship, count/sum/max/min fields HOT 1
- Action links and buttons
- Always supplying primary key to table view
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from livewire-tables.