Ooops, just realised I didn't finished writing the first sentence of my previous post. So here it is: "I have created a custom widget using the branch newforms-admin to represent a ManyToMany relation with checkboxes."
On Nov 22, 10:49 pm, Julien <[EMAIL PROTECTED]> wrote: > Hi all, > > I have created a custom widget using the branch newforms-admin to > represent (see code below): > > To test it, create a couple of countries, then a few cities attached > to those countries, and then create a new Person. > > In the class PersonOptions, the line "formfield.widget.render = > widgets.RelatedFieldWidgetWrapper(formfield.widget.render, > db_field.rel, self.admin_site)" allows me to get the green cross. By > clicking that cross, a popup appears and you can add a new city. Until > then it's great.... > > ....except that once the new city is saved, the popup doesn't close. > It remains blank, and if you look at the html source of that popup > you'll get something like: > "<script type="text/javascript">opener.dismissAddAnotherPopup(window, > 7, "New York");</script>" > > By looking at the function "dismissAddAnotherPopup" in the file > "http://127.0.0.1:8000/media/js/admin/RelatedObjectLookups.js" it > seems that if the widget is not a "select" component, then it won't be > refreshed. > > So, my questions: > - How can we get that pop up window to close when the new city is > saved? > - How can we refresh the custom widget? > - How can we put the green cross in a better place? (with the current > template it is placed in the bottom left corner, which is not that > visible) > > Thanks a lot for your help! > > The actual code: > > class Country(models.Model): > name = models.CharField(max_length=50) > def __unicode__(self): > return self.name > > class City(models.Model): > name = models.CharField(max_length=50) > country = models.ForeignKey(Country) > def __unicode__(self): > return self.name > > class Person(models.Model): > firstName = models.CharField(max_length=30) > lastName = models.CharField(max_length=30) > citiesLived = models.ManyToManyField(City, null=True, blank=True) > def __unicode__(self): > return self.firstName + " " + self.lastName > > from django.newforms.widgets import * > from django.newforms.fields import MultipleChoiceField > from django.template import Context, Template > from django.newforms.util import flatatt > from django.utils.encoding import force_unicode > from itertools import chain > from django.utils.html import escape > class CitiesWidget(CheckboxSelectMultiple): > template_string="""<p>{% regroup city_list|dictsort:"country" by > country as cities_by_country %} > {% for country in cities_by_country %} > <b>{{ country.grouper }}</b><br/> > {% for city in country.list|dictsort:"name" > %} > {{ city.html }}<br/> > {% endfor %} > <br/> > {% endfor %}</p> > """ > def render(self, name, value, attrs=None, choices=()): > if value is None: value = [] > has_id = attrs and 'id' in attrs > final_attrs = self.build_attrs(attrs, name=name) > str_values = set([force_unicode(v) for v in value]) # > Normalize to strings. > city_list = [] > for i, (option_value, option_label) in > enumerate(chain(self.choices, choices)): > city = City.objects.get(id=option_value) > # If an ID attribute was given, add a numeric index as a > suffix, > # so that the checkboxes don't all have the same ID > attribute. > if has_id: > final_attrs = dict(final_attrs, id='%s_%s' % > (attrs['id'], i)) > cb = CheckboxInput(final_attrs, check_test=lambda value: > value in str_values) > option_value = force_unicode(option_value) > rendered_cb = cb.render(name, option_value) > html = (u'%s %s' % (rendered_cb, > escape(force_unicode(option_label)))) > city_list.append({"country":city.country.name, "name": > option_label, "html":html}) > t = Template(self.template_string) > c = Context({"city_list": city_list}) > return t.render(c) > > class CitiesField(MultipleChoiceField): > widget = CitiesWidget > > from django.contrib.admin import widgets > class PersonOptions(admin.ModelAdmin): > def formfield_for_dbfield(self, db_field, **kwargs): > if db_field.name == 'citiesLived': > cities = kwargs['initial'] > kwargs['initial'] = [city.id for city in cities] > formfield = CitiesField(**kwargs) > formfield.choices = [(city.id, city.name) for city in > City.objects.all()] > formfield.widget.render = > widgets.RelatedFieldWidgetWrapper(formfield.widget.render, > db_field.rel, self.admin_site) > return formfield > else: > return > super(PersonOptions,self).formfield_for_dbfield(db_field,**kwargs) > > admin.site.register(Country) > admin.site.register(City) > admin.site.register(Person, PersonOptions) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~----------~----~----~----~------~----~------~--~---