1

I am using the JQuery Boilerplate to write my first JQuery plugin - a responsive carousel. I am using another plugin (SSM - http://www.simplestatemanager.com/) to create states for each device view. So on mobile devices functionA will run, on tablets functionB and on desktops functionC, etc.

For each state created by SSM a corresponding onEnter callback function can be added and I've added 3 suitable functions to run when this occurs. As you can see from the code below a function onEnterDesktop runs on Desktop devices. I am then attempting to run a further function from within this called createCarousel() but am getting an error "createCarousel is not defined".

I believe this is because of a scoping problem and the browser can't find createCarousel from within the onEnterDesktop function. How can I fix this?

Any help would be great. Here's the code for my plugin:

;(function ( $, window, document, undefined ) {

// Create the defaults once
var pluginName = "dcResponsiveCarousel",
    defaults = {
        propertyName: "value"
    };

function Plugin( element, options ) {
    this.element = element;
    this.$element = $(element);
    this.options = $.extend( {}, defaults, options) ;
    this._defaults = defaults;
    this._name = pluginName;
    this.init();
}

Plugin.prototype = {

    init: function() {

        ssm.addStates([
            {
                id: 'mobile',
                maxWidth: 767,
                onEnter: this.onEnterMobile
            },            
            {
                id: 'tablet',
                maxWidth: 991,
                minWidth: 768,
                onEnter: this.onEnterTablet
            },
            {
                id: 'desktop',
                minWidth: 992,
                onEnter: this.onEnterDesktop
            }
        ]);
        ssm.ready();
    },

    onEnterMobile: function (){
        console.log("You've entered mobile screen dimension territory");
        var itemsPerPage = 1;
        console.log(itemsPerPage); 
    },

    onEnterTablet: function (){
        console.log("You've entered tablet screen dimension territory");
        var itemsPerPage = 2;
        console.log(itemsPerPage);         
    },

    onEnterDesktop: function (){
         console.log("You've entered desktop screen dimension territory");
         var itemsPerPage = 3;
         createCarousel();
    },

    createCarousel: function (){
        var $carouselItems = this.$element.children(".item"),
            $carouselItemsLength = $carouselItems.length,
            $carouselItemsWidth = 0;

            for (var i = 0; i < $carouselItemsLength; i++) {
                $carouselItemsWidth = $carouselItemsWidth + $carouselItems.eq(i).outerWidth();
            };

            console.log($carouselItemsWidth);
            this.$element
    }
};

$.fn[pluginName] = function ( options ) {
    return this.each(function () {
        if (!$.data(this, "plugin_" + pluginName)) {
            $.data(this, "plugin_" + pluginName,
            new Plugin( this, options ));
        }
    });
};

})( jQuery, window, document );

1 Answer 1

1

It's an object literal so createCarousel is not defined, Plugin.prototype.createCarousel is, or in the scope you are in, this.createCarousel();

onEnterDesktop: function (){
     console.log("You've entered desktop screen dimension territory");
     var itemsPerPage = 3;
     Plugin.prototype.createCarousel();
},
Sign up to request clarification or add additional context in comments.

5 Comments

Tried using the above and get: Uncaught TypeError: Object [object Array] has no method 'createCarousel'
It's because of the way it's called, it has another scope, use Plugin.prototype.createCarousel() instead
Thanks that seemed to do the trick. Also how can I pass this.$element through to onEnterDesktop and createCarousel. I appreciate your help.
Again, because of the way it's called, it has a completely different scope, so you can either use apply to set the scope, or use Plugin.$element to get the element.
Thanks again. I decided to remove the specificity on the this.$element variable and changed it to $element so I can access it from anywhere.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.