Create a Custom Multiple File Uploader with HTML, CSS, and JavaScript

Faraz

By Faraz -

Learn how to design and code a personalized multiple file uploader using HTML, CSS, and Javascript. Follow our beginner-friendly guide with complete source code.


Create a Custom Multiple File Uploader with HTML, CSS, and Javascript.jpg

Table of Contents

  1. Project Introduction
  2. HTML Code
  3. CSS Code
  4. JavaScript Code
  5. Preview
  6. Conclusion

Welcome to our comprehensive tutorial on creating a versatile and efficient multiple-file uploader using the dynamic trio of HTML, CSS, and JavaScript. Whether you're a seasoned developer looking to enhance your website's functionality or a beginner eager to dive into the world of web development, this step-by-step guide will equip you with the skills needed to build a fully functional file uploading mechanism.

In today's digital landscape, seamless file uploading is essential for websites ranging from social media platforms to e-commerce sites. Our tutorial goes beyond the basics, ensuring that you not only grasp the fundamental concepts but also gain insights into customization and troubleshooting.

File uploading might sound like a complex task, but fear not! We've broken down the process into simple, digestible steps that even beginners can follow with ease. By the end of this tutorial, you'll not only have a working multiple file uploader at your fingertips but also a solid understanding of the underlying HTML, CSS, and JavaScript principles.

Why create a custom multiple file uploader, you ask? While many pre-built solutions are available, crafting your own uploader offers unparalleled control over design, functionality, and integration into your existing projects. You'll be able to tailor the uploader to your exact requirements, ensuring a seamless user experience that aligns perfectly with your website's aesthetics.

Throughout this guide, we'll not only show you how to create the uploader, but we'll also provide you with the rationale behind each step. Understanding the "why" behind the "how" will empower you to troubleshoot and adapt the uploader to meet future challenges and opportunities.

So, if you're ready to embark on a journey to create a custom multiple file uploader that'll elevate your website's capabilities, grab your favorite code editor, and let's get started with the first step: setting up the HTML structure. Your newfound file-uploading prowess awaits!

Credit: Rob Copeland

Source Code

Step 1 (HTML Code):

To get started, we will first need to create a basic HTML file. In this file, we will include the main structure for our file uploader.

After creating the files just paste the following codes into your file. Make sure to save your HTML document with a .html extension, so that it can be properly viewed in a web browser.

Here's an explanation of each part of the code:

1. <!DOCTYPE html>: This declaration specifies that the document is written in HTML5, the latest version of the Hypertext Markup Language.

2. <html lang="en">: The opening <html> tag defines the beginning of the HTML document. The lang attribute is set to "en," indicating that the content is in English.

3. <head>: The <head> section contains metadata about the webpage, including links to external resources and character encoding settings.

  • <title>Home</title>: This sets the title of the webpage, which is displayed in the browser's title bar or tab.
  • <meta charset="UTF-8" />: This meta tag specifies the character encoding of the document, ensuring that text is displayed correctly across different devices and browsers.
  • <meta name="viewport" content="width=device-width" />: This meta tag defines the viewport settings, primarily affecting the layout and scaling of the webpage on various devices.
  • <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">: This link imports an external stylesheet (CSS) named "normalize.min.css" from the provided URL. The stylesheet helps to ensure consistent rendering of HTML elements across different browsers.
  • <link rel="stylesheet" href="styles.css" />: Another link to an external stylesheet named "styles.css" located in the same directory as the HTML file. This stylesheet likely contains custom styling for the webpage.

4. <body>: The <body> tag encloses the main content of the webpage that is visible to users.

  • <form method="post" class="file-uploader" action="" enctype="multipart/form-data">: This <form> element creates a file upload form. It uses the HTTP POST method to send data, has a CSS class "file-uploader," and specifies no action URL (action attribute is empty). The enctype attribute is set to "multipart/form-data" to handle file uploads.
  • <div class="file-uploader__message-area">: A container <div> for displaying a message related to file uploads.
  • <p>Select a file to upload</p>: A paragraph element containing the instruction for users to select a file for uploading.
  • <div class="file-chooser">: A container <div> for the file input field.
  • <input class="file-chooser__input" type="file" multiple>: An <input> element of type "file," allowing users to choose one or more files for upload. It has a CSS class "file-chooser__input."
  • <input class="file-uploader__submit-button" type="submit" value="Upload">: An <input> element of type "submit" that serves as a button to submit the file(s) selected for uploading. It has a CSS class "file-uploader__submit-button."

