Add another popup outside the admin

This documentation drives throught the example app non_admin_add_another which lives in test_project.

Implementing this feature is utterly simple and can be done in two steps:

  • make your create view to return some script if called with _popup=1,
  • add add_another_url_name attribute to your Autocomplete,

Warning

Note that this feature was added in version 1.0.21, if you have overloaded autocomplete_light/static.html from a previous version then you should make it load autocomplete_light/addanother.js to get this new feature.

Specifications

Consider such a model:

from django.db import models
from django.core import urlresolvers


class Widget(models.Model):
    name = models.CharField(max_length=100)
    widget = models.ForeignKey('self', null=True, blank=True,
        related_name='widget_fk')
    widgets = models.ManyToManyField('self', blank=True,
        related_name='widget_m2m')

    def get_absolute_url(self):
        return urlresolvers.reverse(
            'non_admin_add_another:widget_update', args=(self.pk,))

    def __unicode__(self):
        return self.name

And we want to have add/update views outside the admin, with autocompletes for relations as well as a +/add-another button just like in the admin.

Technical details come from a blog post written by me a couple years ago, Howto: javascript popup form returning value for select like Django admin for foreign keys.

Create view

A create view opened via the add-another button should return such a body:

<script type="text/javascript">
opener.dismissAddAnotherPopup(
    window,
    "name of created model",
    "id of created model"
);
</script>

Note that you could also use autocomplete_light.CreateView which simply wraps around django.views.generic.edit.CreateView.form_valid() to do that, example usage:

from django.conf.urls import patterns, url
from django.views import generic

import autocomplete_light

from forms import WidgetForm
from models import Widget


urlpatterns = patterns('',
    url(r'widget/add/$', autocomplete_light.CreateView.as_view(
        model=Widget, form_class=WidgetForm), name='widget_create'),
    url(r'widget/(?P<pk>\d+)/update/$', generic.UpdateView.as_view(
        model=Widget, form_class=WidgetForm), name='widget_update'),
)

Note

It is not mandatory to use url namespaces.

Autocompletes

Simply register an Autocomplete for widget, with an add_another_url_name argument, for example:

from django.core import urlresolvers

import autocomplete_light

from models import Widget


autocomplete_light.register(Widget, add_another_url_name='non_admin_add_another:widget_create')