Quasar's QTable: The ULTIMATE Component (5/6) - Styling EVERYTHING!!!
Tags: quasar, vue, javascript, webdev
Published: 2021-08-20 12:33:51

Welcome back my fine devy friend!

When I started on this post, I had **no idea what I was in for**...

My girlfriend is in the other room, watching a Korean drama, drinking soju (and I LOVE soju).

"1 and a half hours" I told her. When will I learn! **Quasar's `QTable` is relentlessly useful**, and to show you all of it's inner powers takes time!

Anywho..

You'll **love** this one!

Why?

Becuase styling `q-table` is easy! All it takes is a sprinkle of props here and there.

Having said that, there are **two ways to style `q-table`**:
1. props
2. slots

I recommend using **props** where possible (and they're what we'll cover in this post), since they're *easier to write, and eaiser to read*.

## Have You STILL Not Checkerty Checked Out [QuasarComponents.Com?](https://quasarcomponents.com)
If you've come this far into the series and **still** haven't been to [QuasarComponents.Com](https://quasarcomponents.com), then **what the HEY???**

[Head. There. Now.](https://quasarcomponents.com)

I have something [**really cool**](https://quasarcomponents.com) to show you!

...

Ok, let's get started...

## Setup
Here's [le github repo](https://github.com/ldiebold/q-table-blog) ("le github repo" is French for "I don't speak French")

Now **SLAM** this into your editor!

Let's do that thing again where I dive into the code and meet you in there 🤿
```vue
<script>
import { ref } from 'vue'
// 🤿 Quasar has some rad color utilities!
// We'll use "getPaletteColor" in one of the examples.
import { colors } from 'quasar'
const { getPaletteColor } = colors

// 🤿 did saying "rad" up my street cred? I hope so.

export default {
  setup () {
    // three guesses at what we'll use this for...
    const fullscreen = ref(false)

    const rows = [
      {
        id: 1,
        name: 'Panda',
        email: 'panda@chihuahua.com',
        age: 6
      },
      {
        id: 2,
        name: 'Lily',
        email: 'lily@chihuahua.com',
        age: 5
      },
      {
        id: 3,
        name: 'Moe',
        email: 'moe@rip.com',
        age: 7
      },
      {
        id: 4,
        name: 'Avo Cado',
        email: 'free@shivacadoo.com',
        age: 3
      },
      {
        id: 5,
        name: 'Oscar',
        email: 'oscar@comehome.com',
        age: 14
      }
    ]
    
    // 🤿 Oh look, a fish! 🐠

    const columns = [
      { label: 'name', field: 'name', name: 'name', align: 'left' },
      { label: 'email', field: 'email', name: 'email', align: 'left' },
      { label: 'age', field: 'age', name: 'age', align: 'center' }
    ]

    return {
      rows,
      columns,
      columnsStyled,
      fullscreen
    }
  }
}
</script>
```

*emerges from code* 🤿

Did that all make sense?

Sweet! Let's start making some **sexy tables**...

## `color`, `dense`, `dark` and `flat`
```vue
<q-table
  :rows="rows"
  :columns="columns"
  row-key="id"
  color="green"
  :loading="true"
  dense
  dark
  flat
/>
```

![Quasar Vue QTable Color, Dense, Dark and Flat](https://i.imgur.com/s0g34Td.png)


You know what a lot of people don't like about material design? The shadows.

Well guess what... Quasar makes it **EASY to remove the shadow** from all of its components with either `flat` or `unelevated`. As you can see in the above example, `QTable` ain't no exception 🙃

`color` changes the **loading bar color**, and the **selected item in pagination** and...

`dense` tightens things up. Great for when you have a large amount of data to show!

## `bordered`, `flat`, `square` (Cleancut)
I call this the "Cleancut" design. It makes the table look slick and professional:

```vue
<q-table
  :rows="rows"
  :columns="columns"
  row-key="id"
  bordered
  flat
  square
/>
```

![Quasar Vue QTable Bordered, Flat, Square (Cleancut)](https://i.imgur.com/0c8gg0X.png)


See what I mean? It's like the "James Bond" of table design 😎

try removing the `border`. You'll notice that the table stands completely on its own without a border in this example!

![Quasar Vue QTable No Border Or Shadow](https://i.imgur.com/lMszHHN.png)

## Specific Classes and Styles
These little helper props are awesome! **Usually, they're all you'll need** for designing your table:

```vue
<q-table
  :rows="rows"
  :columns="columns"
  row-key="id"
  title="Blue Chihuahua's"
  title-class="text-bold text-blue-9"
  table-class="bg-blue-9 text-white"
  table-style="border: 3px solid black;"
  table-header-style="height: 65px;"
  table-header-class="bg-blue-8"
/>
```

![Quasar Vue QTable Targeting Specific Classes And Styles](https://i.imgur.com/9D0xReM.png)


Notice we can target the
- **Title**
- **Header**
- **Body**

Nice! 😊

## Specific Column Classes and Styles
Now THIS is something I use all the time. **The columns object itself** can be tapped into so we can change the styling of **columns**.

Razvan (creator of Quasar) must have been in some sort of next level zen state when he was designing this **work of art**!

```vue
<template>
  <q-table
    :rows="rows"
    :columns="columnsStyled"
    row-key="id"
  />
</template>

<script>
export default {
  setup () {
    // Add this in
    const columnsStyled = [
      {
        label: 'name',
        field: 'name',
        name: 'name',
        align: 'left',
        classes: 'bg-pink-1 text-bold',
        style: {
          fontSize: '1.2em',
          borderLeft: `6px solid ${getPaletteColor('pink-4')}`
        },
        headerClasses: 'bg-grey-1',
        headerStyle: {
          fontSize: '1.2em'
        }
      },
      {
        label: 'email',
        field: 'email',
        name: 'email',
        align: 'left',
        headerClasses: 'bg-grey-3',
        classes: 'bg-pink-2'
      },
      {
        label: 'age',
        field: 'age',
        name: 'age',
        align: 'center',
        headerClasses: 'bg-grey-1',
        classes: 'bg-pink-1'
      }
    ]
    
    return {
      // And this
      columnsStyled
    }
  }
}

</script>
```

![Quasar Vue QTable Targeting Specific Classes And Styles On Column Objects](https://i.imgur.com/mc03KSn.png)


How. Cool. Is. **THAT!**

To summarise, the **column options** we're using here are:
- classes
- style
- headerClasses
- headerStyle

Sure, the example looks a little messed up... But you're not here to get a degree as an artist 🎨 (nor are you likely to get one from me).

## Pagination
Dealing with pagination and slots can get pretty complicated... Luckily, it's likely we can solve our **pagination styling problems** with these handy dandy props!

```vue
<q-table
  :rows="rows"
  :columns="columns"
  row-key="id"
  :rows-per-page-options="[2, 0]"
  rows-per-page-label="records/page"
  icon-first-page="home"
  icon-last-page="all_inclusive"
  icon-next-page="arrow_right"
  icon-prev-page="arrow_left"
  :pagination-label="(firstRowIndex, endRowIndex, totalRowsNumber) => {
    return `page ${endRowIndex}/${totalRowsNumber}`
  }"
/>
```

![Quasar Vue QTable Styling Pagination](https://i.imgur.com/4ybkFAV.png)


The cool one to note here, is `pagination-label`

With `pagination-label`, we can even change the way we display the "status" of our current pagination with a simple function!

## Hiding Header Row and Bottom (Pure Table)
Sometimes you just want a plain ol table. No heading, no footer, no pagination... Just a "basic as can be" table.

This is how we can do it with `QTable`:
```vue
<q-table
  :rows="rows"
  :columns="columns"
  row-key="id"
  hide-header
  hide-bottom
/>
```

![Quasar Vue QTable Hiding The Header And Bottom (Pure Table)](https://i.imgur.com/VgsKgI5.png)


That's all I have to say on that 🤷

## Hiding Pagination (may auto remove bottom)
Often, we don't even need pagination. Let's just hide it:
```vue
<q-table
  :rows="rows"
  :columns="columns"
  row-key="id"
  hide-pagination
  :rows-per-page-options="[0]"
/>
```

![Quasar Vue QTable Hiding Pagination](https://i.imgur.com/CqrYHol.png)


**IMPORTANT**
hiding pagination **does not remove pagination functionality**. In other words, you might only see 5/10 rows of data, and have no way of viewing the rest of it (since pagination controls are hidden)!

That's why we added `:rows-per-page-options="[0]"` in the above example.

You may remember from the post on pagination, **0** means **all**. So essentially, that code is ensuring that we **show ALL rows** since the pagination is hidden.

Also, if there is **nothing else to show in the bottom row**, no bottom row will show at all (like in the example)

## Hiding `no-data`
I can't think of a good reason to do this, but of course, Quasar makes it possible to hide the default "no data" message...

```vue
<q-table
  :rows="[]"
  :columns="columns"
  row-key="id"
  hide-no-data
/>
```

![Quasar Vue QTable Hiding No Data Message](https://i.imgur.com/oPYHIIj.png)


Nothin but header now!

## Visible Columns
Maybe I should have put this furthur up the list since it's **So HANDY!**

We can **easily** hide columns with the `visible-columns` prop:

```vue
<q-table
  :rows="rows"
  :columns="columns"
  row-key="id"
  :visible-columns="['name', 'age']"
/>
```

![Quasar Vue QTable Hiding And Showing Columns](https://i.imgur.com/X7bU4ko.png)


Note that the **strings in the `visible-columns` array**, need to be the same as the `name` prop on the corresponding `columns` object.

Erg, that was a mouthful... Might need to read it a few times!

In some of my apps, we use a `q-menu` on the top row, and allow people to toggle columns on and off using a menu! This is easy to do with `visible-columns`! Maybe that could be another blog post 🤔

## Fullscreen
"**WHAT!!??** Quasar's `QTable` supports **FULL SCREEN!!??**"

Yes. It does 😉

```vue
<q-table
  :rows="rows"
  :columns="columns"
  row-key="id"
  :fullscreen="fullscreen"
  title="dogs"
>
  <template #top-right>
    <q-btn
      dense
      flat
      icon="fullscreen"
      @click="fullscreen = !fullscreen"
    />
  </template>
</q-table>
```

![Quasar Vue QTable Fullscreen Mode](https://i.imgur.com/o9s61cd.png)


In this example, we added a button on the `#top-right` that **toggles fullscreen on and off.** Piece of cake 🍰

## `separator` and `wrap-cells`
By default, every `QTable` row is divided with a horizontal line. Of course, we can change this to either a `vertical` line, or a full `cell`

In this example, we're also demonstrating `wrap-cells`. `wrap-cells` is handy, as it ensures that long text wraps correctly in a cell! Note that it's only evident for **"Avo Cado"**

```vue
<q-table
  :rows="rows"
  :columns="columns"
  row-key="id"
  separator="cell"
  style="width: 300px;"
  wrap-cells
/>
```

![Quasar Vue QTable Separators, Cell, Vertical, Horizontal and Wrapping Text In Cells](https://i.imgur.com/HG7rN3G.png)


Possible options for `separator` are:
- **horizontal**
- **vertical**
- **cell**
- **none**

Moving on!

## `no-data` Label
Change the default `no-data` label:

```vue
<q-table
  :rows="[]"
  :columns="columns"
  row-key="id"
  no-data-label="I can't find any data 😞"
/>
```

![Quasar Vue QTable Changing The No Data Label](https://i.imgur.com/3UvxXLz.png)


## `loading-data` Label
And the default `loading-data` label:

```vue
<q-table
  :rows="[]"
  :columns="columns"
  row-key="id"
  :loading="true"
  loading-label="Gimme a sec and I'll fetch ya data!"
/>
```

![Quasar Vue QTable Changing The Loading Data Label](https://i.imgur.com/RAS3Hqi.png)


## Grid Mode
I'll be honest, I've never in my life used grid mode (until writing this blog post).

But some people love it, so here ya go!

```vue
<q-table
  :rows="rows"
  :columns="columns"
  row-key="id"
  grid
  card-class="bg-indigo-9 text-white"
  card-style="padding: 22px;"
/>
```

![Quasar Vue QTable Grid Mode](https://i.imgur.com/oHA7Xzb.png)


In this example, we're also tapping into the styling of the grid cards!

## `no-hover` (`q-td` and `q-tr`)
Last, and maybe least, we can **remove the default "highlight" effect** we get with `QTable`.

These are specific to `q-td` and `q-tr`, so we'll have to demonstrate this using the `#body` template...

```
<q-table
  :rows="rows"
  :columns="columns"
  row-key="id"
>
  <template #body="props">
    <q-tr
      no-hover
      :props="props"
    >
      <q-td
        key="name"
        no-hover
        :props="props"
      >
        {{ props.row.name }}
      </q-td>

      <q-td
        key="email"
        no-hover
        :props="props"
      >
        {{ props.row.email }}
      </q-td>

      <q-td
        key="age"
        no-hover
        :props="props"
      >
        {{ props.row.age }}
      </q-td>
    </q-tr>
  </template>
</q-table>
```

![Quasar Vue QTable Removing Hover Effect](https://i.imgur.com/B0mGSGF.png)

Kinda hard to tell with a picture 😅

## Aaand We're Done!
So there you go! If there is anything you want to acheive with `QTable` styling, hit me up.

I feel like I've seen just about everything now, so there's a good chance I can help you out 🙂

And trust me, **you're going to want to checkout [QuasarComponents.Com](https://quasarcomponents.com)!**

Quasar has a **MASSIVE** component library that's second to none, and I want to teach you **[All 72 Of Those Components](https://quasarcomponents.com)**

Thanks for reading, and please dear reader. **Please**...

Keep this thought in your mind as you hit the pillow and drift into the night 🌙

There is **nothing** you can't build...