5. <script src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>: This <script> tag links to an external JavaScript library named jQuery. It's hosted on a content delivery network (CDN). jQuery is a popular library that simplifies JavaScript programming and provides useful functionalities.

6. <script src="script.js"></script>: Another <script> tag that links to an external JavaScript file named "script.js" located in the same directory as the HTML file. This file likely contains custom JavaScript code to enhance the functionality of the webpage.

This is the basic structure of our multiple file uploader using HTML, and now we can move on to styling it using CSS.

Step 2 (CSS Code):

Once the basic HTML structure of the file uploader is in place, the next step is to add styling to the file uploader using CSS.

Next, we will create our CSS file. In this file, we will use some basic CSS rules to style our uploader.

Here's a breakdown of each section:

1. .file-uploader: This class defines styles for the main file uploader container. It sets the background color, border radius, and text color.

2. .file-uploader__message-area: This class defines styles for the message area within the file uploader. It sets the font size, padding, text alignment, and text color.

3. .file-list: This class defines styles for a list of uploaded files. It sets the background color and font size.

4. .file-list__name: This class styles the name of the uploaded files within the list. It applies styles to handle text overflow by showing an ellipsis, and ensures that the text doesn't wrap.

5. .file-list li: This targets each list item (file entry) in the file list. It sets the height, line height, margin, border, and overflow properties.

6. .removal-button: This class styles a removal button, possibly for deleting uploaded files. It sets the width, background color, and text color of the button. The ::before pseudo-element is used to add a "X" content before the button's text.

7. .file-chooser: This class styles a file chooser area, where users can select files for uploading. It defines padding and a transition effect for background color and height changes.

8. .file-chooser p: This targets paragraphs within the file chooser area and sets the font size and padding.

9. **.file-uploader ***: This targets all child elements of the .file-uploader class and sets them to have a block display, effectively stacking them vertically.

10. .file-uploader input[type=submit]: This targets the submit button within the file uploader. It sets the margin, float, and vertical alignment.

11. .file-chooser__input: This targets an input element within the file chooser area. It sets margins to center align the input.

12. .file-uploader__submit-button: This styles the submit button of the file uploader. It sets the width, border, font size, padding, background color, and text color. On hover, the background color changes.

13. .file-list li:after, .file-uploader:after: This uses pseudo-elements to clear floats within list items and the file uploader, ensuring proper layout.

14. .hidden: This class is used to hide elements using the display property.

15. .hidden input: This targets hidden input elements (possibly for file uploads) within elements with the .hidden class.

16. .error: This class defines styles for an error message area. It sets the background color and text color.

17. Universal selector and box-sizing: The '*' selector applies the box-sizing property to all elements, ensuring consistent box model behavior.

18. ul, li: These selectors reset margins and paddings for unordered lists and list items.

This will give our multiple file uploader an upgraded presentation. Create a CSS file with the name of styles.css and paste the given codes into your CSS file. Remember that you must create a file with the .css extension.

.file-uploader {
  background-color: #dbefe9;
  border-radius: 3px;
  color: #242424;
}

.file-uploader__message-area {
  font-size: 18px;
  padding: 1em;
  text-align: center;
  color: #377a65;
}

.file-list {
  background-color: white;
  font-size: 16px;
}

.file-list__name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.file-list li {
  height: 50px;
  line-height: 50px;
  margin-left: 0.5em;
  border: none;
  overflow: hidden;
}

.removal-button {
  width: 20%;
  border: none;
  background-color: #d65d38;
  color: white;
}
.removal-button::before {
  content: "X";
}
.removal-button:focus {
  outline: 0;
}

.file-chooser {
  padding: 1em;
  transition: background-color 1s, height 1s;
}
.file-chooser p {
  font-size: 18px;
  padding-top: 1em;
}

.file-uploader {
  max-width: 400px;
  height: auto;
  margin: 2em auto;
}
.file-uploader * {
  display: block;
}
.file-uploader input[type=submit] {
  margin-top: 2em;
  float: right;
}

.file-list {
  margin: 0 auto;
  max-width: 90%;
}

.file-list__name {
  max-width: 70%;
  float: left;
}

.removal-button {
  display: inline-block;
  height: 100%;
  float: right;
}

.file-chooser {
  width: 90%;
  margin: 0.5em auto;
}

.file-chooser__input {
  margin: 0 auto;
}

