2

Trying to create a file upload directive using jQuery File Upload plugin and this gist of the directive https://gist.github.com/thoughtpalette/4726114

I need to pass in a id from an object in profile-ctrl.js into the submit functionality for the upload form.

My Directive lies outside of the controller and I couldn't set the object to $rootScope to catch/pass it in the directive.

the url: in fileupload is where the magic happens. Calling my controller via an api and passing over the file information and hopefully the vendorId which is in the merchant object in profile-ctrl.js. $scope.merchant

I cannot post in a fiddle due to the project structure unfortunately

My Directive:

//jqueryFileUpload-Plugin 
//https://github.com/blueimp/jQuery-File-Upload
define(['jquery',
        'angular',
        'core',
        'source/core/helpers/urlHelper.js'],
    function ($, angular, core, urlHelper) {
    "use strict";
    return [ function ($compile) {
        return {
            restrict:'E',
            scope: {
                merchant: '=ngModel'
            },
            compile:function(el,attrs, scope){
                var compiler = this,
                elem = el,
                vendorId = scope.merchant.id;
                instanceFn = function() {
                    var currentScope = this,
                        fileInputDiv = $(' <span class="btn btn-success fileinput-button">'+
                        '<i class="icon-plus icon-white"></i>'+
                        '<span>Upload Logo</span>'+
                        '<input type="file" name="files[]" single>'+
                        '</span>').appendTo(elem),
                        fileInput = fileInputDiv.find('input'),
                        fileList = $('<div class="UploaderList">'+
                        '<table>'+
                        '<tr>'+
                        '<td>File to Upload</td>'+
                        '</tr>'+
                        '</table>'+
                        '</div>').appendTo(elem),
                        button = $('<button class="btn">Submit</button>').appendTo(elem);

                    button.hide();
                    $('<div class="uploader">').appendTo(elem);
                    $('</div>').appendTo(elem);

                    fileInput.fileupload({
                        url:urlHelper.vendor.uploadLogo(vendorId),
                        dataType: 'json',
                        add:function (e, data) {

                            button.show();

                            // this will add a handler which will submit this specific file
                            button.bind('click.uploadsubmit', function(){ 
                                data.submit();
                            });
                            $.each(data.files, function (index, file) {
                                $("<tr><td>"+file.name+"</td><td></td><tr>").appendTo(fileList.find('table:first'));
                            });
                        },
                        // for each file
                        done: function (e, data) {

                            button.hide();

                            var result = "",
                                r = data.result,
                                file = data.files[0]; // we only support single file upload by now
                            // error

                            // CHANGE THIS PART FOR YOUR REQUIREMENTS (I have a json repsonse)

                            if(r.success !== undefined && r.success === false){
                                result = "<span class='error'>Unknown error</span>";
                                if(r.errors !== undefined && r.errors.length > 0 && r.errors[0].message !== undefined)
                                {
                                    result = "<span class='error'>"+r.errors[0].message+"</span>";
                                }
                            }
                            else{
                                result = "<span class='success'>OK</span>";
                            }

                            $("td:contains('"+file.name+"')").next().html(result);
                        },
                        progressall:function (e, data) {
                            var progress = parseInt(data.loaded / data.total * 100, 10);
                        },
                        // called only once... (wen submit button is clicked)
                        start:function(e){

                            // we start the upload, so we do also cleanup jobs right now:
                            button.unbind('click.uploadsubmit'); // importan - remove all event handlers
                            button.hide();
                            fileInputDiv.hide();

                        }
                    });

                };
                return instanceFn;
            }

        };
    }]; 
});

Directive Call via html:

<jquery-File-Upload ng-model="merchant"></jquery-File-Upload>

So right now merchant returns undefined in the directive. Can someone help me pass that in?

Christopher Marshall
  • 10,678
  • 10
  • 55
  • 94
  • The 3rd argument to the compile function isn't the scope, its a transclude linking function. I believe the instanceFn you define is your linking function, right? If so, its first argument is the scope, and merchant should be defined on it. – Mark Rajcok Feb 06 '13 at 22:33
  • That is correct, although now I'm finding my directive is executing before my merchant scope is set and hence not setting the value. Tested by putting scope.merchant.id into the start function of fileupload. Feel free to post as an answer :} – Christopher Marshall Feb 06 '13 at 23:16

1 Answers1

1

As mentioned in the comments, the 3rd argument to the compile function isn't the scope, its a transclude linking function. Here's an example of how to use that, if you're curious.

The instanceFn you define is your linking function, since it is being returned by the compile function. The first argument to the linking function is the scope, and merchant should be defined on it.

Trying $watch()ing merchant, then execute your logic once you notice a change.

Community
  • 1
  • 1
Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492