1111 * [ Set up] ( #set-up )
1212 * [ Usage] ( #usage )
1313 * [ Nuxt integration] ( #nuxt-integration )
14+ * [ Laravel integration] ( #laravel-integration )
1415* [ CONFIGURATION] ( #configuration )
1516 * [ Columns] ( #columns )
1617 * [ Custom Cell Component] ( #custom-cell-component )
1920 * [ Selectable rows] ( #selectable-rows )
2021 * [ Text] ( #text )
2122 * [ Adding Language] ( #adding-language )
23+ * [ Async data] ( #async-data )
2224 * [ Layout] ( #layout )
2325 * [ Custom Components] ( #custom-components )
2426 * [ Footer] ( #footer )
@@ -48,6 +50,7 @@ that automatically generates beautiful forms from declarative rules.
4850- Custom Footer to display data summary
4951- Support for Vue3 and Vue2
5052- Nuxt integration
53+ - Laravel integration
5154
5255## DEMO
5356
@@ -128,9 +131,17 @@ export default defineNuxtPlugin(nuxtApp => {
128131
129132Nuxt automatically loads the files in the ` plugins/ ` directory by default.
130133
134+ ### Laravel integration
135+
136+ This plugin integrates with Laravel's pagination API, so it fetches data
137+ asynchronously from the provided URL. Follow the instrunctions in the
138+ [ async data section] ( #async-data ) for a detailed setup.
139+
131140## CONFIGURATION
132141
133- Only ` data ` e ` columns ` are required. Other props are optional.
142+ Only ` columns ` are required. Other props are optional.
143+
144+ If ` data ` is not passed, then ` fetchUrl ` and ` fetchCallback ` * must* be passed.
134145
135146` vKey ` is not required but is ** highly** recommend to set it if you plan to
136147add or delete rows in the table!
@@ -144,6 +155,8 @@ add or delete rows in the table!
144155| lang | ` String ` | ` en ` | The default language |
145156| perPageSizes | ` Array ` | [ 10, 25, 50, 100, '* '] | The options for the number of rows being displayed per page. The string '* ' shows all. |
146157| defaultPerPage | ` Number ` | 10 | The default number of entries. If unset, then it will be the first value of ` perPageSizes ` |
158+ | fetchUrl | ` String ` | - | The URL to fetch data from if ` data ` is null |
159+ | fetchCallback | ` String ` | - | Async function which takes an URL and returns ` data ` matching Laravel's pagination API |
147160| isLoading | ` Bool ` | ` false ` | Whether table data is loading. Table rows are shown only if this value is set to ` false ` |
148161| loadingComponent | ` String ` , ` Object ` | - | VueJS component to be shown if ` isLoading ` is set to ` true ` |
149162| showPerPage | ` Bool ` | ` true ` | Whether to show the ` PerPage ` component |
@@ -664,6 +677,163 @@ reflect the changes globally. For example:
664677languageServiceProvider .setLangText (" en" , " downloadText" , " download as:" )
665678```
666679
680+
681+ ### Async data
682+
683+ If you do not want to fetch all data at once and pass it to ` VueDataTable ` via
684+ the ` data ` prop, you can do so by defining:
685+
686+ - ` fetchUrl ` : initial endpoint for the first ajax request to fetch data
687+ - ` fetchCallback ` : async function which takes an URL and returns a response
688+ following Laravel's pagination API.
689+
690+ Here is a sample ` fetchCallback ` :
691+
692+ ``` vue
693+ <template>
694+ <h1>Users</h1>
695+ <vue-data-table v-bind="vdtProps" />
696+ </template>
697+ <script setup>
698+ const vdtProps = {
699+ columns: [
700+ { key: 'name' },
701+ { key: "email", title: "Email address" },
702+ ],
703+ fetchUrl: "http://app.test/api/users",
704+ fetchCallback: async (url) => fetch(url).then(response => response.json())
705+ }
706+ </script>
707+ ```
708+
709+ The example above uses the browser's built-in ` fetch ` , but you can also use
710+ ` axios ` or Nuxt's ` $fetch ` under the hood. Just make sure the response returned
711+ by the callback matches the following.
712+
713+ The response from the ` fetchCallback ` should look like this:
714+
715+ ``` jsonc
716+ {
717+ " data" : [
718+ {
" id" : 1 ,
" name" : " Miss Juliet Heidenreich" ,
" email" : " [email protected] " },
719+ {
" id" : 2 ,
" name" : " Heloise Boehm" ,
" email" : " [email protected] " },
720+ {
" id" : 3 ,
" name" : " Antwon Collins" ,
" email" : " [email protected] },721+ /* ... */
722+ ],
723+ " current_page" : 1,
724+ " first_page_url" : " http: // app.test/api/users?page=1",
725+ " from" : 1 ,
726+ " last_page" : 23 ,
727+ " last_page_url" : " http://app.test/api/users?page=23" ,
728+ " links" : [
729+ { " url" : null , " label" : " « Previous" , " active" : false },
730+ { " url" : " http://app.test/api/users?page=1" , " label" : " 1" , " active" : true },
731+ { " url" : " http://app.test/api/users?page=2" , " label" : " 2" , " active" : false },
732+ { " url" : " http://app.test/api/users?page=3" , " label" : " 3" , " active" : false },
733+ /* ... */
734+ { " url" : " http://app.test/api/users?page=23" , " label" : " 23" , " active" : false },
735+ { " url" : " http://app.test/api/users?page=2" , " label" : " Next »" , " active" : false }
736+ ],
737+ " next_page_url" : " http://app.test/api/users?page=2" ,
738+ " path" : " http://app.test/api/users" ,
739+ " per_page" : 15 ,
740+ " prev_page_url" : null ,
741+ " to" : 15 ,
742+ " total" : 340
743+ }
744+ ` ` `
745+
746+ Here is how you do so in Laravel:
747+
748+ ` ` ` php
749+ < ? php
750+
751+ use App\Models\User;
752+ use Illuminate\Support\Facades\Route;
753+
754+ Route: : get (' users' , function () {
755+ return User:: paginate ();
756+ });
757+ ` ` `
758+
759+ This will also work with collections: ` new UserCollection (User:: paginate ())` .
760+
761+ In order to be able to **sort** and **search** using endpoints compatible with
762+ Laravel's API, this plugin provides support for Spatie's Laravel Query Builder
763+ package, which allows you to easily generate API endpoints with sorting and
764+ searching functionalities with well-defined standard.
765+
766+ ` ` ` php
767+ < ? php
768+
769+ use App\Models\User;
770+ use Illuminate\Support\Facades\Route;
771+ use Spatie\QueryBuilder\QueryBuilder;
772+
773+ Route: : get (' users' , function () {
774+ return QueryBuilder:: for (User:: class )
775+ - > allowedSorts ([' name' , ' email' ])
776+ - > allowedFilters ([' name' , ' email' ])
777+ - > paginate ();
778+ });
779+ ` ` `
780+
781+ The endpoints look like this:
782+
783+ - ` http: // app.test/api/users?page=1&filter[name]=foo`
784+ - ` http://app.test/api/users?page31&sort=job,-email`
785+ - ` http://app.test/api/users?page=1&sort=email&filter[email]=joe&filter=[name]=joe`
786+
787+ You do ** not** need to worry about the URLs if you are using Spatie' s Laravel Query Bulder,
788+ because `VueDataTable` follows their endpoint standard and automatically generates the urls.
789+
790+ If you do not use their package, then you should parse the `url` variable inside
791+ the `fetchCallback`, and modify the url. For example, your javascript code should modify:
792+
793+ `http://app.test/api/users?page=4&filter[name]=foo --> http://app.test/api/users?page=4&search=foo`.
794+
795+ Keep in mind that, by default, Spatie' s Query Builder apply AND logic for all
796+ filters . That means if you have ` &filter[name]=Ana&filter[email]=Ana` , then
797+ you will only get results that both ` name` and ` email` fields match Ana . If
798+ ` name` matches Ana but not the ` email` column, then this row would not appear.
799+
800+ Here is how you can implement ` OR` logic using their package:
801+
802+ ` ` ` php
803+ <?php
804+
805+ // routes/app.php
806+ use App\H ttp\F ilters\F ilterOrWhere;
807+ use App\M odels\U ser;
808+ use Illuminate\S upport\F acades\R oute;
809+ use Spatie\Q ueryBuilder\Q ueryBuilder;
810+ use Spatie\Q ueryBuilder\A llowedFilter;
811+
812+ Route::get('users', function () {
813+ return QueryBuilder::for (User::class)
814+ ->allowedSorts(['name', 'email'])
815+ ->allowedFilters([
816+ AllowedFilter::custom('name', new FilterOrWhere),
817+ AllowedFilter::custom('email', new FilterOrWhere)
818+ ])
819+ ->paginate();
820+ });
821+
822+ // app/Http/Filters/FilterOrWhere.php
823+ namespace App\H ttp\F ilters;
824+
825+ use Spatie\Q ueryBuilder\F ilters\F ilter;
826+ use Illuminate\D atabase\E loquent\B uilder;
827+
828+ class FilterOrWhere implements Filter
829+ {
830+ public function __invoke(Builder $query, $value, string $property)
831+ {
832+ $query->orWhere($property, 'LIKE', '%' . $value . '%');
833+ }
834+ }
835+ ` ` `
836+
667837### Layout
668838
669839` VueDataTable` uses CSS ' s grid display to specify the position of its components
@@ -939,6 +1109,7 @@ export default {
9391109## ROADMAP
9401110
9411111- [x] Support for Vue3
1112+ - [x] Laravel integration
9421113- [ ] Support for SSR
9431114- [ ] String notation for defining columns
9441115
0 commit comments