Prefer video? I got ya covered!
I use selectable rows, and expandable rows all the time! I'll give you a real world example.
We record "spraying events" for paddocks, and sometimes a paddock will be sprayed many times! Our app groups individual sprays by paddock, and also gives a "total amount sprayed" in the parent row!
Now look at what happens when we click on one of the rows...
The farmers LOVE IT! And guess what...
It was surprisingly easy to build with Quasar's QTable! I'll show you how π
Also, notice the Totals row at the bottom? Also a piece of cake with Quasar! (more on summary rows in a future blog post)
Now before we dive in, take a look at QuasarComponents.Com for some action packed, heart POUNDING, nail biting, high intensity videos on all 72 of Quasar's components!
click here and I'll see you on the other side π
A Little Setup
Let's do some basic setup so things run smoothly!
<script>
import { ref } from 'vue'
export default {
setup () {
const selected = ref()
const rows = [
{
id: 1,
name: 'Panda',
email: 'panda@chihuahua.com',
age: 6
},
{
id: 2,
name: 'Lily',
email: 'lily@chihuahua.com',
age: 5
}
]
const columns = [
{ label: 'expand', name: 'expand', field: 'expand' },
{ label: 'id', field: 'id', name: 'id' },
{ label: 'name', field: 'name', name: 'name' },
{ label: 'email', field: 'email', name: 'email' },
{ label: 'age', field: 'age', name: 'age' }
]
return {
rows,
columns,
selected
}
}
}
</script>
Expandable Rows
Expandable rows are made possible with the #body
slot. I'll here's how it's done π
<q-table
:rows="rows"
:columns="columns"
row-key="id"
>
<template #body="props">
<q-tr :props="props">
<!-- Expand cell/button -->
<q-td
key="expand"
name="expand"
:props="props"
auto-width
>
<!--
The important part here is
@click="props.expand = !props.expand"
-->
<q-btn
flat
round
:icon="props.expand ? 'remove' : 'add'"
@click="props.expand = !props.expand"
/>
</q-td>
<!--
Notice that we the "key" matches the columns "name" property
Notice that we "proxy" the props from #body="props" to our q-td
-->
<q-td
key="id"
:props="props"
>
{{ props.row.id }}
</q-td>
<q-td
key="name"
:props="props"
>
{{ props.row.name }}
</q-td>
<q-td
key="email"
:props="props"
>
{{ props.row.email }}
</q-td>
<q-td
key="age"
:props="props"
>
{{ props.row.age }}
</q-td>
</q-tr>
<!-- We show the row if "props.expand" is toggled to true! -->
<q-tr
v-show="props.expand"
:props="props"
>
<q-td colspan="100%">
<div class="text-left">
Expanded
</div>
</q-td>
</q-tr>
</template>
</q-table>
A few things to note here:
First: The #body
slot allows us to tap into individual rows
Second: we use Quasar's q-tr
and q-td
components to build the row. This gives us INSANE control!
Third: We use the scope (#body="props"
) and pass it to every q-td
and q-tr
. This is important! It means our q-tr
's and q-td
's get all the styling they need for things like dense
and visible-columns
(more on those later)
Fouth: We can toggle/track if a row is expanded with props.expanded
Read those four points back and forth until they make sense! Understand them, and you'll have IMMENSE power over Quasar's QTable!
Also notice that in the expanded row, we use colspan="100%"
to basically say "take up all the space in this row". Helpful for things like "create" buttons that insert new rows.
AND, auto-width
which "Tries to shrink column width size; Useful for columns with a checkbox/radio/toggle"
Individual Cells For Each Row
To be thorough, here's an example where the expanded row has cells, lining up with cells on the parent row...
<!-- Expandable Row (cells) -->
<q-table
:rows="rows"
:columns="columns"
row-key="id"
>
<template #body="props">
<!-- PARENT ROW -->
<q-tr :props="props">
<!-- Expand cell/button -->
<q-td
key="expand"
name="expand"
:props="props"
auto-width
>
<q-btn
flat
round
:icon="props.expand ? 'remove' : 'add'"
@click="props.expand = !props.expand"
/>
</q-td>
<q-td
key="id"
:props="props"
>
{{ props.row.id }}
</q-td>
<q-td
key="name"
:props="props"
>
{{ props.row.name }}
</q-td>
<q-td
key="email"
:props="props"
>
{{ props.row.email }}
</q-td>
<q-td
key="age"
:props="props"
>
{{ props.row.age }}
</q-td>
</q-tr>
<!-- CHILD ROW -->
<q-tr
v-show="props.expand"
:props="props"
>
<!--
Might want to leave the first cell blank, as it is
simply space for the "expand" column
-->
<q-td
key="expand"
:props="props"
/>
<q-td :props="props">
summary
</q-td>
<q-td
key="id"
:props="props"
>
summary
</q-td>
<q-td
key="name"
:props="props"
>
summary
</q-td>
<q-td
key="email"
:props="props"
>
summary
</q-td>
<q-td
key="age"
:props="props"
>
summary
</q-td>
</q-tr>
</template>
</q-table>
those places that say "summary"... You can put whatever you like in those cells!
BIG TIP: use props.row
to access the current row π£
HA! Emoji joke π
It's also worth noting that you can have as many "child" rows as you like!
And THAT my friend, is expandable rows. now let's move on to making rows selectable.
Selectable Rows. A Gift From Quasar π
This truly is a gift! I've implemented a "selectable rows" feature myself in the past and you know what?
It SUCKS!
Quasar makes it easier than blowing out a two year old's birthday candles π (which you shouldn't do, that's not cool)...
Check it!
<q-table
v-model:selected="selected"
selection="single"
:rows="rows"
row-key="id"
/>
Yes! It really is that flippen easy π±π±π±
Do I even need to explain this code!?
The one thing to note, is row-key
is used to uniquely identify the selected data, so you'll need it!
HOT TIP: use the pre
tag to display this data nicely when testing...
<pre>{{ selected }}</pre>
That's what all the cool kids are doing (or so I'm told)
"But Luke! I want to use a TOGGLE, not a checkbox
Oh!? Do ya now!?
No worries my inquisitive friend! Rollup your sleeves and try this!
<q-table
v-model:selected="selected"
selection="multiple"
:rows="rows"
row-key="id"
>
<template #header-selection="scope">
<q-toggle v-model="scope.selected" />
</template>
<template #body-selection="scope">
<q-toggle v-model="scope.selected" />
</template>
</q-table>
(did you catch my cheeky rollup joke?)
Note that scope.selected
is a simple function that toggles the selection for you. Easy right?
Are you starting to see how Quasar's API makes building components bliss? I LOVE it β€οΈ
multiple select
You can enable multiple select by changing selection="single"
to selection="multiple"
πͺ
"Luke! This Is SO COOL! I Want MORE"
Oh nice, I love your enthusiasm!
If you want to learn more about this stuff, head on over to QuasarComponents.Com
In that series, we will...
- Cover all 72 of Quasar's Components
- Build YouTube's UI with Quasar
- Build a Live Chat App with Laravel and Quasar
- Build a Quasar App Extension
All proceeds are donated directly to the Quasar Dev team!
Thanks for reading π€. Tomorrow we'll cover Loading State, Pagination, and Sorting (You're gonna LOVE Pagination).
Bye for now! And please for the love of code remember,
There is nothing you can't build...
Top comments (1)
I've added the ability to hide show rows which works great. Except, if you have a row expanded and go to the next page in the results... then go back to that previous page, all using the table navigation, you see the expanded row icon but the row is not expanded. If I click and click again then the row displays. How can I reset all the expanded rows when moving from page to page in the table?