Sunday, 3 September 2023

How to insert placeholder in Django Admin autocomplete input

I don't want to use JS or alter the template when Django has other mechanisms.

I've tried three methods, first as described in how-to-add-placeholder-text-to-a-django-admin-field and in the docs.

from django import forms

    class AppointmentAdmin(admin.ModelAdmin):
        
        def get_form(self, request, obj=None, **kwargs):
            kwargs['widgets'] = {
                'name': forms.TextInput(attrs={'placeholder': 'Type here'})
            }
            return super().get_form(request, obj, **kwargs)

Then the method described in django-add-placeholder-text-to-form-field, slightly altered to get around Python errors.

class AppointmentAdmin(admin.ModelAdmin):
    
   def get_form(self, request, obj=None, **kwargs):
      form = super().get_form(request, obj, **kwargs)
      form.base_fields['customer'].widget.attrs["placeholder"] = "Type here"
      return form

Finally, using formfield_overrides:

class AppointmentAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.TextField: { "widget":forms.TextInput(attrs={'placeholder':'Type here'})},
    }

None of these are working. I must be overlooking something simple?

The relevant portion of models.py:

class Appointment(models.Model):
    customer = models.ForeignKey(Customer, blank=False, null=True, default=None, on_delete=models.CASCADE, related_name='appointments')

I should also mention that the input field to which I'm trying to add a placeholder is an autocomplete field:

admin.py
class AppointmentAdmin(admin.ModelAdmin):
    autocomplete_fields = ["customer"]

This line was omitted from the code above for readability.
UPDATE: I removed this autocomplete_fields line to no effect vis a vis a placeholder. Anyway, I think autocomplete_fields should have a placeholder option rather than requiring all the jumping through hoops as described above.

The 'help_text' option on the field in models.py would almost be a cheap replacement for a placeholder, except that it makes no sense in other parts of this program.

Here's the HTML that Django generates using the second method above (form.base_fields...etc.):

<span class="selection">
  <span class="select2-selection select2-selection--single" role="combobox" 
  aria-haspopup="true" aria-expanded="false" tabindex="0" aria- 
  disabled="false" aria-labelledby="select2-id_customer-container"><span 
  class="select2-selection__rendered" id="select2-id_customer-container" 
  role="textbox" aria-readonly="true">
  <span class="select2-selection__placeholder"></span>
  </span>
  <span class="select2-selection__arrow" role="presentation"><b 
  role="presentation"></b></span>
</span>


from How to insert placeholder in Django Admin autocomplete input

No comments:

Post a Comment