Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Adding autocomplete for city and country as drop-down

  • Loading branch information...
commit 07df924c8d5749097b62c857321315886a95576d 1 parent e64b02e
Peter Bengtsson peterbe authored
1  apps/autocomplete/__init__.py
View
@@ -0,0 +1 @@
+#
1  apps/autocomplete/models.py
View
@@ -0,0 +1 @@
+# hey! I'm an app!
41 apps/autocomplete/urls.py
View
@@ -0,0 +1,41 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla Sheriff Duty.
+#
+# The Initial Developer of the Original Code is Mozilla Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+from django.conf.urls.defaults import patterns, url
+import views
+
+urlpatterns = patterns('',
+ url(r'^cities/$', views.cities, name='autocomplete.cities'),
+)
53 apps/autocomplete/views.py
View
@@ -0,0 +1,53 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla Sheriff Duty.
+#
+# The Initial Developer of the Original Code is Mozilla Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+from dates.decorators import json_view
+from users.models import UserProfile
+
+
+@json_view
+def cities(request):
+ data = []
+ term = request.GET.get('term')
+ qs = UserProfile.objects.exclude(city='')
+ if term:
+ qs = qs.filter(city__istartswith=term)
+ for each in (qs
+ .values('city')
+ .distinct('city')
+ .order_by('city')):
+ city = each['city']
+ data.append(city)
+ return data
42 apps/users/forms.py
View
@@ -39,7 +39,7 @@
import django.contrib.auth.forms
from .models import UserProfile
from dates.forms import BaseModelForm
-
+from lib.country_aliases import ALIASES as COUNTRY_ALIASES
class EmailInput(forms.widgets.Input):
input_type = 'email'
@@ -62,9 +62,35 @@ class AuthenticationForm(django.contrib.auth.forms.AuthenticationForm):
class ProfileForm(BaseModelForm):
+ country = forms.ChoiceField(widget=forms.widgets.Select())
+
class Meta:
model = UserProfile
- fields = ('start_date', 'country', 'city')
+ fields = ('city',)
+
+ def __init__(self, *args, **kwargs):
+ super(ProfileForm, self).__init__(*args, **kwargs)
+
+ country_choices = []
+ _all_longforms = []
+ for each in (UserProfile.objects.exclude(country='')
+ .values('country')
+ .distinct('country')
+ .order_by('country')):
+ country = each['country']
+ long_form = country
+ if long_form in COUNTRY_ALIASES.values():
+ long_form = [k for (k, v) in COUNTRY_ALIASES.items()
+ if v == country][0]
+ _all_longforms.append(long_form)
+ country_choices.append((country, long_form))
+ for alias, country in COUNTRY_ALIASES.items():
+ if alias not in _all_longforms:
+ _all_longforms.append(alias)
+ country_choices.append((country, alias))
+
+ country_choices.sort(lambda x,y: cmp(x[1], y[1]))
+ self.fields['country'].choices = country_choices
def clean_start_date(self):
value = self.cleaned_data['start_date']
@@ -74,6 +100,14 @@ def clean_start_date(self):
def clean_country(self):
value = self.cleaned_data['country']
- # XXX: we ought to massage and validate this value
- # so that for example 'United Kingdom' -> 'GB'
+ if value in COUNTRY_ALIASES.values():
+ pass
+ elif value in COUNTRY_ALIASES:
+ value = COUNTRY_ALIASES.get(value)
+ else:
+ # search case-insensitively
+ for alias in COUNTRY_ALIASES:
+ if alias.lower() == value.lower():
+ value = COUNTRY_ALIASES[alias]
+ break
return value
54 apps/users/templates/users/settings.html
View
@@ -1,54 +0,0 @@
-{#
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1/GPL 2.0/LGPL 2.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Mozilla Sheriff Duty.
- -
- - The Initial Developer of the Original Code is Mozilla Corporation.
- - Portions created by the Initial Developer are Copyright (C) 2011
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- -
- - Alternatively, the contents of this file may be used under the terms of
- - either the GNU General Public License Version 2 or later (the "GPL"), or
- - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- - in which case the provisions of the GPL or the LGPL are applicable instead
- - of those above. If you wish to allow use of your version of this file only
- - under the terms of either the GPL or the LGPL, and not to allow others to
- - use your version of this file under the terms of the MPL, indicate your
- - decision by deleting the provisions above and replace them with the notice
- - and other provisions required by the GPL or the LGPL. If you do not delete
- - the provisions above, a recipient may use your version of this file under
- - the terms of any one of the MPL, the GPL or the LGPL.
- -
- - ***** END LICENSE BLOCK *****
- -->
-#}
-
-{% extends "base.html" %}
-
-{% block content %}
-<h2>Settings</h2>
-
-<form action="." method="post">{{ csrf() }}
-<table>
-{{ form|safe }}
-<tr>
- <td>&nbsp;</td>
- <td><input type="submit" value="Save"></td>
-</tr>
-</table>
-</form>
-
-{% endblock %}
7 apps/users/views.py
View
@@ -117,7 +117,12 @@ def profile(request):
if request.method == 'POST':
form = forms.ProfileForm(instance=profile, data=request.POST)
if form.is_valid():
- form.save()
+ city = form.cleaned_data['city']
+ country = form.cleaned_data['country']
+ profile.city = city
+ profile.country = country
+ profile.save()
+
return redirect('/')
else:
form = forms.ProfileForm(instance=profile)
1  lib/__init__.py
View
@@ -0,0 +1 @@
+#
6 lib/country_aliases.py
View
@@ -0,0 +1,6 @@
+ALIASES = {
+ 'United Kingdom': 'GB',
+ 'United States': 'US',
+ 'Great Britain': 'GB',
+ 'France': 'FR',
+}
8 media/js/users/profile.js
View
@@ -1,9 +1,5 @@
-var dateFormat = 'DD, MM d, yy';
$(function() {
-
- $('input.date').datepicker({
- dateFormat: dateFormat,
- maxDate: new Date()
+ $('#id_city').autocomplete({
+ source: '/autocomplete/cities/'
});
-
});
1  settings/base.py
View
@@ -270,6 +270,7 @@
'users',
'legacy',
'mobile',
+ 'autocomplete',
)
# Tells the extract script what files to look for L10n in and what function
1  urls.py
View
@@ -9,6 +9,7 @@
urlpatterns = patterns('',
(r'^users/', include('users.urls')),
(r'^mobile/', include('mobile.urls')),
+ (r'^autocomplete/', include('autocomplete.urls')),
(r'', include('dates.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
Please sign in to comment.
Something went wrong with that request. Please try again.