Categories
Vue

Add a Calendar into a Vue App with Vue2-Simple-Calendar

A calendar is something that is hard to create from scratch.

Therefore, there’re many calendar components created for Vue apps.

In this article, we’ll look at how to add a calendar with Vue2-Simple-Calendar.

Vue2-Simple-Calendar

We can install Vue2-Simple-Calendar by running:

npm install vue2-simple-calendar

with NPM or:

yarn add vue2-simple-calendar

Then we can use it by writing:

main.js

import Vue from "vue";
import App from "./App.vue";
import vueCalendar from "vue2-simple-calendar";
import "./assets/calendar.css";

Vue.use(vueCalendar, {});
Vue.config.productionTip = false;

new Vue({
  render: (h) => h(App)
}).$mount("#app");

App.vue

<template>
  <div id="app">
    <vue-calendar
      :show-limit="3"
      :events="events"
      :disable="disabledDays"
      :highlight="highlightDays"
      @show-all="showAll"
      @day-clicked="dayClicked"
      @event-clicked="eventClicked"
      @month-changed="monthChanged"
    ></vue-calendar>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      events: [
        {
          title: "event",
          start: new Date(),
          end: new Date(),
        },
      ],
      disabledDays: {
        to: new Date(2020, 9, 5),
        from: new Date(2020, 11, 26),
      },
      highlightDays: {
        days: [6, 0],
      },
    };
  },
  methods: {
    showAll(events) {
      // Do something...
    },
    dayClicked(day) {
      // Do something...
    },
    eventClicked(event) {
      // Do something...
    },
    monthChanged(start, end) {
      // Do something...
    },
  },
  created() {
    this.$calendar.eventBus.$on("show-all", (events) => this.showAll(events));
    this.$calendar.eventBus.$on("day-clicked", (day) => this.dayClicked(day));
    this.$calendar.eventBus.$on("event-clicked", (event) => console.log(event));
    this.$calendar.eventBus.$on("month-changed", (start, end) =>
      console.log(start, end)
    );
  },
};
</script>

/assets/calendar.css

.vue-calendar {
  display: grid;
  grid-template-rows: 10% 90%;
  background: #fff;
  margin: 0 auto;
}
.calendar-header {
  align-items: center;
}
.header-left,
.header-right {
  flex: 1;
}
.header-center {
  flex: 3;
  text-align: center;
}
.title {
  margin: 0 5px;
}
.next-month,
.prev-month {
  cursor: pointer;
}
.calendar-body {
  display: grid;
  grid-template-rows: 5% 95%;
}
.days-header {
  display: grid;
  grid-auto-columns: 14.25%;
  grid-template-areas: "a a a a a a a";
  border-top: 1px solid #e0e0e0;
  border-left: 1px solid #e0e0e0;
  border-bottom: 1px solid #e0e0e0;
}
.days-body {
  display: grid;
  grid-template-rows: auto;
}
.day-number {
  text-align: right;
  margin-right: 10px;
}
.day-label {
  text-align: center;
  border-right: 1px solid #e0e0e0;
}
.week-row {
  display: grid;
  grid-template-areas: "a a a a a a a";
  grid-row-gap: 5px;
  grid-auto-columns: 14.25%;
  border-left: 1px solid #e0e0e0;
}
.week-day {
  padding: 4px;
  border-right: 1px solid #e0e0e0;
  border-bottom: 1px solid #e0e0e0;
}
.week-day.disabled {
  background-color: #f5f5f5;
}
.week-day.not-current > .day-number {
  color: #c3c3c3;
}
.week-day.today > .day-number {
  font-weight: 700;
  color: red;
}
.events {
  font-size: 12px;
  cursor: pointer;
  padding: 0 0 0 4px;
}
.events .event {
  height: 18px;
  line-height: 18px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  margin: 0 4px 2px 0;
  color: rgba(0, 0, 0, 0.87);
  background-color: #d4dcec;
}
.events .more-link {
  color: rgba(0, 0, 0, 0.38);
}

We add the grid layout with the days-header and the week-row classes.

In main.js , we add the VueCalendar plugin so we can use it our components.

We need to import the calendar.css to apply the styles from the CSS styles.

In App.vue , we add the vue-calendar component to add the calendar.

show-limit has the max number of events shown in a day.

events has an array of events.

disable has days that we want to disable.

show-all event is emitted when the show more link is clicked.

day-clicked is emitted when a day is clicked.

event-clicked is emitted when an event is clicked.

month-changed is emitted when the month changed.

Conclusion

The Vue2-Simple-Calendar lets us add an event calendar easily into our Vue app.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Loading Indicator

