Integrating New Google Maps Autocomplete API into Django Project

I'm using the new Google PlaceAutocompleteElement() API function (not the legacy google.maps.places.Autocomplete) and would like help integrating it into my Django project.

Specifically, I want to add an address search bar to my application.html template.

I've tried connecting the initMap() JavaScript function to the form in several ways, updating all the corresponding files below, but the form submission always fails, and the data never reaches the database.

Here's more information about the this Google API: Place Autocomplete Element

Take a look of my attempt before the address implementation:

models.py

class Applicant(models.Model):
    Name = models.CharField(max_length=101)
    DOB = models.DateField()
    High_School = models.CharField(max_length=100)
    Major = models.CharField(max_length=100)
    SSN = models.CharField(max_length=11)
    Phone = models.CharField(max_length=15)
    
    def __str__(self):
        return self.Name

views.py

def application_page(request):
    form = ApplicationForm()
    return render(request, "DunesApp/application.html", {
        'form': form,
        'google_maps_key': settings.GOOGLE_MAPS_API_KEY
    })

def submit_application(request):
    if request.method == "POST":
        form = ApplicationForm(request.POST)
        if form.is_valid():
            form.save()
            return JsonResponse({"status": "success"})
    return JsonResponse({"status": "error"})

forms.py

class ApplicationForm(forms.ModelForm):
    class Meta:
        model = Applicant
        fields = "__all__"

script.js (called inside layout.html)

function submitApplication() {
    const form = document.getElementById('application-form');
    const formData = new FormData(form);

    fetch('/submit_application/', {
        method: 'POST',
        body: formData,
        headers: {
            'X-CSRFToken': formData.get('csrfmiddlewaretoken')
        }
    })
    .then(response => response.json())
    .then(data => {
        const messageBox = document.getElementById('application-message');

        if (data.status === 'success') {
            messageBox.className = 'alert alert-success mt-3';
            messageBox.innerText = 'Application submitted successfully!';
            messageBox.classList.remove('d-none');
            form.reset();
        } else {
            messageBox.className = 'alert alert-danger mt-3';
            messageBox.innerText = 'Submission failed. Please try again.';
            messageBox.classList.remove('d-none');
        }
    })
    .catch(error => {
        const messageBox = document.getElementById('application-message');
        messageBox.className = 'alert alert-danger mt-3';
        messageBox.innerText = 'An error occurred. Please try again.';
        messageBox.classList.remove('d-none');
        console.error('Error:', error);
    });
}

application.html

{% extends 'DunesApp/layout.html' %}
{% load form_tags %}
{% block content %}
  <h2 class="mb-4">Student Application Form</h2>

  <div class="card p-4 shadow-sm">
    <form id="application-form">
      {% csrf_token %}

      <div class="mb-3">
        <label for="id_name" class="form-label">Full Name:</label>
        {{ form.Name|add_class:'form-control' }}
      </div>

      <div class="mb-3">
        <label for="id_dob" class="form-label">Date of Birth:</label>
        {{ form.DOB|add_class:'form-control' }}
      </div>

      <div class="mb-3">
        <label for="id_ssn" class="form-label">Social Security Number:</label>
        {{ form.SSN|add_class:'form-control' }}
      </div>

      <!-- Google Address Autocomplete will be here -->

      <div class="mb-3">
        <label for="id_phone" class="form-label">Phone Number:</label>
        {{ form.Phone|add_class:'form-control' }}
      </div>

      <div class="mb-3">
        <label for="id_high_school" class="form-label">High School:</label>
        {{ form.High_School|add_class:'form-control' }}
      </div>

      <div class="mb-3">
        <label for="id_major" class="form-label">Intended Major:</label>
        {{ form.Major|add_class:'form-select' }}
      </div>

      <button type="button" class="btn btn-primary" onclick="submitApplication()">Submit Application</button>
    </form>
    <div id="application-message" class="alert mt-3 d-none"></div>
  </div>

Desired Design

Desired Design

Back to Top