15

I am uploading images for our application to the server. Is there any way to validate the extensions in client side by JS before submitting them to the server before uploading them to server?

I am using AngularJs to handle my front-end.

Eugene
  • 10,957
  • 20
  • 69
  • 97
Ali Saberi
  • 864
  • 1
  • 10
  • 33

6 Answers6

27

You can use this simple javascript to validate. This code should be put inside a directive and on change of file upload control.

var extn = filename.split(".").pop();

Alternatively you can use javascript substring method also:

fileName.substr(fileName.lastIndexOf('.')+1)
Sanjeev Singh
  • 3,976
  • 3
  • 33
  • 38
  • extensions can be easily manipulated. Eg: create an image (say png) then change the extension to .xlsx. the image gets uploaded to server as `.xlsx` For the question, the answer is right, but not practically useful – Adarsh Mohan May 13 '19 at 06:35
  • I did not understand your question? What kind of practical use you want from a file name and extenssion? – Sanjeev Singh May 13 '19 at 10:07
12

You can create a angular directive, something like this should work (Change the accepted values in the validFormats array);

HTML:

    <form name='fileForm' >
        <input type="file" name="file" ng-model="fileForm.file" validfile>
    </form>

Javascript:

angular.module('appname').directive('validfile', function validFile() {

    var validFormats = ['jpg', 'gif'];
    return {
        require: 'ngModel',
        link: function (scope, elem, attrs, ctrl) {
            ctrl.$validators.validFile = function() {
                elem.on('change', function () {
                   var value = elem.val(),
                       ext = value.substring(value.lastIndexOf('.') + 1).toLowerCase();   

                   return validFormats.indexOf(ext) !== -1;
                });
           };
        }
    };
});
taxicala
  • 21,408
  • 7
  • 37
  • 66
ecarrizo
  • 2,758
  • 17
  • 29
5

for file validation i.e required,file extension,size.Create custom directive and used angular js ng-message module for simplify the validation errors

HTML

<input type="file" ng-model="imageFile" name="imageFile" valid-file required>

<div ng-messages="{FORMNAME}.imageFile.$error" ng-if="{FORMNAME}.imageFile.$touched">
     <p ng-message="required">This field is required</p>
     <p ng-message="extension">Invalid Image</p>
 </div>

Angular JS

customApp.directive('validFile', function () {
return {
    require: 'ngModel',
    link: function (scope, elem, attrs, ngModel) {
        var validFormats = ['jpg','jpeg','png'];
        elem.bind('change', function () {
            validImage(false);
            scope.$apply(function () {
                ngModel.$render();
            });
        });
        ngModel.$render = function () {
            ngModel.$setViewValue(elem.val());
        };
        function validImage(bool) {
            ngModel.$setValidity('extension', bool);
        }
        ngModel.$parsers.push(function(value) {
            var ext = value.substr(value.lastIndexOf('.')+1);
            if(ext=='') return;
            if(validFormats.indexOf(ext) == -1){
                return value;
            }
            validImage(true);
            return value;
        });
    }
  };
});

Require angular-messages.min.js

Aniket Muruskar
  • 267
  • 3
  • 9
  • It is working fine for validating that if a file is jpg, jpeg or png. But when nothing is selected I get a parse error as below: Please add error message for parse. For more details look this image: http://i66.tinypic.com/2ykz6t1.jpg – Vishal Jun 13 '17 at 12:53
  • Extension validation is working for me with same code, but required is not working, though its showing parse error. Can anyone Provide any changes required in this to acquire same. – Shilpi Jaiswal Dec 11 '18 at 10:00
1

Here is the complete code for validating file extension usign AngularJs

<!DOCTYPE html>
<html>
<head>
    <title></title>

    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>

    <script type='text/javascript'>
            var myApp = angular.module('myApp', []);
            myApp.controller('MyCtrl', function($scope) {
                $scope.setFile = function(element) {
                    $scope.$apply(function($scope) {
                        $scope.theFile = element.files[0];
                        $scope.FileMessage = '';
                        var filename = $scope.theFile.name;
                        console.log(filename.length)
                        var index = filename.lastIndexOf(".");
                        var strsubstring = filename.substring(index, filename.length);
                        if (strsubstring == '.pdf' || strsubstring == '.doc' || strsubstring == '.xls' || strsubstring == '.png' || strsubstring == '.jpeg' || strsubstring == '.png' || strsubstring == '.gif')
                        {
                          console.log('File Uploaded sucessfully');
                        }
                        else {
                            $scope.theFile = '';
                              $scope.FileMessage = 'please upload correct File Name, File extension should be .pdf, .doc or .xls';
                        }

                    });
                };
            });
    </script>

</head>
<body ng-app="myApp">
    <div ng-controller="MyCtrl">
        <input type="file"
               onchange="angular.element(this).scope().setFile(this)">
        {{theFile.name}}
        {{FileMessage}}
    </div>

</body>
</html>
Shakeer Hussain
  • 2,230
  • 7
  • 29
  • 52
0

You can add a custom directive which checks for the element.files array in order to check the type on the onchange event. There is no embedded validation for file input.

0

File Upload using AngularJS

There are many modules that can help you with this. Any one of these should allow you to define a filter to only upload certain file extensions.

If you're looking for a simpler solution, you can use something like string.js to ensure the filenames of the files being uploaded are of extension '.png'.

Community
  • 1
  • 1
jcc
  • 1,137
  • 1
  • 12
  • 31