# How to Display a Vuetify Combobox Across All Pages but Load Data on Specific Pages?

**URL:** <https://discourse.nodered.org/t/how-to-display-a-vuetify-combobox-across-all-pages-but-load-data-on-specific-pages/94753>\
**Category:** General\
**Tags:** dashboard-2\
**Created:** [20 January 2025 07:47 UTC](https://discourse.nodered.org/t/how-to-display-a-vuetify-combobox-across-all-pages-but-load-data-on-specific-pages/94753 "2025-01-20T07:47:56Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nandhini-Subramaniya](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nandhini-subramaniya/32/92882_2.png) [@Nandhini-Subramaniya](https://discourse.nodered.org/u/Nandhini-Subramaniya)\
**Post date:** [20 January 2025 07:47 UTC](https://discourse.nodered.org/t/how-to-display-a-vuetify-combobox-across-all-pages-but-load-data-on-specific-pages/94753/1 "2025-01-20T07:47:56Z")

</div>

Hi everyone,

I'm working on a Vue.js project using Vuetify, and I have a `v-combobox` that I want to display on all pages in my application. However, I only want to load and render the data for the combobox on specific pages where it's needed.

Here's a simplified version of my template:

```auto
<template>
  <div>
    <div class="msg">
      <Teleport v-if="mounted" to="#app-bar-title">
        <div style="order: 2;">
          <div style="display: flex; justify-content: center;">
            <v-combobox 
              label="Topology" 
              :items="topologies.map(topology => topology.name)"
              variant="outlined" 
              style="width: 300px; height: 50px; margin-top: 60px; border-radius: 25px 25px 0 0;"
              prepend-inner-icon="mdi-magnify" 
              v-model="selectedTopology"
            ></v-combobox>
          </div>
        </div>
      </Teleport>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      mounted: false,
      topologies: [],
      selectedTopology: null,
    };
  },
  mounted() {
    this.mounted = true;
    // Logic to load data for specific pages
  },
};
</script>

```

and my flows given below

```auto
[
    {
        "id": "bbe5b8ba69b9e209",
        "type": "function",
        "z": "472eadd660afe821",
        "name": "function 14",
        "func": "const getTopologies = global.get('getTopologies'); // Retrieve the function\nif (!getTopologies) {\n node.error(\"getTopologies function not found in global context\");\n return null;\n}\n\n// Define an async wrapper function to handle the async call\n(async () => {\n try {\n // Call the getTopologies function\n const topologies = await getTopologies();\n console.log(\"Topologies data:\", topologies);\nnode.log(\"----------------->Path: \" + msg.payload.page.path);\n\n // Attach the topologies data to the message\n msg.payload = topologies;\n\n // Send the updated message\n node.send(msg);\n } catch (err) {\n // Handle any errors\n node.error(\"Error fetching topologies: \" + err.message);\n }\n})();\n\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 330,
        "y": 200,
        "wires": [
            [
                "2ccf9075586b5fa9"
            ]
        ]
    },
    {
        "id": "bdeb805bf2151fa6",
        "type": "debug",
        "z": "472eadd660afe821",
        "name": "debug 2585",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 670,
        "y": 200,
        "wires": []
    },
    {
        "id": "2ccf9075586b5fa9",
        "type": "ui-template",
        "z": "472eadd660afe821",
        "group": "",
        "page": "dc3b0354cb683966",
        "ui": "",
        "name": "topo_trial",
        "order": 1,
        "width": "10",
        "height": "6",
        "head": "",
        "format": "<template>\n <div>\n <div class=\"msg\">\n <Teleport v-if=\"mounted\" to=\"#app-bar-title\">\n <div style=\"order: 2;\">\n <div style=\"display: flex; justify-content: center;\">\n \n <v-combobox label=\"Topology\" :items=\"topologies.map(topology => topology.name)\"\n variant=\"outlined\" style=\"width: 300px; height: 50px; margin-top: 60px; border-radius: 25px 25px 0 0;\"\n prepend-inner-icon=\"mdi-magnify\" v-model=\"selectedTopology\"\n ></v-combobox>\n \n </div>\n \n \n </div>\n \n </Teleport>\n\n <div id=\"topology-container\"></div>\n </div>\n <link rel=\"alternate icon\" href=\"./favicon.ico\" type=\"image/png\" sizes=\"16x16\">\n <link rel=\"stylesheet\" href=\"./assets/nextjs/next.css\">\n </div>\n\n <!-- context menu -->\n <v-menu v-model=\"contextMenuVisible\" :style=\"{ left: `${menuX}px`, top: `${menuY}px`, position: 'absolute' }\">\n <v-list>\n <v-list-item v-for=\"(list, i) in lists\" :key=\"i\" @click=\"handleMenuClick(list.title)\">\n <v-list-item-title>{{ list.title }}</v-list-item-title>\n </v-list-item>\n </v-list>\n </v-menu>\n</template>\n\n<script src=\"./assets/nextjs/next.js\"></script>\n<script>\n export default {\n data() {\n return {\n mounted: false,\n topologies: [], // Array of topology objects\n selectedTopology: null,\n topologyApp: null,\n topologyInstance: null,\n value:[],\n labelText: \"\",\n dialogTitle: \"\",\n contextMenuVisible: false,\n menuX: 0,\n menuY: 0,\n lists: [\n { title: 'Item1' },\n { title: 'Item2' },\n],\n };\n },\n watch: {\n selectedTopology(newValue) {\n console.log('Selected topology changed:', newValue);\n this.onTopologyChange(newValue);\n },\n },\n mounted() {\n this.mounted = true;\n // Listen for incoming messages to populate topologies\n this.$watch('msg.payload', (newPayload) => {\n if (Array.isArray(newPayload)) {\n this.topologies = newPayload;\n console.log(\"Topologies updated:\", this.topologies);\n }\n });\n document.addEventListener('contextmenu', (event) => {\n event.preventDefault();\n console.log(\"Click detected on:\", event.target);\n if (event.target.closest('.node')) {\n const node = event.target.closest('.node');\n const dataId = node.getAttribute('data-id');\n const labelElement = node.querySelector('.node-label');\n this.labelText = labelElement ? labelElement.textContent || labelElement.innerText : 'No label';\n \n // Store the position of the right-click\n this.menuX = event.clientX ;\n this.menuY = event.clientY ;\n \n // Open the context menu\n this.contextMenuVisible = true;\n console.log(\"Context menu should be visible now\");\n console.log(\"Position:\", this.menuX, this.menuY);\n \n console.log(\"Node data-id:\", dataId);\n console.log(\"Node label:\", this.labelText);\n }\n else {\n this.contextMenuVisible = false; // Hide the menu if not clicking on a node\n }\n });\n },\n methods: {\n selectTopology(topology) {\n console.log(\"Selected topology:\", this.selectedTopology);\n this.selectedTopology = topology.name;\n this.changeTopology(topology.data);\n },\n onTopologyChange(selected) {\n console.log(\"Topology selected in combobox:\", selected); // Added log\n const topology = this.topologies.find(topology => topology.name === selected);\n if (topology) {\n console.log(\"Topology found:\", topology); // Added log\n this.selectTopology(topology);\n }else {\n console.error(\"Selected topology not found in list\"); // Added log\n }\n },\n initializeTopology(topologyData) {\n console.log(\"Initializing topology:\", topologyData);\n\n if (!this.topologyApp) {\n const app = new nx.ui.Application();\n const topologyConfig = {\n width: window.innerWidth,\n height: window.innerHeight,\n nodeConfig: {\n label: \"model.name\",\n iconType: \"model.device_type\",\n color: \"model.color\",\n },\n linkConfig: {\n linkType: \"straight\",\n color: \"model.color\",\n },\n showIcon: true,\n };\n\n const topology = new nx.graphic.Topology(topologyConfig);\n topology.attach(app);\n app.container(document.getElementById(\"topology-container\"));\n // Attach the app to the element with class 'nrdb-layout-overlay'\n const parentElement = document.querySelector('#topology-container');\n console.log(\"Parent element:\", parentElement);\n const container = parentElement?.querySelector('.nrdb-layout-group--grid');\n console.log(\"Container element:\", container);\n const topo = document.querySelector('.n-topology-blue');\n if (topo) {\n parentElement.appendChild(topo);\n }\n this.topologyApp = app;\n this.topologyInstance = topology;\n\n // // Adding event listeners for expand/collapse\n // topology.on('expandAll', this.expandAllNodes);\n // topology.on('collapseAll', this.collapseAllNodes);\n }\n\n this.topologyInstance.data(topologyData);\n },\n // expandAllNodes() {\n // this.topologyInstance.expandAll(); // Ensure this method is defined in your topology library\n // },\n // collapseAllNodes() {\n // this.topologyInstance.collapseAll(); // Ensure this method is defined in your topology library\n // },\n changeTopology(topologyData) {\n console.log(\"Changing topology to:\", topologyData);\n\n if (this.topologyInstance) {\n console.log(\"Updating existing topology instance\"); // Added log\n this.topologyInstance.data(topologyData);\n } else {\n console.log(\"Topology instance not found, initializing new topology\"); // Added log\n this.initializeTopology(topologyData);\n }\n },\n },\n unmounted() {\n if (this.topologyApp) {\n this.topologyApp.destroy();\n }\n },\n};\n</script>\n\n<style>\n #topology-container {\n width: 100%;\n height: 100%;\n /* background-color: #f0f0f0; */\n overflow: hidden;\n }\n\n body {\n background-color: white;\n }\n\n .v-application__wrap {\n min-height: unset !important;\n }\n\n #app-bar-title {\n overflow: visible;\n position: relative;\n /* display:block; */\n /* z-index: 1000; */\n \n }\n\n /* v-combobox {\n display: block !important; \n } */\n\n .v-menu {\n position: absolute !important;\n z-index: 9999;\n }\n \n\n.bg-primary {\n background-color: #795548 !important;\n color: white !important;\n}\n/* .v-btn {\n height: 48px;\n margin-top: 60px;\n} */\n</style>\n\n\n",
        "storeOutMessages": true,
        "passthru": true,
        "resendOnRefresh": true,
        "templateScope": "widget:page",
        "className": "nextjs",
        "x": 500,
        "y": 200,
        "wires": [
            [
                "bdeb805bf2151fa6"
            ]
        ]
    },
    {
        "id": "8ce6855e818820d5",
        "type": "ui-event",
        "z": "472eadd660afe821",
        "ui": "64fc71361e24a0d0",
        "name": "",
        "x": 50,
        "y": 200,
        "wires": [
            [
                "072452c884b36f30"
            ]
        ]
    },
    {
        "id": "072452c884b36f30",
        "type": "switch",
        "z": "472eadd660afe821",
        "name": "",
        "property": "payload.page.path",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "/topology",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 170,
        "y": 200,
        "wires": [
            [
                "bbe5b8ba69b9e209"
            ]
        ]
    },
    {
        "id": "dc3b0354cb683966",
        "type": "ui-page",
        "name": "topology",
        "ui": "64fc71361e24a0d0",
        "path": "/topology",
        "icon": "home",
        "layout": "grid",
        "theme": "",
        "breakpoints": [
            {
                "name": "Default",
                "px": "0",
                "cols": "3"
            },
            {
                "name": "Tablet",
                "px": "576",
                "cols": "6"
            },
            {
                "name": "Small Desktop",
                "px": "768",
                "cols": "9"
            },
            {
                "name": "Desktop",
                "px": "1024",
                "cols": "12"
            }
        ],
        "order": 1,
        "className": "",
        "visible": "true",
        "disabled": "false"
    },
    {
        "id": "64fc71361e24a0d0",
        "type": "ui-base",
        "name": "",
        "path": "/dashboard",
        "appIcon": "",
        "includeClientData": true,
        "acceptsClientConfig": [
            "ui-iframe",
            "ui-control",
            "ui-template",
            "ui-gauge",
            "ui-chart",
            "ui-slider",
            "ui-text-input",
            "ui-number-input",
            "ui-file-input",
            "ui-button",
            "ui-button-group",
            "ui-dropdown",
            "ui-radio-group",
            "ui-switch",
            "ui-text",
            "ui-chart",
            "ui-number-input",
            "ui-switch",
            "ui-table",
            "ui-gauge",
            "ui-markdown",
            "ui-iframe",
            "ui-tabulator",
            "ui-radio-group",
            "ui-dropdown",
            "ui-button-group",
            "ui-file-input",
            "ui-form"
        ],
        "showPathInSidebar": false,
        "showPageTitle": false,
        "navigationStyle": "icon",
        "titleBarStyle": "fixed"
    }
]

```

I want the combobox to be part of the navigation bar, so it's visible on all pages, but the `topologies` data should only be loaded and rendered when a specific set of pages is visited.

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/5/3/53de0ac6e219a3e9af33a4b53e939ac971d815ea.png)

Could anyone advise on the best way to achieve this? Is there a pattern or approach in Vue.js or Vuetify that facilitates this type of behavior?

Thanks in advance for your help!

---

<div class="post-metadata">

**Author:** ![joepavitt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/joepavitt/32/59722_2.png) [@joepavitt](https://discourse.nodered.org/u/joepavitt)\
**Post date:** [20 January 2025 09:41 UTC](https://discourse.nodered.org/t/how-to-display-a-vuetify-combobox-across-all-pages-but-load-data-on-specific-pages/94753/2 "2025-01-20T09:41:02Z")

</div>

> [@Nandhini-Subramaniya](#):
>
> Could anyone advise on the best way to achieve this? Is there a pattern or approach in Vue.js or Vuetify that facilitates this type of behavior?

Architecturally speaking, I think you've nailed it. I don't have a chance to dive into your flow at the moment, but using:

UI Event \> Switch \> Template (with a Teleport)

would be exactly how I'd achieve this.

---

<div class="post-metadata">

**Author:** ![Nandhini-Subramaniya](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nandhini-subramaniya/32/92882_2.png) [@Nandhini-Subramaniya](https://discourse.nodered.org/u/Nandhini-Subramaniya)\
**Post date:** [20 January 2025 11:02 UTC](https://discourse.nodered.org/t/how-to-display-a-vuetify-combobox-across-all-pages-but-load-data-on-specific-pages/94753/3 "2025-01-20T11:02:37Z")

</div>

sorry i m not get it.can you please guide me .

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [20 April 2025 11:03 UTC](https://discourse.nodered.org/t/how-to-display-a-vuetify-combobox-across-all-pages-but-load-data-on-specific-pages/94753/4 "2025-04-20T11:03:21Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
