Context menu in treeList



  • Hello I was tryng to add a context menu with the TreeList so i can show some options to the user. The problem is that i don’t know how to get the right click source element.

    Is there a way to expose the child element that the context menu was opened above?



  • If the quasar handler does not receive an event, while we wait for @rstoenescu to fix that ;.) … try using this directly to get an event object for your right-click
    https://stackoverflow.com/questions/36622923/vue-js-right-click-event-directive

    and once you get an event e it’s just a matter of sourceElement = e.target



  • THANK YOU VERY MUCH!!!

    @spectrolite, by implementing what you suggested, everything worked and in a very clean way.
    Also, fortunatelly my IOT esp8266 device happly loaded very fast a Quasar page in such small device.
    Its very difficult to me as an electronic engineering student to understand how everything works (Nodejs/NPM + Quasar + ESLint + ES6 + Babel + NWJS), the web world is so huge nowaday, so I will try to explain well what I did to get Tree + Context menu.

    • Created a DIV and put Tree element and de context menu as its child. Also added the context menu handler:
    <div @contextmenu="rightClickHandler($event)">
    
    • Next, I poppulated Tree model data with the same as seen in quasar docs.

    • In the context menu tag I put a :V-SHOW property linked to a variable named enableContextMenu :

    <q-context-menu v-show="enableContextMenu" ref="context">
    
    • Inside context menu, I put an item that its label is linked to the posterior Tree element that is clicked:
    <q-item>
        <q-item-main :label="itemName"/>
    </q-item>
    
    • In the end, the right click event handler is implemented so when the clicked element have a <SPAN> tagName, the handler selects its innerHTML (element name) and enables the context menu to be shown by the enableContextMenu variable:
    methods: {
         rightClickHandler: function(e) {
            e.preventDefault();
            if(e.target.tagName == 'SPAN')
            {
            this.itemName = e.target.innerHTML;
            this.enableContextMenu=true;
            }
             else
             {
                 this.enableContextMenu=false;             
             }
         }
      }
    

    Here’s the complete code

    <template>
      <q-layout
        ref="layout"
        view="lHh Lpr fff"
        :left-class="{'bg-grey-2': true}"
      >
        <q-toolbar slot="header" class="flat">
          <q-toolbar-title>
            Quasar App
            <div slot="subtitle">Running on Quasar v{{$q.version}}</div>
          </q-toolbar-title>
        </q-toolbar>
    
          <div @contextmenu="rightClickHandler($event)">
           <q-tree
            :model="treeModel"
            contract-html="<i class='material-icons'>remove_circle</i>"
            expand-html="<i class='material-icons'>add_circle</i>"
          />
              <q-context-menu v-show="enableContextMenu" ref="context">
              <q-list link separator no-border style="min-width: 150px; max-height: 300px;"
              @click="$refs.context.close()">
                <q-item>
                  <q-item-main :label="itemName"/>
                </q-item>
              </q-list>
            </q-context-menu>
          </div>
      </q-layout>
    </template>
    
    <script>
    import {
      dom,
      event,
      openURL,
      QLayout,
      QToolbar,
      Toast,
      QContextMenu,
      QToolbarTitle,
      QTree,
      QBtn,
      QIcon,
      QList,
      QListHeader,
      QItem,
      QItemSide,
      QItemMain
    } from 'quasar'
    
    
    export default {
      name: 'index',
      components: {
        QLayout,
        QTree,
        QToolbar,
        QContextMenu,
        QToolbarTitle,
        QBtn,
        QIcon,
        QList,
        QListHeader,
        QItem,
        QItemSide,
        QItemMain
      },
      data () {
        return {
            enableContextMenu:false,
            itemName: "",
            treeModel: [
            {
              title: 'Item 1',
              expanded: true,
              icon: 'alarm',
              children: [
                {
                  title: 'Item 1.1',
                  expanded: false,
                  children: [
                    {
                      title: 'Item 1.1.1',
                      expanded: false,
                      children: [
                        {
                          title: 'Item 1.1.1.1',
                          expanded: false,
                          children: []
                        }
                      ]
                    },
                    {
                      title: 'Item 1.1.2',
                      expanded: false,
                      children: []
                    }
                  ]
                },
                {
                  title: 'Item 1.2',
                  expanded: false,
                  children: []
                },
                {
                  title: 'Item 1.3',
                  expanded: false,
                  handler () {
                    Toast.create('Tapped on item 1.3')
                  },
                  children: []
                }
              ]
            },
            {
              title: 'Item 2',
              expanded: false,
              children: [
                {
                  title: 'Item 2.1',
                  expanded: false,
                  children: [
                    {
                      title: 'Item 2.1.1',
                      expanded: false,
                      children: []
                    },
                    {
                      title: 'Item 2.1.2',
                      expanded: false,
                      children: [
                        {
                          title: 'Item 2.1.2.1',
                          expanded: false,
                          children: []
                        },
                        {
                          title: 'Item 2.1.2.2',
                          expanded: false,
                          children: []
                        }
                      ]
                    }
                  ]
                },
                {
                  title: 'Item 2.2',
                  expanded: false,
                  children: []
                },
                {
                  title: 'Item 2.3',
                  expanded: false,
                  children: []
                }
              ]
            }
          ]
        }
      },
      methods: {
         rightClickHandler: function(e) {
            e.preventDefault();
            if(e.target.tagName == 'SPAN')
            {
            this.itemName = e.target.innerHTML;
            this.enableContextMenu=true;
            }
             else
             {
                 this.enableContextMenu=false;             
             }
         }
      }
    }
    </script>
    
    


  • Off topic, but @mendesgeo you use Quasar to build an interface for an ESP8266? That sound like a cool project, love to hear more about it :D



  • @mendesgeo You are very welcome. And thank you very much for sharing the details of your success, it is so very rare, and so much useful to the community.

    I also have to agree with @a47ae : you running quasar in a esp8266 is way cool. I’d love to see a picture of that device!
    I will finally shamelessly plug my favorite forum topic here and ask you to consider posting in it once you feel ready to share some more info on your project: http://forum.quasar-framework.org/topic/498/quasar-live-apps



  • @a47ae and @spectrolite thanks for tour reply. I’m glad that you guys seems surprised with quasar in esp8266. For now i just runned the default quasar sample page in esp8266. I just had to modify some webpack configuration so the bundled files name are kept with a shortname that esp8266 can handle in its file system.

    Soon i will post the project so everyone can try it out in a esp8266 device.

    PS: I’m studing webpack so i can see if its possible to generate a single file only in production build. It would decrease a lot more esp8266 requests when loading a page.



  • Maybe you don’t have to study webpack that much.
    If what you want is to not have your pages chunked in separate files, there’s an easy in-code solution (no webpack messing about).
    http://beta.quasar-framework.org/guide/routes-lazy-loading.html#Avoiding-lazy-loading
    This would net you only 2 js chunks (vendor and app), one css, and one HTML.



  • At that point it should be quite easy to modify the standard quasar webpack configuration to get only one js chunk.
    Reuniting the css and js into the HTML… that I have no idea about, but 1. there’s probably help out there for that specific task and 2. it’s probably an over-kill

    Inlining a few svg or small png files would probably give more measurable results, if you’re trying to minimize server calls.



  • @spectrolite Thank you again, by doing so and increasing the default maximum size of fonts files, the loader inlined everything.



  • I would maybe strip out Roboto as font and rely on a system font stack to minimize the bundle size even further.

    Also, I have to check out your sample, I will probably just hook up an LED and play all day with the knob component and toggle component to change the led and be fascinated by it. :D



  • @a47ae First of all: LOL, I think I would too.
    About Stripping Roboto, imho it would be a shame to cripple the looks of the UI, and the objective was reducing requests to the server, not optimizing bandwidth usage or app total size.

    the loader inlined everything.

    means mission accomplished at this point.



  • @spectrolite @a47ae yes, indeed all I need is to reduce the number of requests. Everything seems OK now. Soon I will upload the project with the github link. Thank for all your help. Tested quasar on NWJS too, it has shown to be very responsive.
    Hehehe, seem like I’m using cheating now that I can make interactive user interfaces for my electronic projects, most electronic enginners don’t bother making a beautiful interface and stick to initially ugly non webs interfaces like C# WinFoms, Qt, etc. The future is Web and NodeJS. :thumbsup:


Log in to reply
 

Looks like your connection to Quasar Framework was lost, please wait while we try to reconnect.