Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I successfully *remotely* fire an event to open a right context menu? #23

Open
DAMisener opened this issue Sep 25, 2019 · 0 comments

Comments

@DAMisener
Copy link

Background:

  • I have an VIS-Timeline component and want to establish a right-click context menu for each
    embedded timeline item.
    • The items are programmatically rendered by VIS but the HTML label content for each
      item are supplied via a template: callback function.
    • I inject a Vue component with vue-menu constructed context menu via this
      callback.
    • If I right click the label the context menu does appear.
  • Unfortunately the label text is a small click-target. It would be
    desirable to be able to right-click anywhere within the containing item
    bar.

My current attempt:

  • I have used the VIS-timeline Timeline.on(...) handler to catch
    right-click (contextmenu events) and forward them to the HTML
    wrapping
    the vue-menu click handler (the same one I right-click manually to bring up
    the context menu). See code snippet below
  • When I uncomment the console output code and right click the label text and then
    right-click the containing event bar... I see a successful redirection.
    • the original event on the containing element
    • then the redirected even to the vue-menu decorated div
  • Sadly the context menu doesn't open.

Any suggestions would be appreciated.

Testing Harness Code:

  // Template generation using mock multi-level context-menu
  // - note *item.content* contains the item label text 
  //   (Sue Simmons in this example).

  const ItemEntry = Vue.extend({
    template: `
        <hsc-menu-style-white>
          <hsc-menu-button-menu ref="itemContextMenu" 
            style="z-index:2; position:relative;" 
            @contextmenu.native.prevent>

            <div> {{item.content}} </div>

            <template slot="contextmenu">
              <hsc-menu-item label="MenuItem 1">
                <hsc-menu-item label="MenuItem 1a" @click.native="processMenu('1a')"/>
                <hsc-menu-item label="MenuItem 1b" @click.native="processMenu('1b')"/>
              </hsc-menu-item>
              <hsc-menu-item label="MenuItem 2" @click.native="processMenu('2')" />
              <hsc-menu-item label="MenuItem 3">
                <hsc-menu-item label="MenuItem 3a" @click.native="processMenu('3a')"/>
                <hsc-menu-item label="MenuItem 3b" @click.native="processMenu('3b')"/>
              </hsc-menu-item>
            </template>
          </hsc-menu-button-menu>
        </hsc-menu-style-white>`,

    methods: {
      processMenu(label){
        alert('ProcessItemMenu: '+label);
        // See: https://github.com/michitaro/vue-menu/issues/21
        this.$refs.itemContextMenu.$refs.menu.close(true);
      }
    },

    props: ['item'],
  });

  ...

  // Remotely fire the contextmenu event

  this.timeline.on('contextmenu', (props) => {

    # Simplified search for approriate vue-menu div
    var findNode = function(start, regexp){
      node = start;
      while (true){
        var html = node.outerHTML;
        if (html == undefined){
          node = undefined;
          break;
        } else {
          if (html.match(regexp)) break;
        };
        node = node.firstChild;
        if (node == undefined) break;
      };
      return node;
    };

    // if (window.$$debugger) debugger;
    // console.log('ContextMenu:',event);
    // Sue Simmon is the exemplar rendered label -- see above
    if (event.target.outerHTML.match(/^<div> Sue Simmons <\/div>$/)){
      // Record original event which does fire
      window.$$saveEvent = new MouseEvent(event.type, event);
    } else {
      var newEvent = new MouseEvent(event.type, event);
      // Use working right-click event (NOTE: *isTrusted* field can't be set to true)
      if (window.$$saveEvent) newEvent = window.$$saveEvent;
      var node = findNode(event.target, /^<div> Sue Simmons <\/div>$/);
      if (node) node.dispatchEvent(newEvent);
    }
    props.event.preventDefault();
  });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant