Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding custom JS to a django admin field

In a django application I have the following model:

class Appointment(models.Model):
    #some other fields
    #address fields
    zipcode=models.CharField(max_length=5)
    address=models.CharField(max_length=120)
    latitude=models.FloatField()
    longitude=models.FloatField()

When I'm rendering an Appointment, I'm just putting a marker at the position specified by longitude and latitude with the address as text, however I need the latitude and longitude to do that.

Currently, latitude and longitude have to be entered manually in the admin backend, but opening Google Maps/OSM, searching for the address and entering latitude and longitude is work that shouldn't have to be done by hand, so I want to retrieve it through the Google Maps API (keyword Geocoding).

Ideally, I want a button "Get coordinates" next to the address, which, when pressed, starts a Geocoding request and fills in latitude and longitude when the address is unambiguous and presents a map with the results and fills in the coordinates when the user clicks on the right marker.

I know how to do that, but I'm not sure how I should insert the markup and the code into the admin backend.

Some things I already considered but don't want to do as they don't seem natural or seem to be too much work for such a simple task:

  • putting the code in the address field's description in field_options in a class derived from admin.ModelAdmin
  • putting everything address related in a separate model and using a custom form (with a separate template
  • create an address picker widget
  • use GeoDjango
like image 868
tstenner Avatar asked Nov 29 '09 19:11

tstenner


1 Answers

What is primarily being dealt with is client-side markup and client-side javascript. Being the case, it would seem that using a facility that's designed to handle those would be the proper choice. I'd also recommend making a custom admin widget. I've used this pattern myself. Depending on the size of the client-side markup, you can even make use of a Django template to render the widget.

As an alternative, you could write non-intrusive javascript to re-render that area of the page after the page has loaded. In this method, you could simply include that javascript media file with class Media: on the admin model.

This is more like pseudo-code than anything but it gives the idea:

admin.py

class AppointmentAdmin(admin.ModelAdmin):
    # ...

    class Media:
        from django.conf import settings
        media_url = getattr(settings, 'MEDIA_URL', '/media')
        js = [ media_url+'/admin/long-lat-render.js', ]

long-lat-render.js

// Written for jQuery
$(function(){
    // on page load...

    $('#_LongitudeTag').html('');

    var getCoordButton = $('<button id="get-coords"></button>');
    $('#_LongitudeTag').append(getCoordButton);

    addGMap($('#_LongitudeTag').get(0));
});

function addGMap(element) {
   // do whatevers
}
like image 154
T. Stone Avatar answered Oct 08 '22 02:10

T. Stone