Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript validation to insert file of specific name

I want a validation in Javascript that, a file name should be of specific type should be uploaded like for an example.

I have a fileupload control which has the feature to upload multipe file.

here is the html of that.

<asp:FileUpload runat="server" ID="flufileUpload" AllowMultiple="true" onchange="return ValidateFileType(this);" />

So while uploading i want user to upload file of specific name

like:-

A user can upload only 5 files with only name as

1 -> 120.jpg

2 -> 150.jpg

3 -> 180.jpg

4 -> 210.jpg

5 -> 240.jpg

if user uploads filename other than this then it should prompt alert message.

my function for handling some validations is below. but I am unable to handle the filename validation.

function ValidateFileType(controlName) {
    try {
        var uploadControl = controlName;
        var isCValidFile = false;

        for (var i = 0; i < uploadControl.files.length; i++) {
            isCValidFile = false;

            var path = uploadControl.files[i].name;
            var ext = path.substring(path.lastIndexOf(".") + 1, path.length).toLowerCase();

            if (path != "") {
                for (var j = 0; j < ValidImageFileExtension.length; j++) {
                    if (ext == ValidImageFileExtension[j]) {
                        isCValidFile = true;
                        break;
                    }
                }
                if (!isCValidFile) {
                    jAlert("Invalid File. Please upload a File with extension " + ValidImageFileExtension.join(", "), "Information");
                    uploadControl.value = '';
                    isCValidFile = false;
                    break;
                }
                else if (uploadControl.files[i].size > 15728640) {
                    jAlert("Please check file size should be less than 15 MB.", "Information");
                    uploadControl.value = '';
                    isCValidFile = false;
                    break;
                }
            }
            else {
                jAlert("Please select File", "Information");
                isCValidFile = false;
                break;
            }
        }

        return isCValidFile;

    } catch (e) {
        isCValidFile = false;
        jAlert("Error occurred on validate file.", "Error");
        return isCValidFile;
    }
}
like image 300
Nad Avatar asked Mar 09 '23 16:03

Nad


2 Answers

You could check filenames with an object of valid file names and also you need to know which tab is active. you could use the following code

var Tabtype = document.getElementById('hdnType').value; 

if (Tabtype == "Panaromic") { 
    var validFileName = { 
         "120.jpg": 1, "150.jpg": 1, "180.jpg": 1, "210.jpg": 1, "240.jpg": 1, 
    } 
} 

if (Tabtype == "Satellite") { 
    var validFileName = { 
          "55.jpg": 1, "74.jpg": 1, "83.jpg": 1, "935.jpg": 1, 
    } 
} 

if (Tabtype == "SitePlot") { 
    var validFileName = 0; 
}


