cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
Highlighted
Helper I
Helper I

jquery-contextmenu in custom visual

Hi,

 

After loading jquery-contextmenu using:

npm i jquery-contextmenu
npm i @types/jquery.contextmenu

and adding the javascript using:

this.contextmenuScript = d3.select(this.element).append('script');
this.contextmenuScript.attr({
	type: 'text/javascript',
	class: 'showcase'
});
this.contextmenuScript.text("$(function() { $.contextMenu({ selector: '.context-menu-one', callback: function(key, options) { var m      ...

I get the following error: 'VM3309:1 Uncaught TypeError: $.contextMenu is not a function'.

 

Do I need to import the javascript explicitly? If so, how?

What is the correct way to add the context menu code above?

 

I am using PBIVIZ v3.1.2 / ES6.

 

Github

Working example in JSFiddle.

 

 

Thanks for any help.

Martijn

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Highlighted
Super User II
Super User II

Hi there,

In your linked snippet, you have the following, which loads the JS libraries of interest:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://swisnl.github.io/jQuery-contextMenu/dist/jquery.contextMenu.js" type="text/javascript"></script>

Using npm to import packages sets them up as a dependency, but does not load them; you have to do something similar in your code when/where you want to make use of them.

If you're using ES6, then have a look at how ES6 imports work. You will see similar statements at the top of your visual.ts for the standard stuff the visual is loading in, e.g.:

import '@babel/polyfill';
import './../style/visual.less';
import powerbi from 'powerbi-visuals-api';
import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions;
import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions;
...

The bottom two are extensions of the third line, but one that dependency has been imported then it can be referenced to specify others as simpler variables.

There's instructions on how to include jQuery in your project on jQuery's NPM site. The section you want will be under Babel (notice that import '@babel/polyfill' above?), specifically:

Babel is a next generation JavaScript compiler. One of the features is the ability to use ES6/ES2015 modules now, even though browsers do not yet support this feature natively.

import $ from "jquery";

You can then access $ as an object in your visual.ts.

I'd recommend changing this slightly, as if you install the typings for jQuery (npm i @types/jquery) then it doesn't like $ as a reference (the module exports a variable named jQuery rather than $), and it's generally advisable to use the following:

import * as jQuery from 'jquery';
import 'jquery-contextmenu';

...and then referring to jQuery rather than $ in your code, e.g.:

jQuery(function () {
    jQuery.contextMenu({
        ...
    })
});

I've walked this through and the libraries load (and have tested that jQuery.contextMenu exists), so you will no longer get the errors you were getting. However, I don't really use this library, so can't advise further on how you'll use it in your visual, but hopefully this will help you a bit.

Of note, the API supports a context menu as well, so you could also try this (personally haven't used it yet).

Good luck!

Daniel





Did I answer your question? Mark my post as a solution!

Proud to be a Super User!




View solution in original post

3 REPLIES 3
Highlighted
Super User II
Super User II

Hi there,

In your linked snippet, you have the following, which loads the JS libraries of interest:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://swisnl.github.io/jQuery-contextMenu/dist/jquery.contextMenu.js" type="text/javascript"></script>

Using npm to import packages sets them up as a dependency, but does not load them; you have to do something similar in your code when/where you want to make use of them.

If you're using ES6, then have a look at how ES6 imports work. You will see similar statements at the top of your visual.ts for the standard stuff the visual is loading in, e.g.:

import '@babel/polyfill';
import './../style/visual.less';
import powerbi from 'powerbi-visuals-api';
import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions;
import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions;
...

The bottom two are extensions of the third line, but one that dependency has been imported then it can be referenced to specify others as simpler variables.

There's instructions on how to include jQuery in your project on jQuery's NPM site. The section you want will be under Babel (notice that import '@babel/polyfill' above?), specifically:

Babel is a next generation JavaScript compiler. One of the features is the ability to use ES6/ES2015 modules now, even though browsers do not yet support this feature natively.

import $ from "jquery";

You can then access $ as an object in your visual.ts.

I'd recommend changing this slightly, as if you install the typings for jQuery (npm i @types/jquery) then it doesn't like $ as a reference (the module exports a variable named jQuery rather than $), and it's generally advisable to use the following:

import * as jQuery from 'jquery';
import 'jquery-contextmenu';

...and then referring to jQuery rather than $ in your code, e.g.:

jQuery(function () {
    jQuery.contextMenu({
        ...
    })
});

I've walked this through and the libraries load (and have tested that jQuery.contextMenu exists), so you will no longer get the errors you were getting. However, I don't really use this library, so can't advise further on how you'll use it in your visual, but hopefully this will help you a bit.

Of note, the API supports a context menu as well, so you could also try this (personally haven't used it yet).

Good luck!

Daniel





Did I answer your question? Mark my post as a solution!

Proud to be a Super User!




View solution in original post

Highlighted

Hi @dm-p ,

 

That works! The import statement indeed did the trick:

import 'jquery-contextmenu';

In addition I had to add the corresponding stylesheet using:

import "./../node_modules/jquery-contextmenu/dist/jquery.contextMenu.css";

And I agree, using jQuery is much more elegant than using $:

jQuery(function () {
    jQuery.contextMenu({
        ...
    })
});

Thanks again, very much appreciated!

Martijn

 

 

 

Highlighted

Sweet! Glad you're unblocked 🙂





Did I answer your question? Mark my post as a solution!

Proud to be a Super User!




Helpful resources

Announcements
Community Conference

Power Platform Community Conference

Check out the on demand sessions that are available now!

Community Conference

Microsoft Power Platform Communities

Check out the Winners!

secondImage

Create an end-to-end data and analytics solution

Learn how Power BI works with the latest Azure data and analytics innovations at the digital event with Microsoft CEO Satya Nadella.

Top Solution Authors
Top Kudoed Authors