Quasar's QTable: The ULTIMATE Component (3/6) - Loading State, Pagination, and Sorting (2024)

Luke for Quasar

Posted on • Updated on

Quasar's QTable: The ULTIMATE Component (3/6) - Loading State, Pagination, and Sorting (4) Quasar's QTable: The ULTIMATE Component (3/6) - Loading State, Pagination, and Sorting (5) Quasar's QTable: The ULTIMATE Component (3/6) - Loading State, Pagination, and Sorting (6) Quasar's QTable: The ULTIMATE Component (3/6) - Loading State, Pagination, and Sorting (7) Quasar's QTable: The ULTIMATE Component (3/6) - Loading State, Pagination, and Sorting (8)

#quasar #vue #javascript #webdev

Here's the video version...

You already know what loading state, pagination and sorting is right?

Sweet! No preamble required, let's just dive right in...

Oh, and WACK this link if you'd like to Learn All 72 Of Quasar's Components!

Now let's begin!

Setup

Just want the code? Here's the github repo! ldiebold/q-table-blog

We'll do some fancy pants stuff in this blog, so we'll need a backend... Luckily, I built a free api just for you! checkout this endpoint...

https://table.quasarcomponents.com/dogs

Take a squiz at the data! if you scroll down to the meta property, you'll notice that we have pagination...

{ data: [ { id: 1, created_at: "2021-08-17T01:29:29.000000Z", updated_at: "2021-08-17T01:29:29.000000Z", name: "Hollie", email: "nshields@yahoo.com", age: 9 }, { id: 2, created_at: "2021-08-17T01:29:29.000000Z", updated_at: "2021-08-17T01:29:29.000000Z", name: "Sonya", email: "shields.gonzalo@douglas.info", age: 19 } ], links: { first: "http://table.quasarcomponents.com/dogs?page=1", last: "http://table.quasarcomponents.com/dogs?page=34", prev: null, next: "http://table.quasarcomponents.com/dogs?page=2" }, meta: { current_page: 1, from: 1, last_page: 34, links: [ { url: null, label: "« Previous", active: false }, { url: "http://table.quasarcomponents.com/dogs?page=1", label: "1", active: true } ], path: "http://table.quasarcomponents.com/dogs", per_page: 15, to: 15, total: 500 }}

Note that much of the data and links have been removed for brevity

We'll need axios so it's easy to hit that endpoint, so let's go ahead and install it:

Now we'll use it in our <script>:

<script>import { defineComponent, ref } from 'vue'import axios from 'axios'export default defineComponent({ setup () { const loading = ref(true) const dogs = ref([]) const columns = [ { name: 'name', label: 'Name', field: 'name', align: 'left' }, { name: 'age', label: 'Age', field: 'age', align: 'center' }, { name: 'email', label: 'Email', field: 'email' } ] // Fetch dogs axios.get('https://table.quasarcomponents.com/dogs') .then(response => { dogs.value = response.data.data }) .finally(() => { loading.value = false }) return { columns, loading, dogs } }})</script>

If you've read the prior two posts, this might be starting to make sense...

We setup some data, do some column config, fetch the dogs, update our dogs array, toggle the loading state, and expose it to the template!

Loading State

Quasar gives us a simple, beautiful loading bar when we set the loading prop to true. It also respects the tables color prop!

Here, I'll show you...

<q-table color="secondary" :loading="loading" :rows="dogs" :columns="columns"/>

Quasar's QTable: The ULTIMATE Component (3/6) - Loading State, Pagination, and Sorting (9)

That's it! You might need to refresh the page to see it loading (especially if you're in Paris, cause that's where the server is!)

You could also just set :loading="true". I usually do this when playing with the styling!

So that's basic loading but of course...

Quasar gives us TOTAL control with slots 🙃

The #loading Slot

Take a look at the #loading slot in this example:

<q-table :loading="loading" :rows="dogs" color="primary"> <template #loading> <q-inner-loading showing color="primary" /> </template></q-table>

Quasar's QTable: The ULTIMATE Component (3/6) - Loading State, Pagination, and Sorting (10)

Using Quasar's QInnerSpinner component, we can create a beautiful alternative way of displaying "loading".

I personally think this looks sweet!

Alright, that's enough loading you crazy dev you 😁. Let's take a look at pagination.

Pagination

Quasar's QTable gives you everything you need for pagination by allowing you to model pagination.

let's add it to our script

export default defineComponent({ setup () { // ... const pagination = ref({ sortBy: 'name', descending: false, page: 1, rowsPerPage: 3 }) return { // ... pagination } }}

Most of those pagination options likely make sense to you. Note that Quasar also gives us sortBy and descending.

sortBy and descending allow us to set a default sort to our table. Where I work, we use this a lot as clients often want to see their data in alphabetical order by default.

I'll show you later how it's possible to change the sort algorithm (I always feel smart using the word "algorithm")

Now let's model this pagination data in the table:

<q-table v-model:pagination="pagination" color="secondary" :loading="loading" :rows="dogs" :columns="columns"/>

Quasar's QTable: The ULTIMATE Component (3/6) - Loading State, Pagination, and Sorting (11)

Pretty cool huh?

AND, we can even change those Rows per page options with a prop:

<q-table v-model:pagination="pagination" :rows-per-page-options="[3, 5, 10, 0]" color="secondary" :loading="loading" :rows="dogs" :columns="columns"/>

Quasar's QTable: The ULTIMATE Component (3/6) - Loading State, Pagination, and Sorting (12)

Gosh I love Quasar ❤️

If you're a POWER user, you might be crossing your arms thinking "yea, but I need server side pagination. Server side pagination is always a pain to implement."

Well uncross those arms because it's a piece of pecan pie with Quasar!

Server Side Pagination (A Piece Of Pecan Pie)

This is why I build the https://table.quasarcomponents.com/dogs api! So we can easily play with server side pagination...

I'm going to move my explanation into the code, since this example is a little more involved! See you there...

⬇️Jumps into code block below⬇️

<template> <!-- Why hello there! Meet me at the "script" section. That's where the magic happens 🪄 --> <q-page padding class="flex justify-center" > <div class="full-width q-gutter-xl" > <!-- Two things to notice here 1. "rows-per-page-options" has been emptied. We're going to let the server decide how many "rows per page" 2. @request is fired whenever a pagination is clicked! Handy 🙂 --> <q-table v-model:pagination="pagination" :rows-per-page-options="[]" color="secondary" :loading="loading" :rows="dogs" :columns="columns" @request="onRequest" /> </div> </q-page></template><script>import { defineComponent, ref } from 'vue'import axios from 'axios'export default defineComponent({ setup () { // And here we are! // I'll only comment on the parts that are different 😉 const loading = ref(true) const dogs = ref([]) const pagination = ref({ // No longer using sort. if needed, this can now be done using the backend! // sortBy: 'name', // descending: false, page: 1, rowsPerPage: 15, // When using server side pagination, QTable needs // to know the "rows number" (total number of rows). // Why? // Because Quasar has no way of knowing what the last page // will be without this information! // Therefore, we now need to supply it with a "rowsNumber" ourself. rowsNumber: 0 }) const columns = [ { name: 'name', label: 'Name', field: 'name', align: 'left', sortable: true }, { name: 'age', label: 'Age', field: 'age', align: 'center' }, { name: 'email', label: 'Email', field: 'email' } ] // Fetch dogs const fetchDogs = (page = 0) => { // we can specify the "page" to jump to loading.value = true return axios.get('https://table.quasarcomponents.com/dogs', { params: { page: page } // here, we tell the api what "page" to jump to }) .then(response => { dogs.value = response.data.data // The api gives us "meta data". // this meta data gives us everything we // need to get pagination working! const meta = response.data.meta // We now update "pagination" with our meta data // from the server. This is where the magic happens 🪄 pagination.value.page = meta.current_page pagination.value.rowsPerPage = meta.per_page pagination.value.rowsNumber = meta.total }) .finally(() => { loading.value = false }) } // QTable exposes a @request method (see the <template>) // This will be called when one of the pagination buttons are clicked. // it gives us everything we need, including the new page number! const onRequest = (props) => { fetchDogs(props.pagination.page) } // The initial fetch fetchDogs() return { onRequest, columns, loading, dogs, pagination } }})</script>

⬆️Jumps out of code block⬆️

HOW COOL WAS THAT!!??

Being INSIDE a code block is strange... It was kinda cold in there, will have to take a coat next time 🧥

Anywho,

Let's take a look at the result:

Quasar's QTable: The ULTIMATE Component (3/6) - Loading State, Pagination, and Sorting (13)

So there you go. Server side pagination is a blast with Quasar!

And if you really want total control, you could use Quasar's QPagination component and completely replace QTable's pagination.

Right, let's move on to the last topic for today/night/evening/morning (us devs are worldy people)...

Sorting

Want basic sorting? Quasar's got ya sorted! HA! I made a joke!!!

ahem

Sorting is only one prop away...

const columns = [ { name: 'name', label: 'Name', field: 'name', align: 'left', sortable: true }, { name: 'age', label: 'Age', field: 'age', align: 'center', sortable: true }, { name: 'email', label: 'Email', field: 'email', sortable: true }]

Notice we set sortable: true on all the columns?

Also, notice that when we hover over one of the "heading" cells, we get a sort arrow...
Quasar's QTable: The ULTIMATE Component (3/6) - Loading State, Pagination, and Sorting (14)

sortable: true will do the job most of the time, otherwise we can use...

Custom Sorting

Need to use your own sort function? No problem!

In this example, we'll sort using email by domain (e.g. gmail.com, hotmail.com, quasarcast.com etc)

const columns = [ { name: 'name', label: 'Name', field: 'name', align: 'left', sortable: true }, { name: 'age', label: 'Age', field: 'age', align: 'center', sortable: true }, { name: 'email', label: 'Email', field: 'email', sortable: true, sort: (a, b) => { const domainA = a.split('@')[1] const domainB = b.split('@')[1] return domainA.localeCompare(domainB) } }]

Bon Appétable!

Quasar's QTable: The ULTIMATE Component (3/6) - Loading State, Pagination, and Sorting (15)

We're now sorting with our own sorter! Sorta cool right?

"What's Next?""

In the next post, I'm going to gift you with QTable's ultimate power!

We're going to cover All of Quasar's Slots!!!

You're not gonna wanna miss it! Slots give QTable UNLIMITED flexibility 💪

For Those That Need A Little More...

Quasar has a huge, impressive component library.

The APIs will bring you to your knees with joy! The flexibility will have you nodding your head with approval, and the beautiful community will lead you to fall in love with this framework.

Sound like something worth exploring?

Of course it is!

Now head on over to QuasarComponents.Com and let me to take you on a journey you'll never forget!

I'll teach you all 72 of Quasar's components in action packed videos that will leave you excited to code!!!

Click Here and I'll see you on the other side!

That's all my dear dev friends. Now can you please do me a very important favour?

Go to bed tonight remembering, and dreaming about this one thing,

There is nothing you can't build...

Quasar's QTable: The ULTIMATE Component (3/6) - Loading State, Pagination, and Sorting (2024)
Top Articles
Latest Posts
Article information

Author: Wyatt Volkman LLD

Last Updated:

Views: 5710

Rating: 4.6 / 5 (66 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Wyatt Volkman LLD

Birthday: 1992-02-16

Address: Suite 851 78549 Lubowitz Well, Wardside, TX 98080-8615

Phone: +67618977178100

Job: Manufacturing Director

Hobby: Running, Mountaineering, Inline skating, Writing, Baton twirling, Computer programming, Stone skipping

Introduction: My name is Wyatt Volkman LLD, I am a handsome, rich, comfortable, lively, zealous, graceful, gifted person who loves writing and wants to share my knowledge and understanding with you.