if (path != "") {
   if(validFileName && !isFileNameValid(path)){
       jAlert("Invalid File. Please upload a File with extension " + 
       ValidImageFileExtension.join(", "), "Information");
       uploadControl.value = '';
       isCValidFile = false;
       break;
   }
   ...
like image 136
fingerpich Avatar answered Mar 17 '23 16:03

fingerpich


In practice, I would do one of two things here. Either write custom adapters for the jQuery Validation plugin or write a custom jQuery plugin.

I typically use jQuery validation so I would write custom adapters for my needs. This is beneficial because once written I can reuse the rules over and over and can configure them by changing attributes on my Html Elements. It also has the benefit of dynamically displaying error messages and disabling form submission without the need for my interaction.

Here's a working example of using Jquery Validation:

$(document).ready(function() {
  $.validator.addMethod("filecount", function(value, element, params) {
    var maxcount = params;
    if (maxcount) {
      return $(element)[0].files.length <= Number(maxcount);
    }
    return true;
  }, "Maximum number of files exceeded");

  $.validator.addMethod("filename", function(value, element, params) {

    if (!params) return true;
    var names = params.split(',');
    var files = $(element)[0].files;
    for (var i = 0; i < files.length; i++) {
      var file = files[i];
      if (names.indexOf(file.name.toLowerCase()) == -1) return false;
    }
    return true;

  }, "File name is not allowed");

  var mb = 1048576;
  var defaultmaxfilesize = mb * 15;

  $.validator.addMethod("filesize", function(value, element, params) {
    var el = $(element);
    var parsedmaxval = parseInt(el.attr("data-val-filesize-max"));
    var maxval = null;
    if (isNaN(parsedmaxval) || parsedmaxval < 1 || parsedmaxval > 1048576000) {
      maxval = defaultmaxfilesize;
    } else {

      maxval = parsedmaxval;
    }

    var files = el[0].files;
    if (files != null && files.length > 0) {
      for (var i = 0; i < files.length; i++) {
        var file = files[i];
        var size = file.size;
        if (maxval < Number(size)) return false;
      }
    }
    return true;

  }, "File is too large");
});
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <title></title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.16.0/jquery.validate.min.js"></script>



  <script>
    $(document).ready(function() {

      $('input[type="file"]').change(function() {

        var el = $(this);

        if (!el.valid()) el.val('');
      });
    });
  </script>
</head>

<body>
  <form id="form1" name="form1" action="/root" method="Post">
    <div>
      <input type=file 
          ID="flufileUpload" 
          multiple 
          data-msg-filename="File name must be '120.jpg, 150.jpg, 180.jpg, 210.jpg, or 240.jpg'" 
          data-rule-filename="120.jpg,150.jpg,180.jpg,210.jpg,240.jpg" 
          data-msg-filesize="Maximum File Size is 15 MB" 
          data-rule-filesize="15728640"
          data-msg-filecount="You can only upload 5 files" 
          data-rule-filecount="5" />


    </div>
    <div>
      <input type=file 
          ID="flufileUpload2" 
          name="flufileUpload2" 
          multiple 
          data-msg-filename="File name must be '480.jpg, 640.jpg, or 1024.jpg'" 
          data-rule-filename="480.jpg,640.jpg,1024.jpg" 
          data-msg-filesize="Maximum File Size is 10 MB" 
          data-rule-filesize="10485760"
          data-msg-filecount="You can only upload 5 files" 
          data-rule-filecount="5" />
    </div>
  </form>
</body>

</html>

When working in MVC, I use jQuery Unobtrusive Validation adapters which have a slightly different api and for this question might look like this:

$.validator.unobtrusive.adapters.add("filecount", ["filecount"], function (options) {
    options.rules["filecount"] = "#" + options.params.param;
    options.messages["filecount"] = options.message;
});

$.validator.addMethod("filecount", function (value, element, params) {

    var maxcount = $(element).attr("data-val-filecount-max");
    if (maxcount) {
        return $(element)[0].files.length <= Number(maxcount);
    }
    return true;

});
$.validator.unobtrusive.adapters.add("filenames", ["filename"], function (options) {
    options.rules["filename"] = "#" + options.params.param;
    options.messages["filename"] = options.message;
});

$.validator.addMethod("filename", function (value, element, params) {

    var names = $(element).attr("data-val-filename-allowed").split(',');
    var files = $(element)[0].files;
    for (var i = 0; i < files.length; i++) {
        var file = files[i];
        if (names.indexOf(file.name.toLowerCase()) == -1) return false;
    }
    return true;

});

var mb = 1048576;
var defaultmaxfilesize = mb * 15;

$.validator.unobtrusive.adapters.add("filesize", ["filesize"], function (options) {
    options.rules["filesize"] = "#" + options.params.param;
    options.messages["filesize"] = options.message;
});

$.validator.addMethod("filesize", function (value, element, params) {
    var el = $(element);
    var parsedmaxval = parseInt(el.attr("data-val-filesize-max"));
    var maxval = null;
    if (isNaN(parsedmaxval) || parsedmaxval < 1 || parsedmaxval > 1048576000) {
        maxval = defaultmaxfilesize;
    } else {

        maxval = parsedmaxval;
    }

    var files = el[0].files;
    if (files != null && files.length > 0) {
        for (var i = 0; i < files.length; i++) {
            var file = files[i];
            var size = file.size;
            if (maxval < size) return false;
        }
    }
    return true;


});

I can then decorate my element with the validation attributes as required:

<input 
    type=file 
    ID="flufileUpload" 
    multiple data-val-filename="File name must be '120.jpg, 150.jpg, 180.jpg, 210.jpg, or 240.jpg'" 
    data-val-filename-allowed="120.jpg,150.jpg,180.jpg,210.jpg,240.jpg"
    data-val-filesize="Maximum File Size is 15 MB"
    data-val-filesize-max="15728640"
    data-val-filecount="You can only upload 5 files"
    data-val-filecount-max="5"
/>

And using different values for a different element is just a matter of changing the attributes:

<input 
    type=file 
    ID="flufileUpload" 
    multiple data-val-filename="File name must be '480.jpg, 640.jpg, or 1024.jpg'" 
    data-val-filename-allowed="480.jpg,640.jpg,1024.jpg"
    data-val-filesize="Maximum File Size is 10 MB"
    data-val-filesize-max="10485760"
/>

The other approach I would take is creating a custom jQuery plugin. This allows for custom functions that can be configured by passing options to the the plugin. I would typically only take this approach if I need custom functionality, such as automatically uploading the files after they passed validation using AJAX or if granular control of the error messages was needed.

Once written your plugin can be called with custom options as needed like this:

 <script>
        $(document).ready(function () {
            $('#flufileUpload').fileValidate({ maxcount: 5, allowedFileNames: "file1.html,file2.html,file3.html" });
        });
    </script>

A custom plugin would look like this, but typically you would put the plugin JavaScript in its own file so you can reuse it as needed:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <style type="text/css">
        #qrcode {
            width: 160px;
            height: 160px;
            margin-top: 15px;
        }
    </style>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script>
        (function ($) {
            $.fn.fileValidate = function (options) {
                var Container = $(this);
                var id = Container.attr("id");
                var mb = 1048576;
                var settings = $.extend({
                    maxfilesize: mb * 15,
                    allowMultiple: true,
                    allowedFileNames: null,
                    allowedExtensions: ".png,.gif,tif,.tiff,.jpg,.jpeg,.bmp,.pdf",
                    maxcount: -1,
                    documentRemoveCallback: null,
                    target: null,
                    errlab: null
                }, options);

                var getErrorLabel = function () {
                    var validator = $('span[data-val-msgfor="' + id + "']");
                    if (validator.length == 0) {
                        validator = $("<span/>");
                        validator.attr("data-val-msgfor", id);
                        Container.parent().append(validator);
                    }
                    return validator;
                }
                var formatBytes = function formatBytes(bytes, decimals) {
                    if (bytes == 0) return '0 Bytes';
                    var k = 1024,
                        dm = decimals + 1 || 3,
                        sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
                        i = Math.floor(Math.log(bytes) / Math.log(k));
                    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
                };
                var validExtensions = (settings.allowedExtensions) ? settings.allowedExtensions.split(",") : [];
                var validFileNames = (settings.allowedFileNames) ? settings.allowedFileNames.split(",") : [];
                var errlab = settings.errlab || getErrorLabel();
                var hasError = false;
                var errors = [];
                var setError = function (s) {
                    errors.push(s);

                }
                var getErrorHtml = function () {
                    var ul = $("<ul>");
                    errors.forEach(function (err) { ul.append($("<li>").html(err)); });
                    return ul;
                }
                var validateSize = function (files) {
                    for (var i = 0; i < files.length; i++) {
                        if (files[i].size > settings.maxfilesize) return false;
                    }
                    return true;
                }
                var validateExenstions = function (files) {
                    var invalid = [];
                    for (var i = 0; i < files.length; i++) {
                        var file = files[i];
                        var parts = file.name.split(".");
                        var ext = parts[parts.length - 1].toLowerCase();
                        var found = false;
                        validExtensions.forEach(function (x) {
                            if (x == ext) found = true;
                        });
                        !found && invalid.indexOf(ext) == -1 && invalid.push(ext);
                        if (!found) return false;
                    }
                    return true;

                }
                var validateFileNames = function (files) {
                    for (var i = 0; i < files.length; i++) {
                        var file = files[i];
                        if (validFileNames.indexOf(file.name) == -1) return false;
                    }
                    return true;
                }
                var onDocumentChange = function () {
                    errors = [];
                    var el = Container[0];
                    errlab.html('');
                    var files = el.files;

                    settings.maxcount > 0 && files.length > settings.maxcount && setError("You may only select " + settings.maxcount + " file(s).");
                    validExtensions.length > 0 && !validateExenstions(files) && setError("File extensions must be '" + settings.allowedExtensions + "'.");
                    settings.maxfilesize > 0 && !validateSize(files) && setError("Maximum file size is " + formatBytes(settings.maxfilesize) + ".");
                    validFileNames.length > 0 && !validateFileNames(files) && setError("Files names must be one of the following: '" + settings.allowedFileNames + "'.");
                    errors.length > 0 && $(Container).val(''), errlab.html('').append(getErrorHtml());
                    if (settings.documentChangeCallBack) { window.setTimeout(settings.documentChangeCallBack, 1); }
                };
                Container.change(onDocumentChange);
            };
        }(jQuery));
    </script>
</head>
<body>




    <input type=file ID="flufileUpload" multiple />
    <script>
      
    </script>
    <script>
        $(document).ready(function () {
            $('#flufileUpload').fileValidate({ maxcount: 5, allowedFileNames: "file1.html,file2.html,file3.html" });
        });
    </script>

</body>
</html>
like image 29
Alexander Higgins Avatar answered Mar 17 '23 15:03

Alexander Higgins