Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 
cpomeren003
Partner - Creator II
Partner - Creator II

Problems combining require.js and jquery.min.js in my mashup

Hello everyone,

I am currently trying to make a mashup with both require.js (needed by Qlik Sense) and jquery.min.js. Problem is, when I try to run it, I get an error/warning and nothing works (for example, scrollspy and smooth scrolling doesn't work). If I remove the required require.js then suddenly all my other .js files work again. Problem is, I really need/want both, because otherwise I have a nice working website without Qlik sense objects or I have a static website with only Qlik Sense objects.

Unfortunately I am quite new in the world of HTML/CSS/JS/Jquery/require.js so it's quite hard to understand some fixes people suggest. For example I found these documents:

Problem is, I don't know how to apply these solutions to my code / problem? Could any of you guru's help a noob out?

Here is all my code and the warnings/error I get in the console of google Chrome:

The error:

jquery.min.js:2 jQuery.Deferred exception: $(...).scrollspy is not a function TypeError: $(...).scrollspy is not a function
  at
HTMLDocument.<anonymous> (http://localhost:4848/extensions/version3/navigation/navigation.js:4:13)
  at l
(https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js:2:29375)
  at c
(https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js:2:29677) undefined

The warning:

Uncaught TypeError: $(...).scrollspy is not a function
  at
HTMLDocument.<anonymous> (navigation.js:4)
  at l
(jquery.min.js:2)
  at c
(jquery.min.js:2)

My HTML where I import everything:

<!doctype html>
<html><head>
  
<title>Try 3</title>
  
<meta charset="utf-8">
  
<meta name="viewport" content="width=device-width, initial-scale=1">

  
<!-- Font Awesome -->
  
<script defer src="https://use.fontawesome.com/releases/v5.0.13/js/all.js" integrity="sha384-xymdQtn1n3lH2wcu0qhcdaOpQwyoarkgLVxC/wZ5q7h9gHtxICrpcaSUfygqZGOe" crossorigin="anonymous"></script>

  
<!-- Bootstrap -->
  
<!-- Latest compiled and minified CSS -->
  
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
  
<!-- jQuery library -->
  
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  
<!-- Popper JS -->
  
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
  
<!-- Latest compiled JavaScript -->
  
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>

  
<!-- Qlik -->
  
<script src="../../resources/assets/external/requirejs/require.js"></script>
  
<link rel="stylesheet" href="../../resources/autogenerated/qlik-styles.css">

  
<!-- Navigation / Scrollspy / Back to top -->
  
<script src="navigation/navigation.js"></script>

  
<!-- Remaining -->
  
<link rel="stylesheet" href="version3.css">
  
<script src="version3.js"></script>

</head>

Navigation.js (Use it for scrollspy / smooth scrolling / back to top button):

$(document).ready(function(){
 
// Scrollspy with animated scroll: https://www.w3schools.com/bootstrap/bootstrap_ref_js_scrollspy.asp
 
// Add scrollspy to <body>
  $
('body').scrollspy({target: ".navbar", offset: 75});

 
// Add smooth scrolling on all links inside the navbar
  $
("#navbarSupportedContent a, .smoothScroll").on('click', function(event) {

  
// Make sure this.hash has a value before overriding default behavior
  
if (this.hash !== "") {

  
// Prevent default anchor click behavior
  
event.preventDefault();

  
// Store hash
  
var hash = this.hash;

  
// Using jQuery's animate() method to add smooth page scroll
  
// The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area
  $
('html, body').animate({
  scrollTop
: $(hash).offset().top -75// -75 to compensate for the navbar
  
}, 800, function(){

  
// Add hash (#) to URL when done scrolling (default click behavior)
  window
.location.hash = hash -75;  // -75 to compensate for the navbar
  
});

  
} // End if
 
});

 
// Flying in Qlikmenu based on scrollposition:
 
// zie: http://jsfiddle.net/MkJwm/2250/ en https://www.w3schools.com/howto/howto_js_sidenav.asp
 
// $ can vervangen worden door jQuery indien wenselijk
  $
(window).scroll(function() {
  clearTimeout
($.data(this, 'scrollTimer'));
  $
.data(this, 'scrollTimer', setTimeout(function() {
  
if ($(this).scrollTop() > 700) {
  $
('#qlikmenu').stop().animate({marginRight: '0px'});
  
} else {
  $
('#qlikmenu').stop().animate({ marginRight: '-135px' });
  
};
  
}, 250));
 
});


 
// source: https://paulund.co.uk/how-to-create-an-animated-scroll-to-top-with-jquery
 
// Check to see if the window is top if not then display button
  $
(window).scroll(function(){
  
if ($(this).scrollTop() > 90) {
  $
('.scrollToTop').fadeIn();
  
} else {
  $
('.scrollToTop').fadeOut();
  
}
 
});

});


Version3.js (Standard Qlik Sense mashup document):

/*
* Bootstrap-based responsive mashup
*/

/*
* Fill in host and port for Qlik engine
*/

var prefix = window.location.pathname.substr( 0, window.location.pathname.toLowerCase().lastIndexOf( "/extensions" ) + 1 );

var config = {
  host
: window.location.hostname,
  prefix
: prefix,
  port
: window.location.port,
  isSecure
: window.location.protocol === "https:"
};
//to avoid errors in workbench: you can remove this when you have added an app
var app;
require.config( {
  baseUrl
: (config.isSecure ? "https://" : "http://" ) + config.host + (config.port ? ":" + config.port : "" ) + config.prefix + "resources"
} );

require( ["js/qlik"], function ( qlik ) {

  
var control = false;
  qlik
.setOnError( function ( error ) {
  $
( '#popupText' ).append( error.message + "<br>" );
  
if ( !control ) {
  control
= true;
  $
( '#popup' ).delay( 1000 ).fadeIn( 1000 ).delay( 11000 ).fadeOut( 1000 );
  
}
  
} );

  $
( "#closePopup" ).click( function () {
  $
( '#popup' ).hide();
  
} );
  
if ( $( 'ul#qbmlist li' ).length === 0 ) {
  $
( '#qbmlist' ).append( "<li><a>No bookmarks available</a></li>" );
  
}
  $
( "body" ).css( "overflow: hidden;" );
  
function AppUi ( app ) {
  
var me = this;
  
this.app = app;
  app
.global.isPersonalMode( function ( reply ) {
  me
.isPersonalMode = reply.qReturn;
  
} );
  app
.getAppLayout( function ( layout ) {
  $
( "#title" ).html( layout.qTitle );
  $
( "#title" ).attr( "title", "Last reload:" + layout.qLastReloadTime.replace( /T/, ' ' ).replace( /Z/, ' ' ) );
  
//TODO: bootstrap tooltip ??
  
} );
  app
.getList( 'SelectionObject', function ( reply ) {
  $
( "[data-qcmd='back']" ).parent().toggleClass( 'disabled', reply.qSelectionObject.qBackCount < 1 );
  $
( "[data-qcmd='forward']" ).parent().toggleClass( 'disabled', reply.qSelectionObject.qForwardCount < 1 );
  
} );
  app
.getList( "BookmarkList", function ( reply ) {
  
var str = "";
  reply
.qBookmarkList.qItems.forEach( function ( value ) {
  
if ( value.qData.title ) {
  str
+= '<li><a data-id="' + value.qInfo.qId + '">' + value.qData.title + '</a></li>';
  
}
  
} );
  str
+= '<li><a data-cmd="create">Create</a></li>';
  $
( '#qbmlist' ).html( str ).find( 'a' ).on( 'click', function () {
  
var id = $( this ).data( 'id' );
  
if ( id ) {
  app
.bookmark.apply( id );
  
} else {
  
var cmd = $( this ).data( 'cmd' );
  
if ( cmd === "create" ) {
  $
( '#createBmModal' ).modal();
  
}
  
}
  
} );
  
} );
  $
( "[data-qcmd]" ).on( 'click', function () {
  
var $element = $( this );
  
switch ( $element.data( 'qcmd' ) ) {
  
//app level commands
  
case 'clearAll':
  app
.clearAll();
  app1
.clearAll();
  app2
.clearAll();
  
break;
  
case 'back':
  app
.back();
  
break;
  
case 'forward':
  app
.forward();
  
break;
  
case 'lockAll':
  app
.lockAll();
  
break;
  
case 'unlockAll':
  app
.unlockAll();
  
break;
  
case 'createBm':
  
var title = $( "#bmtitle" ).val(), desc = $( "#bmdesc" ).val();
  app
.bookmark.create( title, desc );
  $
( '#createBmModal' ).modal( 'hide' );
  
break;
  
}
  
} );
  
}

  
//callbacks -- inserted here --

  
//open apps -- inserted here --

  
//get objects -- inserted here --

  
//create cubes and lists -- inserted here --
  
if ( app ) {
  
new AppUi( app );
  
}

Would love some pointers on how to solve this problem and where I can learn more about why this doesn't work (preferably in layman terms).

Thanks in advance,

Casper

17 Replies
ErikWetterberg

Hi,

The file called requirejs in a Qlik installation actually contains jQuery. Why do you need to load jQuery separately too?

Erik Wetterberg

cpomeren003
Partner - Creator II
Partner - Creator II
Author

Hi Erik,

I tried using only requirejs, but then my scrollspy doesn't work anymore. After a lot of testing I figured out that the problem wasn't in only the conflicting requirejs and jQuery, but the combination of scrollspy and requirejs and jQuery.

The current solution is:
- move my scrollspy line from my navigation.js to the html itself;
- use both requirejs and jQuery.

If I find a more satisfactory solution I'll update this post.

Francis_Kabinoff
Former Employee
Former Employee

So you have a confluence of problems you're going to run into here. First is that when you load scrollspy as a jquery plugin on a jquery instance you load to window before the qlik require.js file loads it's version of jquery, it won't be available since the qlik require.js file version of jquery is going to overwrite your version of jquery. you can either load scrollspy using require.js and onto the jquery instance loaded by the require file, or you can save the jquery version you load with scrollspy as something other than jquery or $ before the require file overwrites it.

Second, capability api css sets html and body height to 100%, and scrolls on the body. This stops things like scrollspy from working correctly since window.scrollY is always 0. You can try to fight this, but you may end up with the tooltips to your embedded Qlik Sense charts "floating" away as you scroll down the page.

cpomeren003
Partner - Creator II
Partner - Creator II
Author

Hi Francis,

Weirdly enough, I thought the same as you, but it somehow all works without any problems. I am not quite sure how and I don't think this solution is ideal. I'll try to figure out why/how and I will work towards a better solution, because I prefer to understand what is happening.

About your second point, also correct, but I corrected that with some css and now I can use scrollspy and the tooltips still works like you would expect. (Took me a long time to come to this point, with lots and lots of trial and error ).

I'll let you know when I have a more elegant solution.

Casper

s_achraphe
Contributor III
Contributor III

Hello cpomeren003‌ !

I'm having the same issue like you did you manage to find another solution to your issue ?

would be great if you can share

cpomeren003
Partner - Creator II
Partner - Creator II
Author

Unfortunately no, the current solution is still:

- move my scrollspy line from my navigation.js to the html itself;

- use both requirejs and jQuery.


This works without any problems/errors.


Do you also still need help with this: having trouble to embbed chart in my mashup ? If so I can probably help you out.






s_achraphe
Contributor III
Contributor III

Actually i'm not using scrollspy, only smooth-scroll

but I'm using other libraries and have a js file per library j.PNG

So I don't know how to use  your solution

But the issue is the same when require.js line is active , the scroll (with a bouncing arrow) and the collapse navbar is not working anymore

And when it's unactive I cannot see my embbeded qliksense charts ...

For my question in the other topic I think it's related to this issue with the js files

cpomeren003
Partner - Creator II
Partner - Creator II
Author

Could you maybe upload your mashup? So I could take a look into fixing both problems.

s_achraphe
Contributor III
Contributor III

May I sent a PM ?