0

This is my first attempt at a jQuery plugin and I have managed to cobble something together that is nearly working. I have a button that, once pressed, sends an ID via ajax in order to delete an image. My problem is that when the ajax call returns I am getting the following error in my Firebug console window:

TypeError: self.releaseCropBoxIfSet is not a function

Here is a stripped down version of my plugin:

if( typeof Object.create !== 'function' ){
    Object.create = function( obj ){
        function F() {};
        F.prototype = obj;
        return new F();
    };
}

(function( $, window, document, undefined ) {
    var uploadCrop = {
        init: function (options, elem ){
            var self = this;
            self.elem = elem;
            self.$elem = $( elem );
            self.options = $.extend( {}, $.fn.uploadCropPlugin.options, options);
            self.deleteUploadedImageButton = $('#'+self.options.deleteUploadedImageButton);
            self.ajaxurl = self.options.ajaxurl;
            self.deleteUploadedImageButton.on('click', function(e) {
                $(this).hide();
                $.ajax({
                    url: self.ajaxurl,
                    type: 'post',
                    success: self.deleteSuccess,
                    error: self.deleteError,
                    data: {
                        IDtoDelete : IDtoDelete,                
                        action : 'deleteImage'
                    }
                });
            });
        },
        deleteSuccess: function(data) {
            var self = this;
            var returnedData = $.parseJSON(data);  
            self.releaseCropBoxIfSet(); // I am getting an error here
        },
        releaseCropBoxIfSet: function() {
            var self = this;
            // REMOVE OLD JCROP
            if (typeof self.jcrop_api != "undefined") {
                self.jcrop_api.release();
                self.jcrop_api.destroy();
            }
        }
    };
    $.fn.uploadCropPlugin = function( options ) {
        return this.each(function() {
            var thisUploadCropObj = Object.create( uploadCrop );
            thisUploadCropObj.init( options, this );
        });
    };
    $.fn.uploadCropPlugin.options = {
        // my vars here
    };
})( jQuery, window, document );

I wondered whether the issue was that self gets lost during the Ajax call. So I tried sending self as a variable to the function and then returning it but I got errors that way. I also tried leaving the self. bit off the front of the function call but it still doesn't work.

4
  • Try removing the (self.) and call the function normally Not sure if that will help though. Commented Sep 20, 2014 at 16:11
  • @Tasos thanks I did try that and just got: ReferenceError: releaseCropBoxIfSet is not defined :-( Commented Sep 20, 2014 at 16:21
  • Ok. where is the (self) referenced to. I don't know how you plugging is structured but usually it should be ( self = { myfunctiona : function() { }, myfunctionb : function() { }, myfunctionc : function() { } ) so when you call a function withing the group (self) e.g (functionc) you do ( self.functionc() ) -- have you structured it that way --- example script --- nativedroid.godesign.ch/res/js/script.js Commented Sep 20, 2014 at 16:51
  • @Tasos Thanks for the example. My plugin is shown in the question. I have my button 'click' function inside my init part of the plugin. Is that not correct? I've tried moving it outside but couldn't get it to work that way? My 'self' is defined at the start of the 'init' function and refers to 'this' i.e. var self = this; Commented Sep 20, 2014 at 17:48

1 Answer 1

1

To reword the issue you are running into:

TypeError: self.releaseCropBoxIfSet is not a function

The above means that the releaseCropBoxIfSet property of self is not a function. If you are sure you are defining the function properly (which you are) the issue must be that self isn't what you think it is (that is, it is not the object you want it to be). To fix the issue, you can bind the this value to be what you want (expect) it to be.

(function ($, window, document, undefined) {
    var uploadCrop = {
        init: function (options, elem){
            // ...
            self.deleteUploadedImageButton.on('click', function(e) {
                $(this).hide();
                $.ajax({
                    url: self.ajaxurl,
                    type: 'post',
                    // Notice the call to `bind`
                    success: self.deleteSuccess.bind(self),
                    error: self.deleteError,
                    data: {
                        IDtoDelete : IDtoDelete,                
                        action : 'deleteImage'
                    }
                });
            });
        },
        deleteSuccess: function(data) {
            var self = this;
            var returnedData = $.parseJSON(data);  
            self.releaseCropBoxIfSet();
        }
    };
})(jQuery, window, document);

Chances are you will want to do the same for the deleteError callback.

(Also, please don't alias this to self if this === self. It is unnecessary and confusing.)

Sign up to request clarification or add additional context in comments.

1 Comment

Genius! Thank you so much for your help and your advice. I will take this on board along my (extremely) long and arduous road towards becoming a programming deity... :-)

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.