Quasar is a popular Vue UI library for developing good looking Vue apps.

In this article, we’ll take a look at how to create Vue apps with the Quasar UI library.

Loading Indicator

We can add a loading indicator with the $q.loading object:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md"></div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        beforeMount() {
          this.$q.loading.show({
            delay: 400
          });
          setTimeout(() => {
            this.$q.loading.hide();
          }, 3000);
        }
      });
    </script>
  </body>
</html>

We call the $q.loading.show method with the delay property to delay the loading indicator’s display.

The number is in milliseconds.

Then we hide it with the $q.loading.hide method.

We can add a message with the message property:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md"></div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        beforeMount() {
          this.$q.loading.show({
            delay: 400,
            message:
              'Some important <b>process</b> is in progress.<br/><span class="text-primary">Hang on...</span>'
          });
          setTimeout(() => {
            this.$q.loading.hide();
          }, 3000);
        }
      });
    </script>
  </body>
</html>

We can set it to HTML.

We can add the sanitize property to the object to escape the HTML code.

We can add more customizations with more properties:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md"></div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        beforeMount() {
          this.$q.loading.show({
            spinner: Quasar.QSpinnerFacebook,
            spinnerColor: "yellow",
            spinnerSize: 140,
            backgroundColor: "purple",
            message: "Some important process is in progress. Hang on...",
            messageColor: "black"
          });
          setTimeout(() => {
            this.$q.loading.hide();
          }, 3000);
        }
      });
    </script>
  </body>
</html>

spinner has the icon for the loading spinner,

spinnerColor sets the spinner color.

spinnerSize sets the spinner size.

backgroundColor sets the background color of the overlay.

messageColor sets the color of the message.

Loading Bar

We can add a loading bar with the $q.loadingBar object.

For instance, we can write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md"></div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        beforeMount() {
          this.$q.loadingBar.start();

          setTimeout(() => {
            this.$q.loadingBar.stop();
          }, 3000);
        }
      });
    </script>
  </body>
</html>

We call start to show it and stop to stop it.

We can also call this.$q.loadingBar.increment(value) to change the progress value.

Also, we can change the options with the LoadingBar.setDefaults method:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md"></div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        beforeMount() {
          Quasar.LoadingBar.setDefaults({
            color: "purple",
            size: "15px",
            position: "bottom"
          });
          this.$q.loadingBar.start();

          setTimeout(() => {
            this.$q.loadingBar.stop();
          }, 3000);
        }
      });
    </script>
  </body>
</html>

We set the color , size , and position to set those styles.

Conclusion

We can add a loading indicator with various styles into our Vue app with Quasar’s loading bar plugin.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Dialog Validation and Custom Dialog

Quasar is a popular Vue UI library for developing good looking Vue apps.

In this article, we’ll take a look at how to create Vue apps with the Quasar UI library.

Dialog Validation

We can add validation to prompt dialogs with the prompt.isValid property:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md">
        <q-btn label="Prompt" color="primary" @click="prompt"></q-btn>
      </div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        methods: {
          prompt() {
            this.$q
              .dialog({
                title: "Prompt",
                message: "What is your name? (Minimum 3 characters)",
                prompt: {
                  model: "",
                  isValid: (val) => val.length > 2,
                  type: "text"
                },
                cancel: true,
                persistent: true
              })
              .onOk((data) => {
                console.log(data);
              });
          }
        }
      });
    </script>
  </body>
</html>

We set isValid to a function that takes the entered value and returns the validation condition.

This can also be used with radio buttons and checkbox dialogs.

HTML Dialog

We can show a native HTML dialog with the html property set to true .

For example, we can write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md">
        <q-btn
          label="Show HTML Dialog"
          color="primary"
          @click="showDialog"
        ></q-btn>
      </div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        methods: {
          showDialog() {
            this.$q
              .dialog({
                title: "Alert<em>!</em>",
                message:
                  '<em>I can</em> <span class="text-red">use</span> <strong>HTML</strong>',
                html: true
              })
              .onOk(() => {
                console.log("OK");
              })
              .onCancel(() => {
                console.log("Cancel");
              })
              .onDismiss(() => {
                console.log("I am triggered on both OK and Cancel");
              });
          }
        }
      });
    </script>
  </body>
</html>

We just set the title and message properties to HTML that we want to render.

This means that cross-site scripting attacks can be executed if malicious code is planted into the HTML.

