javascriptpythondjangodjango-forms

What is the equivalent of <input id="id"> with Django form


I am trying to input results from Autocomplete in (a.js file) into a Django form (html).

Currently the html file looks like this:

Template:

<input class="field" id="street_number" disabled="true" />

Obvioulsy, I cannot input directly {{form.street_number}}. I have found a few posts on the topic, (in particular this one: How to get form fields' id in Django), but I am not too sure to understand how this solves the problem.

.js file

 function initAutocomplete(){  
      autocomplete = new google.maps.places.Autocomplete(document.getElementById("autocomplete"),{
        componentRestrictions: {'country':['uk']},
        fields: ['name','geometry','address_components'],
        types:['establishment','geocode']
      });
    
       autocomplete.addListener('place_changed', fillInAddress );
    }
    
    function fillInAddress(){
        // Get the place details from the autocomplete object.
        var place = autocomplete.getPlace();
        //showsdiffrent address components (click on 'inspect' on webpage to see)
        console.log(place);
    
         document.getElementById('business').value = place.name;
            //loop through address components detailed in consol 
            for (let i = 0; i < place.address_components.length; i++) {
              for (let j = 0; j < place.address_components[i].types.length; j++) {
                ...
                if (place.address_components[i].types[j] === "street_number") {
                document.getElementById('street_number').value = place.address_components[i].short_name;
                } ...

I suppose the question is how do I translate <input id="id"> into django form terms? Maybe there is a possibility to apply an id in the django form.py itself?

I tried a solution found on here, but I am getting an error saying TextInput is not defined.

forms.py:

 class VenueForm(ModelForm):
        address = forms.CharField(max_length=100, required=True, widget = forms.HiddenInput())
    
        class Meta:
            model = Venue
            fields = ['address']
        
        def __init__(self, *args, **kwargs):
                super(VenueForm, self).__init__(*args, **kwargs)
                self.fields['address'].widget = TextInput(attrs={
                    'id': 'street_number'})

Solution

  • Ok, so here is the solution I worked out.

    Reading different posts, there is probably more sophisticated ways to address the problem, but this one worked for me. It might also be more beneficial for other beginners like me, as this solution is easy to understand.

    I basically created an id for each form field in the forms.py. Without this id in the forms, django did not make the link between the assigned ID in the .js file and the form field in the template.

    forms.py

    class VenueForm(ModelForm):
        street_number = forms.CharField(max_length=100, label = '', widget = forms.TextInput(attrs={'id':"street_number"}))
    

    template

     <form id="venueform" method="POST">
        {% csrf_token %}
        {{ form|as_crispy_errors }}
    
        <td class="label">Street Number </td>
        {{form.street_number| as_crispy_field}} </form>
    

    .js file (not changes)

    function initAutocomplete(){  
          autocomplete = new google.maps.places.Autocomplete(document.getElementById("autocomplete"),{
            componentRestrictions: {'country':['uk']},
            fields: ['name','geometry','address_components'],
            types:['establishment','geocode']
          });
        
           autocomplete.addListener('place_changed', fillInAddress );
        }
        
        function fillInAddress(){
            // Get the place details from the autocomplete object.
            var place = autocomplete.getPlace();
            //showsdiffrent address components (click on 'inspect' on webpage to see)
            console.log(place);
        
             document.getElementById('business').value = place.name;
                //loop through address components detailed in consol 
                for (let i = 0; i < place.address_components.length; i++) {
                  for (let j = 0; j < place.address_components[i].types.length; j++) {
                    ...
                    if (place.address_components[i].types[j] === "street_number") {
                    document.getElementById('street_number').value = place.address_components[i].short_name;
                    } ...