16 Replies Latest reply: Aug 17, 2018 8:11 AM by Casper van Pomeren RSS

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

    Casper van Pomeren

      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