Search code examples
javascriptangularjsrequirejszeroclipboard

ZeroClipboard and RequireJS - ZeroClipboard is not defined


I'm attempting to use ZeroClipboard inside an AngularJS/RequireJS Application.

I have put ZeroClipboard.js into the location /assets/js/vendors/ZeroClipboard.js

I have set up the main.js of the RequireJS application

main.js

requirejs.config({

    paths: { 
        jQuery: 'vendors/jquery.min',
        'clipboard': 'vendors/ZeroClipboard',
        underscore: 'vendors/underscore-min',
        angular: 'vendors/angular.min',
        'angular-route': 'vendors/angular-route.min',
        'controllers': 'controllers',
        'services': 'services',
        'filters': 'filters',
        'directives': 'directives',
        'app': 'app'

    },

    shim: {
        underscore: {
            exports: '_'
        },
        'jQuery': {
            'exports': 'jQuery'
        },
        'angular': {
            exports: 'angular'
        },
        'states': {
            deps: ['angular'],
            exports: 'states'
        },
        'angular-route': {
            deps: ['angular']
        }
    },
    priority: [
        'angular'
    ]
});

requirejs(['angular',
            'app',
            'underscore',
            'routes',
            'vendors/jquery.min',
            'services/services',
            'directives/directives',
            'filters/filters',
            'controllers/controllers'
           ], function (angular, app, _) {
               angular.element(document).ready(function () {
                   angular.bootstrap(document, ['App']);
                   document.getElementsByTagName('html')[0].dataset.ngApp = 'App';
               });

           });

And inside the controller that I am calling ZeroClipboard

controller.js

define(['clipboard'], function() {
    var AppCtrl = function($scope, $modal, $timeout, $log, $http, $routeParams,  $rootScope) {
        var client = new ZeroClipboard( $("li#copy-buildr") );
    };
    return AppCtrl;
});

All I seem to get is ReferenceError: ZeroClipboard is not defined


Solution

  • Using a directive and loading the ZeroClipboard.js directly into the DOM has worked. Unsure how to load that file via AMD though as it always returns an error.

                        .directive('clipCopy', ['$window', function ($window) {
                            return {
                                scope: {
                                    clipCopy: '&',
                                    clipClick: '&'
                                },
                                restrict: 'A',
                                link: function (scope, element, attrs) {
                                    // Create the clip object
                                    var clip = new ZeroClipboard( element, {
                                        moviePath: '//cdnjs.cloudflare.com/ajax/libs/zeroclipboard/1.1.7/ZeroClipboard.swf',
                                        trustedDomains: ['*'],
                                        allowScriptAccess: "always"          
                                    });
    
                                    clip.on( 'mousedown', function(client) {
                                        client.setText(scope.$eval(scope.clipCopy));
                                        if (angular.isDefined(attrs.clipClick)) {
                                            scope.$apply(scope.clipClick);
                                            console.log($scope.clipClick);
                                        }
                                    });
                                }
                            }
                        }]);