Form With Image Previews – No JQuery

By on October 8th, 2019 in   Ajax CSS Front-End HTML JavaScript

Forms are everywhere, they are like a portal to another dimension. Form is a standard way of transferring data from one point to another in the world of internet. For example, from your browser to server, from your mobile apps to your social media profiles (again a server). They are literally everywhere and we use them every day without realizing.

In this blog, I will be showing you how to create a simple form that shows image previews prior to their upload. The aim of this article is to provide an approach that is simple, efficient and uses only what is available within the browser i.e. HTML, CSS and JavaScript.

Let’s get started.

This article will have the following:

  • Demo file (downloadable for self-study)
  • Explanation of following
    1. Basic HTML Structure
    2. CSS for layout (using flexbox)
    3. JavaScript – using FileReader
    4. Additional Ajax Links – for sending data to server (optional)
  • Conclusion

Final demo product will have the following properties:

  • Compatibility with all major browsers
  • Very less loading time
  • Responsive on all screen widths
  • Minimum code with no external library

Demo file (downloadable for self-study)

Download demo file (.zip) here

Explanation

1. Basic HTML Structure

Hierarchy of elements:

Form
   Fieldset
      Form heading - Legend
      Title Input
      Description Textarea
      File Upload Box Div
         Upload Box Left - File Input
            Label for File Element
               File Input Element
               Label Text Span
         File Upload Box Right (Existing Images Preview) 
            Images Div
               Image Elements

HTML of basic structure (only content within the body):

<form class="form_outer" id="uploadForm" enctype="multipart/form-data" action="#" method="POST">
        <fieldset>
            <legend>Create Post</legend>
            Title:<br>
            <input type="text" name="title" value=""><br>
            Description:<br>
            <textarea name="description" rows="10" value=""></textarea><br>

            <div class="file_upload_box">
                <div class="file_upload_box_left">
                    <label class="myLabel">
                        <input type="file" id="featured_image" name="featured_image" value=""
                            accept="image/x-png,image/gif,image/jpeg" />
                        <span>Select Featured Image:</span>
                    </label>
                    <div class="image_preview"></div>
                </div>
                <div class="file_upload_box_right myLabel">
                    Current Images:
                    <div class="post_images">
                        <img class="icon" src="images/image 1.png" />
                        <img class="icon" src="images/image 2.png" />
                    </div>
                </div>
            </div>

            <div class="file_upload_box">
                <div class="file_upload_box_left">
                    <label class="myLabel">
                        <input type="file" id="userPhoto" name="userPhoto" value="" multiple
                            accept="image/x-png,image/gif,image/jpeg" />
                        <span>Select Post Images:</span>
                    </label>
                    <div class="image_preview"></div>
                </div>
                <div class="file_upload_box_right myLabel">
                    Current Images:
                    <div class="post_images">
                        <img class="icon" src="images/image 3.png" />
                        <img class="icon" src="images/image 4.png" />
                    </div>
                </div>
            </div>

            <input name="submit" type="submit" value="Create Post">

            <span id="status"></span>
        </fieldset>
    </form>

Above HTML will render the a simple structure as shown (nothing special)

2. CSS for layout (using flexbox)

Apart from standard styling, given CSS will do the following:

  • Set container elements as flex-boxes so the form is responsive
  • Setting flex directions
  • Setting File Upload input elements not to be displayed
  • Using styled labels in place of File Input elements because of their special properties
* {
    box-sizing: border-box;
}

html, body {
    background-color: whitesmoke;
    font-family: Verdana, Geneva, Tahoma, sans-serif;
    display: flex;
    width: -webkit-fill-available;
    align-items: center;
    justify-content: center;
}

#uploadForm {
    width: 50%;
}

fieldset {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    align-content: flex-start;
    flex-wrap: wrap;
}

fieldset input, fieldset textarea {
    width: 100%;
    padding: 5px;
    margin: 5px 0px;
    font-family: inherit;
}

input[type=file] {
    padding: 5px 0px;
}

.icon {
    height: 60px;
    width: 90px;
    margin: 5px;
    display: inline-block;
}

label.myLabel input[type="file"] {
    position: absolute;
    display: none;
}

.myLabel {
    border: 2px solid #AAA;
    padding: 5px 5px;
    margin: 2px;
    background: #DDD;
    min-width: 200px;
    text-align: center;
    cursor: pointer;
    color: #4A4;
}

.myLabel:hover {
    background: #CCC;
}

.file_upload_box {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    margin: 5px auto;
}

.file_upload_box_left, .file_upload_box_right {
    flex: 45%;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}

As a result of the above styling, our form should look somewhat like this:

Form After CSS
Form After CSS

3. JavaScript – using FileReader

  • Binding both form elements to “loadPreview” the event listeners
  • Creating the loadPreview event lister function which does the following:
    • Selects the clicked element
    • Selecting its corresponding preview area by hierarchical selection
    • Clearing the previous preview images
    • Looping through the selected files
    • Creating and Registering a FileReader Object for every image/file
    • Creating the onload function to set file as image for each image
    • Setting each file to be read as data for format compatibility using local readAsDataURL
<script>
        document.getElementById("featured_image").addEventListener("change", loadPreview);
        document.getElementById("userPhoto").addEventListener("change", loadPreview);

        function loadPreview() {

            let input = this;
            let preview_area = this.parentNode.parentNode.childNodes[3];
            preview_area.innerHTML = "";

            if (input.files) {
                var filesAmount = input.files.length;

                for (i = 0; i < filesAmount; i++) {
                    var reader = new FileReader();

                    reader.onload = function (event) {

                        let img = document.createElement("img");
                        img.src=event.target.result;
                        img.className="icon";
                        preview_area.appendChild(img);
                    }

                    reader.readAsDataURL(input.files[i]);
                }
            }
        };
    </script>

As a result of above code, the fiinal ready-to-use form is given as:

HTML form with image previews
HTML form with image previews

4. Additional Ajax – for sending data to server (optional)

Although sending data to the webserver using form is out of scope, and pure JavaScript solution is rather lengthy but it can be achieved in a simple step by step process using XmlHttpRequest like given in these links:

Conclusion:

In conclusion, this article provides a simple approach for creating forms that are both useful and functional. Otherwise, there may be endless ways to make anything in the world of development.

Moreover, given form can easily be customized for personal use because of its simplicity. Feel free to post links to your own customized forms in the comments.

If you are interested in approach-based development using local resources, check out my other articles on Sidebar and Navigation Menu as well.

Let me know if you have any questions or require assistance in any step. Till next time.

One response to “Form With Image Previews – No JQuery”

  1. […] check out my other articles if you like approach-based programming. Also, refer to my article on Form With Image Previews if you want to see how the form in the demo was made.That is it for now. Let me know if you have […]

Leave a Reply

Your email address will not be published. Required fields are marked *