.file-uploader__submit-button {
  width: 100%;
  border: none;
  font-size: 1.5em;
  padding: 1em;
  background-color: #72bfa7;
  color: white;
}
.file-uploader__submit-button:hover {
  background-color: #a7d7c8;
}

.file-list li:after, .file-uploader:after {
  content: "";
  display: table;
  clear: both;
}

.hidden {
  display: none;
}
.hidden input {
  display: none;
}

.error {
  background-color: #d65d38;
  color: white;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

ul,
li {
  margin: 0;
  padding: 0;
} 

Step 3 (JavaScript Code):

Finally, we need to create a function in JavaScript. This JavaScript code defines a jQuery plugin called "uploader" that enhances the functionality of file uploading on a web page. The plugin is designed to work with HTML elements that have the class "fileUploader". Here's a breakdown of what the code does:

1. The code is enclosed in an immediately-invoked function expression (IIFE) that takes the jQuery object as an argument ($). This helps prevent any potential conflicts with other JavaScript code.

2. Inside the IIFE, a jQuery plugin named "uploader" is defined as a method that can be called on jQuery objects. It accepts an optional "options" parameter.

3. The settings object is created by extending a default configuration object with the provided "options". The default settings include messages, error messages, and accepted file types.

4. An uploadId variable is initialized to keep track of the unique IDs associated with each uploaded file.

5. The code finds the element with the class "file-uploader__message-area" and updates its text to display the initial message provided in the options or the default message.

6. Two elements, "fileList" and "hiddenInputs", are created using jQuery to hold the list of uploaded files and hidden input fields, respectively. These elements are added to the DOM after the "file-uploader__message-area" element.

7. An event handler is attached to the change event of the file input element with the class "file-chooser__input". This event is triggered when a file is selected for uploading.

8. Inside the event handler, the selected files are retrieved from the file input element.

9. For each selected file, the code checks if the file name matches any of the accepted file types specified in the settings.

10. If the file name matches a valid file type, the following actions are taken:

  • The "real" file input element is moved to the "hidden-inputs" container.
  • A clone of the file input element is added back to the "file-chooser" container.
  • The file name and a removal button are added to the "file-list".
  • A removal button event handler is attached to the newly added button.

11. If the file name does not match a valid file type, an error message is displayed, and the file input element is marked as having an error.

12. The checkFile function is defined to validate whether a file's extension matches any of the accepted file types. It iterates through the list of accepted file types and uses regular expressions to determine if the file name has a matching extension.

13. The IIFE ends with the jQuery plugin definition.

14. After the plugin definition, a document-ready event handler is used to initialize the plugin on elements with the class "fileUploader". The uploader is initialized with a specific message to be displayed in the message area.

Create a JavaScript file with the name of script.js and paste the given codes into your JavaScript file and make sure it's linked properly to your HTML document, so that the scripts are executed on the page. Remember, you’ve to create a file with .js extension.

(function ($) {
  $.fn.uploader = function (options) {
    var settings = $.extend(
      {
        MessageAreaText: "No files selected.",
        MessageAreaTextWithFiles: "File List:",
        DefaultErrorMessage: "Unable to open this file.",
        BadTypeErrorMessage: "We cannot accept this file type at this time.",
        acceptedFileTypes: [
          "pdf","jpg","gif","jpeg","bmp","tif","tiff","png","xps","doc","docx","fax","wmp","ico","txt","cs","rtf","xls","xlsx"
        ]
      },
      options
    );

    var uploadId = 1;
    //update the messaging
    $(".file-uploader__message-area p").text(
      options.MessageAreaText || settings.MessageAreaText
    );

    //create and add the file list and the hidden input list
    var fileList = $('<ul class="file-list"></ul>');
    var hiddenInputs = $('<div class="hidden-inputs hidden"></div>');
    $(".file-uploader__message-area").after(fileList);
    $(".file-list").after(hiddenInputs);

    //when choosing a file, add the name to the list and copy the file input into the hidden inputs
    $(".file-chooser__input").on("change", function () {
      var files = document.querySelector(".file-chooser__input").files;

      for (var i = 0; i < files.length; i++) {
        console.log(files[i]);

        var file = files[i];
        var fileName = file.name.match(/([^\\\/]+)$/)[0];

        //clear any error condition
        $(".file-chooser").removeClass("error");
        $(".error-message").remove();

        //validate the file
        var check = checkFile(fileName);
        if (check === "valid") {
          // move the 'real' one to hidden list
          $(".hidden-inputs").append($(".file-chooser__input"));

          //insert a clone after the hiddens (copy the event handlers too)
          $(".file-chooser").append(
            $(".file-chooser__input").clone({ withDataAndEvents: true })
          );

          //add the name and a remove button to the file-list
          $(".file-list").append(
            '<li style="display: none;"><span class="file-list__name">' +
              fileName +
              '</span><button class="removal-button" data-uploadid="' +
              uploadId +
              '"></button></li>'
          );
          $(".file-list").find("li:last").show(800);

          //removal button handler
          $(".removal-button").on("click", function (e) {
            e.preventDefault();

            //remove the corresponding hidden input
            $(
              '.hidden-inputs input[data-uploadid="' +
                $(this).data("uploadid") +
                '"]'
            ).remove();

            //remove the name from file-list that corresponds to the button clicked
            $(this)
              .parent()
              .hide("puff")
              .delay(10)
              .queue(function () {
                $(this).remove();
              });

            //if the list is now empty, change the text back
            if ($(".file-list li").length === 0) {
              $(".file-uploader__message-area").text(
                options.MessageAreaText || settings.MessageAreaText
              );
            }
          });

          //so the event handler works on the new "real" one
          $(".hidden-inputs .file-chooser__input")
            .removeClass("file-chooser__input")
            .attr("data-uploadId", uploadId);

          //update the message area
          $(".file-uploader__message-area").text(
            options.MessageAreaTextWithFiles ||
              settings.MessageAreaTextWithFiles
          );

          uploadId++;
        } else {
          //indicate that the file is not ok
          $(".file-chooser").addClass("error");
          var errorText =
            options.DefaultErrorMessage || settings.DefaultErrorMessage;

          if (check === "badFileName") {
            errorText =
              options.BadTypeErrorMessage || settings.BadTypeErrorMessage;
          }

          $(".file-chooser__input").after(
            '<p class="error-message">' + errorText + "</p>"
          );
        }
      }
    });

    var checkFile = function (fileName) {
      var accepted = "invalid",
        acceptedFileTypes =
          this.acceptedFileTypes || settings.acceptedFileTypes,
        regex;

      for (var i = 0; i < acceptedFileTypes.length; i++) {
        regex = new RegExp("\\." + acceptedFileTypes[i] + "$", "i");

        if (regex.test(fileName)) {
          accepted = "valid";
          break;
        } else {
          accepted = "badFileName";
        }
      }

      return accepted;
    };
  };
})($);

//init
$(document).ready(function () {
  $(".fileUploader").uploader({
    MessageAreaText: "No files selected. Please select a file."
  });
});

Final Output:

Create a Custom Multiple File Uploader with HTML, CSS, and Javascript.gif

Conclusion:

Congratulations on successfully navigating the world of HTML, CSS, and JavaScript to create your very own multiple-file uploader! You've embarked on a journey that began with the building blocks of code and ended with a functional and visually appealing tool that can greatly enhance your website's user experience.

Throughout this tutorial, you've learned not only how to construct the uploader itself but also the principles behind each component. From setting up the HTML structure to styling with CSS, and implementing dynamic interactivity with JavaScript, you've gained a solid foundation in web development techniques that can be applied to a myriad of projects.

By now, you understand the power of customization. Creating your own file uploader empowers you to tailor its behavior, appearance, and functionality to your exact needs. Whether you're running a portfolio website, managing an e-commerce platform, or nurturing a social networking site, this uploader will seamlessly integrate and elevate the user experience.

Remember, this is just the beginning. As you continue your coding journey, you'll find countless opportunities to refine and expand upon what you've learned here. Experiment with additional features, explore responsive design principles, and dive deeper into JavaScript's capabilities to take your uploader to new heights.

We hope you've enjoyed this tutorial and gained confidence in your coding abilities. Keep exploring, keep learning, and keep creating. The world of web development is at your fingertips, and your newly acquired skills are your passport to building incredible digital experiences.

Thank you for joining us on this educational adventure. Here's to your continued success as a web developer, armed with the knowledge of how to Create Multiple File Uploader using HTML, CSS, and JavaScript. Happy coding!

That’s a wrap!

I hope you enjoyed this post. Now, with these examples, you can create your own amazing page.

Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee.

And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!

Thanks!
Faraz 😊

End of the article

Subscribe to my Newsletter

Get the latest posts delivered right to your inbox


Latest Post