1

I have a working version of HTML5 drag & drop file uploader. I was editing the JS code to support multiple file uploads on same page. I came across with a problem by trying to access "instance" properties in methods which are registered as events.

The problem is shown by the code below, in method this.drop. The reason of existence of the this.$$upload_self property is to access data through this property. For example, I can't use this keyword inside this.drop function, because when event is raised, this not referring my "instance".

I'm not sure that by creating $$upload_self was a good idea.

The new instances area created like this:

  var recording_upload = new upload();
  recording_upload.init(recording_upload, ...);

Code of Drag & drop file upload:

    var upload = function() {
    this.$$upload_self = null;
    this.$drop = null;
    this.$status = null;
    this.$progress = null;
    this.maxNumberOfFiles = null;
    ...
    
    this.init = function (self, pUrl, maxNmbOfFiles, dropArea, progress, status) {
        $$upload_self = self;
        $$upload_self.postUrl = pUrl;
        $$upload_self.maxNumberOfFiles = maxNmbOfFiles;

        $$upload_self.$drop = $("#" + dropArea);
        $$upload_self.$progress = $("#" + progress);
        $$upload_self.$status = $("#" + status);

        $$upload_self.$drop.bind('dragenter', $$upload_self.enter);
        $$upload_self.$drop.bind('dragleave', $$upload_self.leave);
        $$upload_self.$drop.bind('drop', $$upload_self.drop);
    };
    
    this.enter = function (e) {
        $(e.target).addClass('hover');
        return false;
    };

    this.leave = function (e) {
        $(e.target).removeClass('hover');
        return false;
    };
    
    this.drop = function (e, _this) {
        $(e.target).removeClass('hover');
        var files = e.originalEvent.dataTransfer.files;

        if (files.length > $$upload_self.maxNumberOfFiles) { // for example, here $$upload_self references always last instance...
            $$upload_self.displayErrorMessage('Error: You can only drop ' + $$upload_self.maxNumberOfFiles + ' file(s) at time.');
            return false;
        }
     ...
    };
    ...
}

Is there any workaround to solve this issue? I believe this maybe a common problem, but can't find nothing to solve this problem.

Any help is very much appreciated.

3 Answers 3

1

You could ditch the new keyword altogether and use a fresh closure for each instance of upload.

EDIT: Updated to avoid potential clobbering of global this.

var upload = function(pUrl, maxNmbOfFiles, dropArea, progress, status) {
    return {
        postUrl: pUrl,
        ...
        drop: function(e) {
            ...
            if (files.length > this.maxNumberOfFiles) {
                this.displayErrorMessage(...);
            }
            ...
        },
        ...
    };
};

...

var someUpload = upload(...);
Sign up to request clarification or add additional context in comments.

Comments

1

Try to search for a "scope". As an example see how it implemented in ExtJS.

2 Comments

This is not really a scope issue; it's an issue with the semantics of function calls and this.
This is a "scope" in terms of ExtJS. Not variable scope, but may be some context -- I don't know more correct universal word.
1

In a modern browser you can do this:

  $$upload_self.$drop.bind('dragleave', $$upload_self.leave.bind($$upload_self));

For older IE versions you can do this:

  $$upload_self.$drop.bind('dragleave', function() { $$upload_self.leave(); });

Really the ".bind()" method of all Function objects in new browsers just creates a little intermediate function for you, essentially like the second example. The Mozilla docs page for ".bind()" has a very good block of code you can use as a "polyfill" patch for browsers that don't support ".bind()" natively.

Comments

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.