Update the Django HTML Form with JavaScript and a Progress Bar

A Simple Example of Using JavaScript to Show Form Upload When a FileField has Large file Such as Video
November 2, 2024 by
Update the Django HTML Form with JavaScript and a Progress Bar
Hamed Mohammadi
| No comments yet

In this post we discuss how to implement a file upload progress bar using JavaScript’s API with the FormData object. This approach allows for the same real-time progress tracking while keeping things simpler and more modern.

Add a <progress> element for visual feedback.

Use JavaScript's fetch API to handle the file upload and track progress.

<!-- HTML Form -->
<form id="uploadForm" method="post" enctype="multipart/form-data" action="{% url 'upload_view' %}">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Upload</button>
</form>

<!-- Progress Bar -->
<progress id="progressBar" value="0" max="100" style="width: 100%; display: none;"></progress>
<span id="progressText"></span>

<script>
const form = document.getElementById("uploadForm");
const progressBar = document.getElementById("progressBar");
const progressText = document.getElementById("progressText");

form.onsubmit = function (event) {
  event.preventDefault(); // Prevent default form submission
  const formData = new FormData(form);

  // Get the CSRF token from the form
  const csrfToken = form.querySelector("[name=csrfmiddlewaretoken]").value;

  // Show progress bar
  progressBar.style.display = "block";

  // Use XMLHttpRequest to upload the file with progress tracking
  const xhr = new XMLHttpRequest();
  xhr.open("POST", form.action, true);
  xhr.setRequestHeader("X-CSRFToken", csrfToken);

  // Track upload progress
  xhr.upload.onprogress = function (event) {
    if (event.lengthComputable) {
      const percentComplete = (event.loaded / event.total) * 100;
      progressBar.value = percentComplete;
      progressText.textContent = `${Math.round(percentComplete)}% uploaded`;
    }
  };

  // Handle the response
  xhr.onload = function () {
    if (xhr.status === 200) {
      // Reset progress bar and display success message
      alert("File uploaded successfully!");
      progressBar.style.display = "none";
      progressText.textContent = "";

      // Redirect to the success URL
      window.location.href = "/album/"; // Use the success URL from your Django view context
    } else {
      alert("Error uploading file");
    }
  };

  // Handle any network errors
  xhr.onerror = function () {
    alert("An error occurred while uploading the file.");
  };

  // Send the form data
  xhr.send(formData);
};

</script>

Adjust the Django View to Handle the POST Request

This view receives the uploaded file data, validates it, and saves it if valid. The view then returns a JSON response indicating success or failure.


from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt  # Only if CSRF tokens aren’t working with fetch API
def upload_view(request):
    if request.method == "POST":
        form = YourUploadForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()  # Save the file
            return JsonResponse({"status": "success"})
        else:
            return JsonResponse({"status": "error", "errors": form.errors}, status=400)
    return JsonResponse({"status": "error", "message": "Invalid request"}, status=400)


Explanation

  1. XMLHttpRequest: This allows tracking upload progress, unlike fetch.
  2. Set CSRF Token: The X-CSRFToken header is set explicitly in the XMLHttpRequest for Django’s CSRF protection.
  3. Track Progress: The xhr.upload.onprogress event is used to update the progress bar and display the upload percentage.

Summary

This code should provide a working upload progress bar that accurately reflects the upload status of large files. With this setup, the progress bar should update correctly during the file upload.


Update the Django HTML Form with JavaScript and a Progress Bar
Hamed Mohammadi November 2, 2024
Share this post
Tags
Archive

Please visit our blog at:

https://zehabsd.com/blog

A platform for Flash Stories:

https://readflashy.com

A platform for Persian Literature Lovers:

https://sarayesokhan.com

Sign in to leave a comment