We can render a custom dialog with the q-dialog component:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md">
        <q-btn label="Show Dialog" color="primary" @click="showDialog"></q-btn>
      </div>
    </div>
    <script>
      const CustomComponent = {
        template: `
        <q-dialog ref="dialog" @hide="onDialogHide">
          <q-card class="q-dialog-plugin">
            <q-card-section>
              Hello
            </q-card-section>
            <q-card-actions align="right">
              <q-btn color="primary" label="OK" @click="onOKClick"></q-btn>
              <q-btn color="primary" label="Cancel" @click="onCancelClick"></q-btn>
            </q-card-actions>
          </q-card>
        </q-dialog>
        `,
        methods: {
          show() {
            this.$refs.dialog.show();
          },
          hide() {
            this.$refs.dialog.hide();
          },
          onDialogHide() {
            this.$emit("hide");
          },
          onOKClick() {
            this.$emit("ok");
            this.hide();
          },
          onCancelClick() {
            this.hide();
          }
        }
      };

      new Vue({
        el: "#q-app",
        data: {},
        methods: {
          showDialog() {
            this.$q
              .dialog({
                component: CustomComponent,
                parent: this,
                text: "something"
              })
              .onOk(() => {
                console.log("OK");
              })
              .onCancel(() => {
                console.log("Cancel");
              })
              .onDismiss(() => {
                console.log("Called on OK or Cancel");
              });
          }
        }
      });
    </script>
  </body>
</html>

We add the CustomComponent component with the q-dialog component to add a dialog.

We have the show and hide methods to show and hide the dialog.

And we emit the hide event when we close the dialog to close it.

onOKClick emits the ok event to trigger the onOK callback.

Conclusion

We can add dialogs with various customizations with the Quasar library.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Dark Mode and Dialogs

Quasar is a popular Vue UI library for developing good looking Vue apps.

In this article, we’ll take a look at how to create Vue apps with the Quasar UI library.

Dark Mode

We can enable dark mode with the $q.dark.set method:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md"></div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        beforeMount() {
          this.$q.dark.set(true);
        }
      });
    </script>
  </body>
</html>

true will turn on dark mode and false will turn it off.

Dialog

We can add a dialog with the $q.dialog method:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md">
        <q-btn label="Confirm" color="primary" @click="confirm"></q-btn>
        <q-btn label="Prompt" color="primary" @click="prompt"></q-btn>
      </div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        methods: {
          confirm() {
            this.$q
              .dialog({
                title: "Confirm",
                message: "Would you like to turn on the wifi?",
                cancel: true,
                persistent: true
              })
              .onOk(() => {
                console.log("OK");
              })
              .onOk(() => {
                console.log("Second OK catcher");
              })
              .onCancel(() => {
                console.log("Cancel");
              })
              .onDismiss(() => {
                console.log("I am triggered on both OK and Cancel");
              });
          },

          prompt() {
            this.$q
              .dialog({
                title: "Prompt",
                message: "What is your name?",
                prompt: {
                  model: "",
                  type: "text"
                },
                cancel: true,
                persistent: true
              })
              .onOk((data) => {
                console.log("OK, received", data);
              })
              .onCancel(() => {
                console.log("Cancel");
              })
              .onDismiss(() => {
                console.log("I am triggered on both OK and Cancel");
              });
          }
        }
      });
    </script>
  </body>
</html>

The title property sets the title.

message sets the dialog message.

cancel adds a Cancel button when it’s set to true .

persistent makes the dialog persistent.

And we can watch the events emitted from the dialogs with the onOK , onCancel and onDismiss methods.

The prompt property lets us show an input with the prompt.

We get the data from the data parameter from the onOK callback with the prompt dialog.

We can set the dark property to true to enable dark mode.

Radio, Checkboxes, and Toggles

We can add dialogs that let users select options with radio buttons, checkboxes, and toggles.

