Michael Hall has proposed merging lp:~mhall119/loco-directory/579828 into
lp:loco-directory.
Requested reviews:
loco-directory-dev (loco-directory-dev)
Related bugs:
#579828 serialise add-event procedure (if venue does not exist)
https://bugs.launchpad.net/bugs/579828
Uses some modified bits of code from the Django Admin app to allow a popup
window creating new venues without leaving the Event edit page.
Requires an update of ubuntu_website
--
https://code.launchpad.net/~mhall119/loco-directory/579828/+merge/30452
Your team loco-directory-dev is requested to review the proposed merge of
lp:~mhall119/loco-directory/579828 into lp:loco-directory.
=== added file 'loco_directory/common/widgets.py'
--- loco_directory/common/widgets.py 1970-01-01 00:00:00 +0000
+++ loco_directory/common/widgets.py 2010-07-20 19:11:43 +0000
@@ -0,0 +1,56 @@
+from django import forms
+from django.conf import settings
+from django.core.urlresolvers import reverse
+from django.utils.translation import ugettext as _
+from django.utils.safestring import mark_safe
+from django.utils.encoding import force_unicode
+
+class PopupRelatedFieldWidgetWrapper(forms.Widget):
+ """
+ This class is a wrapper to a given widget to add the add icon for the
+ admin interface.
+ """
+ def __init__(self, widget, popup_url):
+ self.is_hidden = widget.is_hidden
+ self.needs_multipart_form = widget.needs_multipart_form
+ self.attrs = widget.attrs
+ self.choices = widget.choices
+ self.widget = widget
+ self.popup_url = popup_url
+
+ def __deepcopy__(self, memo):
+ obj = copy.copy(self)
+ obj.widget = copy.deepcopy(self.widget, memo)
+ obj.attrs = self.widget.attrs
+ memo[id(self)] = obj
+ return obj
+
+ def _media(self):
+ wm = self.widget.media
+ wm.add_js(['%sjs/RelatedObjectLookups.js'%settings.MEDIA_URL,])
+ return wm
+ media = property(_media)
+
+ def render(self, name, value, *args, **kwargs):
+
+ self.widget.choices = self.choices
+ output = [self.widget.render(name, value, *args, **kwargs)]
+ output.append(u'<a href="%s" class="add-another" id="add_id_%s" onclick="return showAddAnotherPopup(this);"> ' % \
+ (self.popup_url, name))
+ output.append(u'<img src="%simg/add.gif" width="10" height="10" alt="%s"/></a>' % (settings.MEDIA_URL, _('Add Another')))
+ return mark_safe(u''.join(output))
+
+ def build_attrs(self, extra_attrs=None, **kwargs):
+ "Helper function for building an attribute dictionary."
+ self.attrs = self.widget.build_attrs(extra_attrs=None, **kwargs)
+ return self.attrs
+
+ def value_from_datadict(self, data, files, name):
+ return self.widget.value_from_datadict(data, files, name)
+
+ def _has_changed(self, initial, data):
+ return self.widget._has_changed(initial, data)
+
+ def id_for_label(self, id_):
+ return self.widget.id_for_label(id_)
+
=== modified file 'loco_directory/events/forms.py'
--- loco_directory/events/forms.py 2010-06-19 21:35:39 +0000
+++ loco_directory/events/forms.py 2010-07-20 19:11:43 +0000
@@ -2,6 +2,7 @@
from django import forms
from django.utils.translation import ugettext as _
+from django.core.urlresolvers import reverse
from models import BaseEvent, GlobalEvent, TeamEvent, Attendee, TeamEventComment
from venues.models import Venue
@@ -60,6 +61,8 @@
def __init__(self, *args, **kargs):
super(TeamEventForm, self).__init__(*args, **kargs)
self.fields['venue'].choices = self.grouped_venue_list()
+ from common.widgets import PopupRelatedFieldWidgetWrapper
+ self.fields['venue'].widget = PopupRelatedFieldWidgetWrapper(self.fields['venue'].widget, reverse('venue-new'))
def grouped_venue_list(self):
"""
=== added file 'loco_directory/media/img/add.gif'
Binary files loco_directory/media/img/add.gif 1970-01-01 00:00:00 +0000 and loco_directory/media/img/add.gif 2010-07-20 19:11:43 +0000 differ
=== added file 'loco_directory/media/js/RelatedObjectLookups.js'
--- loco_directory/media/js/RelatedObjectLookups.js 1970-01-01 00:00:00 +0000
+++ loco_directory/media/js/RelatedObjectLookups.js 2010-07-20 19:11:43 +0000
@@ -0,0 +1,96 @@
+// Handles related-objects functionality: lookup link for raw_id_fields
+// and Add Another links.
+
+function html_unescape(text) {
+ // Unescape a string that was escaped using django.utils.html.escape.
+ text = text.replace(/</g, '<');
+ text = text.replace(/>/g, '>');
+ text = text.replace(/"/g, '"');
+ text = text.replace(/'/g, "'");
+ text = text.replace(/&/g, '&');
+ return text;
+}
+
+// IE doesn't accept periods or dashes in the window name, but the element IDs
+// we use to generate popup window names may contain them, therefore we map them
+// to allowed characters in a reversible way so that we can locate the correct
+// element when the popup window is dismissed.
+function id_to_windowname(text) {
+ text = text.replace(/\./g, '__dot__');
+ text = text.replace(/\-/g, '__dash__');
+ return text;
+}
+
+function windowname_to_id(text) {
+ text = text.replace(/__dot__/g, '.');
+ text = text.replace(/__dash__/g, '-');
+ return text;
+}
+
+function showRelatedObjectLookupPopup(triggeringLink) {
+ var name = triggeringLink.id.replace(/^lookup_/, '');
+ name = id_to_windowname(name);
+ var href;
+ if (triggeringLink.href.search(/\?/) >= 0) {
+ href = triggeringLink.href + '&pop=1';
+ } else {
+ href = triggeringLink.href + '?pop=1';
+ }
+ var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
+ win.focus();
+ return false;
+}
+
+function dismissRelatedLookupPopup(win, chosenId) {
+ var name = windowname_to_id(win.name);
+ var elem = document.getElementById(name);
+ if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
+ elem.value += ',' + chosenId;
+ } else {
+ document.getElementById(name).value = chosenId;
+ }
+ win.close();
+}
+
+function showAddAnotherPopup(triggeringLink) {
+ var name = triggeringLink.id.replace(/^add_/, '');
+ name = id_to_windowname(name);
+ href = triggeringLink.href
+ if (href.indexOf('?') == -1) {
+ href += '?_popup=1';
+ } else {
+ href += '&_popup=1';
+ }
+ var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
+ win.focus();
+ return false;
+}
+
+function dismissAddAnotherPopup(win, newId, newRepr) {
+ // newId and newRepr are expected to have previously been escaped by
+ // django.utils.html.escape.
+ newId = html_unescape(newId);
+ newRepr = html_unescape(newRepr);
+ var name = windowname_to_id(win.name);
+ var elem = document.getElementById(name);
+ if (elem) {
+ if (elem.nodeName == 'SELECT') {
+ var o = new Option(newRepr, newId);
+ elem.options[elem.options.length] = o;
+ o.selected = true;
+ } else if (elem.nodeName == 'INPUT') {
+ if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
+ elem.value += ',' + newId;
+ } else {
+ elem.value = newId;
+ }
+ }
+ } else {
+ var toId = name + "_to";
+ elem = document.getElementById(toId);
+ var o = new Option(newRepr, newId);
+ SelectBox.add_to_cache(toId, o);
+ SelectBox.redisplay(toId);
+ }
+ win.close();
+}
=== modified file 'loco_directory/settings.py'
--- loco_directory/settings.py 2010-07-18 16:34:12 +0000
+++ loco_directory/settings.py 2010-07-20 19:11:43 +0000
@@ -100,6 +100,7 @@
if uw_import:
TEMPLATE_CONTEXT_PROCESSORS += (
"ubuntu_website.media_processor",
+ "ubuntu_website.popup_check",
)
TEMPLATE_DIRS += (
ubuntu_website.TEMPLATE_DIR,
=== modified file 'loco_directory/templates/venues/venue_update.html'
--- loco_directory/templates/venues/venue_update.html 2010-06-24 19:18:57 +0000
+++ loco_directory/templates/venues/venue_update.html 2010-07-20 19:11:43 +0000
@@ -30,7 +30,7 @@
<table>
{{ form.as_table }}
</table>
- <p><input type="submit" value="Submit" /></p>
+ <p>{% if is_popup %}<input type="hidden" name="_popup" value="1">{% endif %}<input type="submit" value="Submit" /></p>
</form>
</article>
=== modified file 'loco_directory/venues/views.py'
--- loco_directory/venues/views.py 2010-06-19 20:20:12 +0000
+++ loco_directory/venues/views.py 2010-07-20 19:11:43 +0000
@@ -2,9 +2,10 @@
from django.shortcuts import render_to_response
from django.shortcuts import get_object_or_404
from django.contrib.auth.decorators import login_required
-from django.http import HttpResponseRedirect
+from django.http import HttpResponse, HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
+from django.utils.html import escape
from django.db.models import Q
from models import Venue
@@ -47,12 +48,19 @@
"""
new venue
"""
+ venue_object = Venue()
if request.method == 'POST':
- form = VenueForm(data=request.POST)
+ form = VenueForm(data=request.POST, instance=venue_object)
if form.is_valid():
form.save()
request.user.message_set.create(message=_('New Venue created'))
- return HttpResponseRedirect( reverse( 'venue-list' ) )
+ if request.REQUEST.has_key('_popup'):
+ print "POST from Popup"
+ return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script>' % \
+ # escape() calls force_unicode.
+ (escape(venue_object.pk), escape(venue_object)))
+ else:
+ return HttpResponseRedirect( reverse( 'venue-list' ) )
else:
form = VenueForm()
_______________________________________________
Mailing list: https://launchpad.net/~loco-directory-dev
Post to : [email protected]
Unsubscribe : https://launchpad.net/~loco-directory-dev
More help : https://help.launchpad.net/ListHelp