fm722
fm722

Reputation: 33

How can you load multiple JQuery plugins?

How can you load multiple JQuery plugins that use the $ to access methods? My configuration file (config.js) is as follows:

var require = {
    paths: {
        "jquery": "lib/jquery",
        "jqueryui": "lib/jquery-ui",
        "semanticui": "lib/semantic",
    },
    shim: {
        "jqueryui": {
            exports: "$",
            deps:['jquery']
        },
        "semanticui": {
            exports: "$",
            deps: ['jquery']
        }
    }};

My application file (load.js) is defined as follows:

define(['jqueryui', 'semanticui'], function ($) {
    console.log($);
})

I found that the $ was undefined. However when I use the following code below:

define(['semanticui', 'jqueryui'], function ($) {
    console.log($);
})

$ is defined as the jQuery object.

Is it possible to use the $ to access jQuery and the methods defined by the plugins?

This is the index.html file I use:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Dashboard</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.8/semantic.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
    <link rel="stylesheet" href="./css/app.css">
    <script type="text/javascript" src="config.js"></script>
    <script data-main="load" src="lib/require.js" async></script>
</head>

<body>
    <!--NAVIGATION BAR-->
    <div class="ui fixed inverted menu">
        <div class="ui fluid container">
            <div class="header item" id="activateSidebar">AthenaViz<i class="terminal icon"></i></div>
        </div>
    </div>
    <!--END OF NAVIGATION BAR-->
    <!--SIDEBAR MENU-->
    <div class="ui left vertical  sidebar labeled icon menu">
        <a class="item">
        </a>
        <a class="item">
            <i class="fa fa-pie-chart"></i> Dashboard
        </a>
        <a class="item">
            <i class="fa fa-eye"></i> Visualize
        </a>
    </div>
    <!--END OF SIDEBAR MENU-->
    <div class="pusher">
<table class="ui striped table">
  <thead>
    <tr>
      <th>Name</th>
      <th>Date Joined</th>
      <th>E-mail</th>
      <th>Called</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>John Lilki</td>
      <td>September 14, 2013</td>
      <td>[email protected]</td>
      <td>No</td>
    </tr>
    <tr>
      <td>Jamie Harington</td>
      <td>January 11, 2014</td>
      <td>[email protected]</td>
      <td>Yes</td>
    </tr>
    <tr>
      <td>Jill Lewis</td>
      <td>May 11, 2014</td>
      <td>[email protected]</td>
      <td>Yes</td>
    </tr>
          <tr>
      <td>Jill Lewis</td>
      <td>May 11, 2014</td>
      <td>[email protected]</td>
      <td>Yes</td>
    </tr>
          <tr>
      <td>Jill Lewis</td>
      <td>May 11, 2014</td>
      <td>[email protected]</td>
      <td>Yes</td>
    </tr>
  </tbody>
</table>
    </div>
</body>

</html>

Upvotes: 1

Views: 238

Answers (1)

Louis
Louis

Reputation: 151380

You should not use a shim with jQuery UI, because it calls define by itself, and shim is only for modules that do not call define. If you look at the code here, you'll see near the start of the file:

(function( factory ) {
    if ( typeof define === "function" && define.amd ) {

        // AMD. Register as an anonymous module.
        define([ "jquery" ], factory );
    } else {

        // Browser globals
        factory( jQuery );
    }
}(function( $ ) {

And it looks like the factory function does not return anything, which explains why you got $ set to undefined.

Semantic UI does need a shim because it does not call define.

I suggest that instead of trying to grab $ from the plugins, you get it from jquery itself:

define(['jquery', 'jqueryui', 'semanticui'], function($) {
  console.log($);
});

The order may appear strange but it will work fine. You have to think about how jQuery plugins install themselves: they modify the jQuery object, which is $ here. So the code above will load jquery, then load jqueryui, which will modify jQuery to add itself as a plugin, and load semanticui, which will also modify jQuery to add itself as a plugin. (Actually, semanticui could load before jqueryui because one is not dependent on the other, but it does not change the end result.) So the $ that you get into your anonymous function will have the plugins installed on it.

I do what I'm suggesting above all the time, without any issue, but I use the CommonJS idiom:

define(function (require, exports, module) {
    var $ = require("jquery");
    require("bootstrap");
    require("jquery.bootstrap-growl");
});

bootstrap and jquery.bootstrap-growl install themselves as jQuery plugins, but I get my reference from jquery itself.

(The CommonJS idiom is not better. It's just what I use.)

Upvotes: 1

Related Questions