0

I am trying to upload multiple files that allow users to upload multiple files.

For first time I'm able to upload files but when I select second time it come twice and for third time file name will comes three times.

Here is my code:

<body ng-app='myApp' ng-controller='myCtrl'>
  <input type="file" class="filePost" name="file" id="filePost" multiple="" ng-click='getSelectedFile()'>
  <div id='files_list'>
    <ul> </ul>
  </div>
  <script>
    var app = angular.module('myApp', []);
    app.controller('myCtrl', function($scope) {
      $scope.getSelectedFile = function() {
        $("#filePost").change(function() {
          var ele = document.getElementById('filePost');
          var result = ele.files;
          for (var x = 0; x < result.length; x++) {
            var file = result[x];
            $("#files_list ul").append(
              "<li class='list_item'>" + file.name + " " + "<span 
              class = 'remove' > X < /span>" +"</li > "
            );
          }
          $(document).on('click', '.remove', function() {
            var span_id = $(this.parentNode).text();
            $(this).closest('li').remove();
          });
        });
      }
    });
  </script>
</body>
Omi
  • 3,954
  • 5
  • 21
  • 41
Yashwanth
  • 181
  • 1
  • 3
  • 17

3 Answers3

1

I have made an example on plunker.. Hope you will understand.

Multiple uploading Files in Angular App Example

In html-

<body ng-controller="myCtrl">
    <p>Hello {{name}}!</p>
    <input type="file" ng-file-model="files" multiple />
    <button type="button" ng-click="upload()">Upload</button>

    <p ng-repeat="file in files">
      {{file.name}}
    </p>
  </body>

In js-

var app = angular.module('myApp', []);

app.controller('MyCtrl', function($scope) {
  $scope.name = 'World';
  $scope.files = []; 
  $scope.upload=function(){
    alert($scope.files.length+" files selected ... Write your Upload Code"); 

  };
});


app.directive('ngFileModel', ['$parse', function ($parse) {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            var model = $parse(attrs.ngFileModel);
            var isMultiple = attrs.multiple;
            var modelSetter = model.assign;
            element.bind('change', function () {
                var values = [];
                angular.forEach(element[0].files, function (item) {
                    var value = {
                       // File Name 
                        name: item.name,
                        //File Size 
                        size: item.size,
                        //File URL to view 
                        url: URL.createObjectURL(item),
                        // File Input Value 
                        _file: item
                    };
                    values.push(value);
                });
                scope.$apply(function () {
                    if (isMultiple) {
                        modelSetter(scope, values);
                    } else {
                        modelSetter(scope, values[0]);
                    }
                });
            });
        }
    };
}]);

If you still not got..notify me.

Vikas Gupta
  • 1,183
  • 1
  • 10
  • 25
0

There is a lot of things wrong with this.

  1. Your append should follow a standard string wrap. Most people would advise a 'this is a string' over "this is a string" when trying to push HTML to the DOM.

  2. If you're pushing HTML into the DOM make sure that the evaluated string at the end is correct HTML.

    class = 'remove' > X < /span>" +" "

From point 1 & 2 your HTML in JS should be

$('#files_list ul').append( '<li class="list_item">' + file.name + ' ' + '<span class="remove"> X </span>'+'</li>');

  1. I believe the main issue you are having is down to not wiping the previous uploads. One way of doing it is removing the HTML inside the ul tag at the start of the change event instead of an on click within the Document.
James Bass Davies
  • 408
  • 1
  • 3
  • 11
0

This problem occurs because browser doesn't clears the file list stored in the file input after the change, so try this edited code in which that file input is entirely removed and prepended to body again so that files will be removed after its read

<body ng-app='myApp' ng-controller='myCtrl'>
  <input type="file" class="filePost" name="file" id="filePost" multiple="" ng-click='getSelectedFile()'>
  <div id='files_list'>
    <ul> </ul>
  </div>
  <script>
    var app = angular.module('myApp', []);
    app.controller('myCtrl', function($scope) {
      $scope.getSelectedFile = function() {
        $(document).on('change',"#filePost",function() {
          var ele = document.getElementById('filePost');
          var result = ele.files;
          for (var x = 0; x < result.length; x++) {
            var file = result[x];
            $("#files_list ul").append(
              "<li class='list_item'>" + file.name + " " + "<span class = 'remove' > X < /span>" +"</li > "
            );
          }
          $("#filePost").remove();
          $("body").prepend('<input type="file" class="filePost" name="file" id="filePost" multiple="" ng-click='getSelectedFile()'>');
        });

        $(document).on('click', '.remove', function() {
          var span_id = $(this.parentNode).text();
          $(this).closest('li').remove();
        });
      }
    });
  </script>
</body>
Ananthakrishnan Baji
  • 1,254
  • 1
  • 9
  • 21