To add them, we write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md">
        <q-btn label="Radio" color="primary" @click="radio"></q-btn>
        <q-btn label="Checkbox" color="primary" @click="checkbox"></q-btn>
        <q-btn label="Toggle" color="primary" @click="toggle"></q-btn>
      </div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        methods: {
          radio() {
            this.$q
              .dialog({
                title: "Options",
                message: "Choose an option:",
                options: {
                  type: "radio",
                  model: "opt1",
                  items: [
                    { label: "Option 1", value: "opt1", color: "secondary" },
                    { label: "Option 2", value: "opt2" },
                    { label: "Option 3", value: "opt3" }
                  ]
                },
                cancel: true,
                persistent: true
              })
              .onOk((data) => {
                console.log("OK, received", data);
              });
          },

          checkbox() {
            this.$q
              .dialog({
                title: "Options",
                message: "Choose your options:",
                options: {
                  type: "checkbox",
                  model: [],
                  items: [
                    { label: "Option 1", value: "opt1", color: "secondary" },
                    { label: "Option 2", value: "opt2" },
                    { label: "Option 3", value: "opt3" }
                  ]
                },
                cancel: true,
                persistent: true
              })
              .onOk((data) => {
                console.log("OK, received", data);
              });
          },

toggle() {
            this.$q
              .dialog({
                title: "Options",
                message: "Choose your options:",
                options: {
                  type: "toggle",
                  model: [],
                  items: [
                    { label: "Option 1", value: "opt1", color: "secondary" },
                    { label: "Option 2", value: "opt2" },
                    { label: "Option 3", value: "opt3" }
                  ]
                },
                cancel: true,
                persistent: true
              })
              .onOk((data) => {
                console.log("OK, received", data);
              });
          }
        }
      });
    </script>
  </body>
</html>

We just add the options.items property to add the options.

And we change the control type to show with the options.type property.

We get the selected item from the data parameter from the onOK callback.

Conclusion

We can add dark mode and dialogs with the Quasar library into our Vue app.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Full Screen and Cookies

Quasar is a popular Vue UI library for developing good looking Vue apps.

In this article, we’ll take a look at how to create Vue apps with the Quasar UI library.

Full-Screen Toggle

Quasar comes with code to let us toggle full-screen mode and check if we’re in full-screen mode.

To use it, we write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md">
        <q-btn
          color="secondary"
          @click="$q.fullscreen.toggle()"
          :icon="$q.fullscreen.isActive ? 'fullscreen_exit' : 'fullscreen'"
          :label="$q.fullscreen.isActive ? 'Exit Fullscreen' : 'Go Fullscreen'"
        >
        </q-btn>
      </div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We call $q.fullscreen.toggle() to toggle full-screen mode.

Then we $q.fullscreen.isActive property indicates whether we’re in full-screen mode.

App Visibility

We can watch for app visibility with the $q.appVisible property:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md"></div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        watch: {
          "$q.appVisible"(val) {
            console.log(
              val ? "App became visible" : "App went in the background"
            );
          }
        }
      });
    </script>
  </body>
</html>

Bottom Sheet

We can add a bottom sheet with Quasar’s $q.bottomSheet method.

To add it, we write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md">
        <q-btn
          no-caps
          push
          color="primary"
          label="List BottomSheet"
          @click="show()"
        ></q-btn>
        <q-btn
          no-caps
          push
          color="white"
          text-color="primary"
          label="Grid BottomSheet"
          @click="show(true)"
        ></q-btn>
      </div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        methods: {
          show(grid) {
            this.$q
              .bottomSheet({
                message: "Bottom Sheet message",
                grid,
                actions: [
                  {
                    label: "Drive",
                    img: "https://cdn.quasar.dev/img/logo_drive_128px.png",
                    id: "drive"
                  },
                  {
                    label: "Keep",
                    img: "https://cdn.quasar.dev/img/logo_keep_128px.png",
                    id: "keep"
                  },
                  {
                    label: "Google Hangouts",
                    img: "https://cdn.quasar.dev/img/logo_hangouts_128px.png",
                    id: "calendar"
                  },
                  {},
                  {
                    label: "John",
                    avatar: "https://cdn.quasar.dev/img/boy-avatar.png",
                    id: "john"
                  }
                ]
              })
              .onOk((action) => {
                console.log("Action chosen:", action.id);
              })
              .onCancel(() => {
                console.log("Dismissed");
              })
              .onDismiss(() => {
                console.log("I am triggered on both OK and Cancel");
              });
          }
        }
      });
    </script>
  </body>
</html>

We call bottomSheet with an array of objects to add the items to the bottom sheet.

label has the text of each item. img has the image for each item.

Then we can watch various events with the onOk , onCancel and onDismiss methods to watch item click and closing the bottom sheet.

Cookies

We can get and set cookies with the $q.cookies property.

For example, we can write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md"></div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        beforeMount() {
          this.$q.cookies.set("cookie_name", "foo", {
            expires: 10,
            secure: true
          });
          console.log(this.$q.cookies.getAll());
        }
      });
    </script>
  </body>
</html>

We call set with the key, value, and options respectively.

expires has the expiration time in seconds.

secure makes sure the cookie is set on HTTPS connections only.

Other cookie options like path , domain , sameSite , httpOnly , etc. are supported.

And we get all the cookies with the getAll method.

Conclusion

We can toggle full screen and get and set cookies with Quasar’s built in plugins.