Search code examples
javascriptangularjsgroup-byangular-file-upload

Sort/GroupBy files pre-uploaded using AngularJS


I want to group my files before to upload them by extension(The extension can not be defined in the mime type attribute defined by the upload infos. So I used groupBy defined by angular-filter and instead to put an attribute('file.name' for example) to the filter Im using a function to get the extension. So I want my pre-loaded files appears like this:

  • Extension1:

file3.Extension1

file1.Extension1

  • Extension2:

file4.Extension2

file2.Extension2

This is my EXAMPLE

Also my code:

  <ul>
    <li ng-repeat="f in files | groupBy: fileExtension" style="font:smaller">
        {{f.name}}
    </li>
</ul>

$scope.fileExtension = function(file) {
    return file.name.split('.').pop();
};

Any suggestion is appreciated!


Solution

  • I would transform your list of file names into a list of file groups inside of an ngController or service. Binding to this transformed collection becomes trivial in the view.

    $scope.groups = groupByExt(filenames);
    
    function groupByExt(filenames) {
        var extensions = [];
        var groups = [];
        angular.forEach(filenames, function(item) {
            var extension = item.substring(item.lastIndexOf(".")+1);
            if (!extensions[extension]) {
                var group = { name: extension, files: [] };
                extensions[extension] = group;
                groups.push(group);
    
                group.files.push({ name: item });
            }
            else {
                var group = extensions[extension];
                group.files.push({ name: item});
            }
        });
        return groups;
    }
    

    HTML

    <ul>
        <li ng-repeat="group in groups">
            {{ group.name }}
            <ul>
                <li ng-repeat="file in group.files">
                    {{ file.name }}
                </li>
            </ul>
        </li>
    </ul>
    

    Demo

    You can also set up $watchers so that when the original filenames list changes, it updates the file groups:

    $scope.$watchCollection('filenames', function(newVal, oldVal)    {
      if(newVal !== oldVal) {
          $scope.groups = groupByExt(newVal);
      }
    });
    

    Demo

    I would avoid filters because filters should not change the references of the underlying items (infinite digest issue)