cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
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
Super User I
Super User I

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!


My course: Introduction to Developing Power BI Visuals


On how to ask a technical question, if you really want an answer (courtesy of SQLBI)




View solution in original post

3 REPLIES 3
Super User I
Super User I

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!


My course: Introduction to Developing Power BI Visuals


On how to ask a technical question, if you really want an answer (courtesy of SQLBI)




View solution in original post

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

 

 

 

Sweet! Glad you're unblocked 🙂





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

Proud to be a Super User!


My course: Introduction to Developing Power BI Visuals


On how to ask a technical question, if you really want an answer (courtesy of SQLBI)




Helpful resources

Announcements
secondImage

Happy New Year from Power BI

This is a must watch for a message from Power BI!

December Update

Check it Out!

Click here to read more about the December 2020 Updates!

Community Blog

Check it Out!

Click here to read the latest blog and learn more about contributing to the Power BI blog!

Get Ready for Power BI Dev Camp

Get Ready for Power BI Dev Camp

Mark your calendars and join us for our next Power BI Dev Camp!.