Categories
Quasar

Developing Vue Apps with the Quasar Library — Accordion Tree, Filter, and Selection

Spread the love

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.

Accordion Tree Mode

We can show the tree view as an accordion with the accordion prop:

<!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">
      <q-tree
        :nodes="data"
        node-key="label"
        selected-color="primary"
        :selected.sync="selected"
        default-expand-all
        accordion
      >
      </q-tree>
    </div>
    <script>
      const data = [
        {
          label: "Hotel",
          children: [
            {
              label: "Food",
              icon: "restaurant_menu"
            },
            {
              label: "Room service",
              icon: "room_service"
            },
            {
              label: "Room view",
              icon: "photo"
            }
          ]
        }
      ];

      new Vue({
        el: "#q-app",
        data: {
          data,
          splitterModel: 50,
          selected: "Food"
        }
      });
    </script>
  </body>
</html>

Filter Tree Nodes

We can add a filter to let users search for tree nodes.

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">
      <q-input ref="filter" filled v-model="filter" label="Filter">
        <template v-slot:append>
          <q-icon
            v-if="filter !== ''"
            name="clear"
            class="cursor-pointer"
            @click="resetFilter"
          >
          </q-icon>
        </template>
      </q-input>

      <q-tree
        :nodes="data"
        node-key="label"
        :filter="filter"
        default-expand-all
      >
      </q-tree>
    </div>
    <script>
      const data = [
        {
          label: "Hotel",
          children: [
            {
              label: "Food",
              icon: "restaurant_menu"
            },
            {
              label: "Room service",
              icon: "room_service"
            },
            {
              label: "Room view",
              icon: "photo"
            }
          ]
        }
      ];

      new Vue({
        el: "#q-app",
        data: {
          data,
          filter: ""
        },
        methods: {
          resetFilter() {
            this.filter = "";
            this.$refs.filter.focus();
          }
        }
      });
    </script>
  </body>
</html>

We add a q-input that’s bound to the filter reactive property.

Then we pass in the filter reactive property as the value of filter prop of the q-tree component.

This will let us search for nodes as we type into the input box.

Selectable Nodes

We can set nodes as selected by setting the reactive property bound to the q-tree as the value.

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>
        <div class="q-gutter-sm">
          <q-btn
            size="sm"
            color="primary"
            @click="selectRoomService"
            label="Select Room service"
          >
          </q-btn>
          <q-btn
            v-if="selected"
            size="sm"
            color="red"
            @click="unselectNode"
            label="Unselect node"
          >
          </q-btn>
        </div>
      </div>

      <q-tree
        :nodes="data"
        default-expand-all
        :selected.sync="selected"
        node-key="label"
      >
      </q-tree>
    </div>
    <script>
      const data = [
        {
          label: "Hotel",
          children: [
            {
              label: "Food",
              icon: "restaurant_menu"
            },
            {
              label: "Room service",
              icon: "room_service"
            },
            {
              label: "Room view",
              icon: "photo"
            }
          ]
        }
      ];

      new Vue({
        el: "#q-app",
        data: {
          data,
          selected: ""
        },
        methods: {
          selectRoomService() {
            if (this.selected !== "Room service") {
              this.selected = "Room service";
            }
          },
          unselectNode() {
            this.selected = null;
          }
        }
      });
    </script>
  </body>
</html>

In the selectRoomService method, we set this.selected to 'Room service' .

And since this.selected is bound to q-tree with v-model , the node will be selected.

And if we set it to null as we did in unselectNode , the node will be unselected.

Conclusion

We can customize Quasar’s tree component and add filter and selection features to it.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *