summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@peacefrogs.net>2011-01-08 14:48:58 +0100
committerÉtienne Loks <etienne.loks@peacefrogs.net>2011-01-08 14:48:58 +0100
commite87f791d0fa450da71ead7148437ba95151c8eeb (patch)
tree7492ddacc34a309d671b34ba539f5f8095e6c62f
parent3259ae9642a0d86f9cca2c94bfba510cd55549c1 (diff)
downloadIshtar-e87f791d0fa450da71ead7148437ba95151c8eeb.tar.bz2
Ishtar-e87f791d0fa450da71ead7148437ba95151c8eeb.zip
Better style. Better confirmation page. Better management of wizard steps. (closes #63)
-rw-r--r--ishtar/furnitures/forms.py98
-rw-r--r--ishtar/furnitures/models.py6
-rw-r--r--ishtar/furnitures/urls.py6
-rw-r--r--ishtar/furnitures/views.py25
-rw-r--r--ishtar/templates/confirm_wizard.html27
-rw-r--r--ishtar/templates/default_wizard.html4
-rw-r--r--ishtar/templates/wizard_done.html6
-rw-r--r--static/media/style.css9
8 files changed, 138 insertions, 43 deletions
diff --git a/ishtar/furnitures/forms.py b/ishtar/furnitures/forms.py
index c5284e46d..924ea8b94 100644
--- a/ishtar/furnitures/forms.py
+++ b/ishtar/furnitures/forms.py
@@ -57,7 +57,8 @@ class Wizard(NamedUrlSessionFormWizard):
model = None
def get_template(self, request, storage):
templates = ['default_wizard.html']
- current_step = storage.get_current_step() or '0'
+ current_step = storage.get_current_step() or self.get_first_step(
+ request, storage)
if current_step == self.get_last_step(request, storage):
templates = ['confirm_wizard.html'] + templates
return templates
@@ -69,7 +70,8 @@ class Wizard(NamedUrlSessionFormWizard):
context = super(Wizard, self).get_template_context(request, storage,
form)
step = self.get_first_step(request, storage)
- current_step = storage.get_current_step() or '0'
+ current_step = storage.get_current_step() or self.get_first_step(
+ request, storage)
context.update({'current_step':self.form_list[current_step]})
if step == current_step:
return context
@@ -99,24 +101,39 @@ class Wizard(NamedUrlSessionFormWizard):
"""
datas = []
for form in forms:
+ form_datas = []
base_form = hasattr(form, 'forms') and form.forms[0] or form
associated_models = hasattr(base_form, 'associated_models') and \
base_form.associated_models or {}
- if not hasattr(form, 'cleaned_data'):
+ if not hasattr(form, 'cleaned_data') and hasattr(form, 'forms'):
+ cleaned_datas = [frm.cleaned_data for frm in form.forms
+ if frm.is_valid()]
+ if not cleaned_datas:
+ continue
+ elif not hasattr(form, 'cleaned_data'):
continue
- cleaned_datas = type(form.cleaned_data) == list and \
+ else:
+ cleaned_datas = type(form.cleaned_data) == list and \
form.cleaned_data \
or [form.cleaned_data]
for cleaned_data in cleaned_datas:
+ if cleaned_data and form_datas:
+ form_datas.append(("", "", "spacer"))
for key in cleaned_data:
- lbl = key
+ lbl = None
if hasattr(base_form, 'fields') and key in base_form.fields:
lbl = base_form.fields[key].label
+ if not lbl:
+ continue
value = cleaned_data[key]
if key in associated_models:
value = unicode(associated_models[key].objects.get(
pk=value))
- datas.append((lbl, value))
+ if not value:
+ continue
+ form_datas.append((lbl, value, ''))
+ if form_datas:
+ datas.append((form.form_label, form_datas))
return datas
def get_extra_model(self, dct, request, storage, form_list):
@@ -217,6 +234,22 @@ class Wizard(NamedUrlSessionFormWizard):
return super(Wizard, self).render_next_step(request, storage, form,
**kwargs)
+ def process_post_request(self, request, storage, *args, **kwargs):
+ """
+ Convert numerical step number to step name
+ """
+ if request.POST.has_key('form_prev_step'):
+ try:
+ step_number = int(request.POST['form_prev_step'])
+ post_data = request.POST.copy()
+ post_data['form_prev_step'] = self.get_form_list(request,
+ storage).keys()[step_number]
+ request.POST = post_data
+ except ValueError:
+ pass
+ return super(Wizard, self).process_post_request(request, storage, *args,
+ **kwargs)
+
class FileWizard(Wizard):
model = models.File
def get_form(self, request, storage, step=None, data=None, files=None):
@@ -231,12 +264,13 @@ class FileWizard(Wizard):
if not step:
step = self.determine_step(request, storage)
form = self.get_form_list(request, storage)[step]
- if step == '3' and hasattr(form, 'management_form') \
+ town_form_key = 'towns-' + self.url_name
+ if step.startswith('parcels-') and hasattr(form, 'management_form') \
and storage.prefix in request.session \
and 'step_data' in request.session[storage.prefix] \
- and '2' in request.session[storage.prefix]['step_data']:
+ and town_form_key in request.session[storage.prefix]['step_data']:
towns = []
- qdict = request.session[storage.prefix]['step_data']['2']
+ qdict = request.session[storage.prefix]['step_data'][town_form_key]
for k in qdict.keys():
if k.endswith("town") and qdict[k]:
try:
@@ -268,7 +302,8 @@ class FileWizard(Wizard):
return r
obj, res = r
for form in form_list:
- if not hasattr(form, 'prefix') or form.prefix != '3' \
+ if not hasattr(form, 'prefix') \
+ or not form.prefix.startswith('parcels-') \
or not hasattr(form, 'forms'):
continue
for frm in form.forms:
@@ -293,7 +328,14 @@ def get_now():
value = datetime.datetime.now().strftime(format)
return value
-class FileForm1(forms.Form):
+class FileFormSelection(forms.Form):
+ form_label = _("Archaelogical file")
+ archaelogical_file = forms.IntegerField(label=_("Archaelogical file"),
+ widget=widgets.JQueryAutoComplete(reverse_lazy('autocomplete-file'),
+ associated_model=models.File),
+ validators=[models.valid_id(models.File)])
+
+class FileFormGeneral(forms.Form):
form_label = _("General")
associated_models = {'in_charge':models.Person,
'file_type':models.FileType}
@@ -312,7 +354,7 @@ max_length=60, validators=[models.is_unique(models.File, 'internal_reference')])
comment = forms.CharField(label=_(u"Comment"), widget=forms.Textarea,
required=False)
-class FileForm2(forms.Form):
+class FileFormAddress(forms.Form):
form_label = _("Address")
total_surface = forms.IntegerField(label=_("Total surface"))
address = forms.CharField(label=_(u"Address"), widget=forms.Textarea)
@@ -346,7 +388,7 @@ TownFormSet.form_label = _("Towns")
class ParcelForm(forms.Form):
form_label = _("Parcels")
- associated_models = {'parcel':models.Parcel}
+ associated_models = {'parcel':models.Parcel, 'town':models.Town}
town = forms.ChoiceField(label=_("Town"), choices=(),
validators=[models.valid_id(models.Town)])
section = forms.CharField(label=_(u"Section"),
@@ -393,7 +435,7 @@ ParcelFormSet = formset_factory(ParcelForm, can_delete=True,
formset=ParcelFormSet)
ParcelFormSet.form_label = _("Parcels")
-class FileForm4(forms.Form):
+class FileFormPreventive(forms.Form):
form_label = _("Preventive informations")
associated_models = {'general_contractor':models.Organization,
'saisine_type':models.SaisineType}
@@ -426,7 +468,27 @@ def is_preventive(form_name, file_type_key='file_type'):
return False
return func
-file_creation_wizard = FileWizard([FileForm1, FileForm2, TownFormSet,
- ParcelFormSet, FileForm4, FinalForm],
- url_name='file_creation', condition_list={'4':is_preventive('0')})
-
+file_creation_wizard = FileWizard([
+ ('general-file_creation', FileFormGeneral),
+ ('address-file_creation', FileFormAddress),
+ ('towns-file_creation', TownFormSet),
+ ('parcels-file_creation', ParcelFormSet),
+ ('preventive-file_creation', FileFormPreventive),
+ ('final-file_creation', FinalForm)],
+ condition_list={
+ 'preventive-file_creation':is_preventive('general-file_creation')
+ },
+ url_name='file_creation',)
+
+file_modification_wizard = FileWizard([
+ ('selec-file_modification', FileFormSelection),
+ ('general-file_modification', FileFormGeneral),
+ ('adress-file_modification', FileFormAddress),
+ ('towns-file_modification', TownFormSet),
+ ('parcels-file_modification', ParcelFormSet),
+ ('preventive-file_modification', FileFormPreventive),
+ ('final-file_modification', FinalForm)],
+ condition_list={
+ 'preventive-file_modification':is_preventive('general-file_modif')
+ },
+ url_name='file_modification',)
diff --git a/ishtar/furnitures/models.py b/ishtar/furnitures/models.py
index abb8c963e..e75eb9b51 100644
--- a/ishtar/furnitures/models.py
+++ b/ishtar/furnitures/models.py
@@ -259,7 +259,11 @@ class File(BaseHistorizedItem, OwnPerms):
("delete_own_file", ugettext(u"Can delete own Archaelogical file")),
)
def __unicode__(self):
- return u"%d - %s" % (self.year, self.internal_reference)
+ items = [unicode(getattr(self, k)) for k in ['internal_reference']
+ if getattr(self, k)]
+ if self.year and self.numeric_reference:
+ items = [u'%d-%d' % (self.year, self.numeric_reference)] + items
+ return u" - ".join(items)
class OperationType(GeneralType):
class Meta:
diff --git a/ishtar/furnitures/urls.py b/ishtar/furnitures/urls.py
index aeaec4863..4a9349700 100644
--- a/ishtar/furnitures/urls.py
+++ b/ishtar/furnitures/urls.py
@@ -21,13 +21,15 @@ from django.conf.urls.defaults import *
from ishtar.urls import BASE_URL
from menus import menu
-from forms import file_creation_wizard
+from forms import file_creation_wizard, file_modification_wizard
urlpatterns, actions = [], []
urlpatterns = patterns('',
url(BASE_URL + r'file_creation/(?P<step>.+)$', file_creation_wizard,
name='file_creation'),
+ url(BASE_URL + r'file_modification/(?P<step>.+)$',
+ file_modification_wizard, name='file_modification'),
)
for section in menu.childs:
for menu_item in section.childs:
@@ -43,4 +45,6 @@ urlpatterns += patterns('ishtar.furnitures.views',
name='autocomplete-town'),
url(BASE_URL + r'autocomplete-organization/$', 'autocomplete_organization',
name='autocomplete-organization'),
+ url(BASE_URL + r'autocomplete-file/$', 'autocomplete_file',
+ name='autocomplete-file'),
)
diff --git a/ishtar/furnitures/views.py b/ishtar/furnitures/views.py
index 832089ea8..dcf0f28d9 100644
--- a/ishtar/furnitures/views.py
+++ b/ishtar/furnitures/views.py
@@ -31,7 +31,7 @@ from django.core import serializers
from ishtar import settings
from menus import menu
-from forms import file_creation_wizard
+from forms import file_creation_wizard, file_modification_wizard
import models
def index(request):
@@ -86,6 +86,26 @@ def autocomplete_town(request):
for town in towns])
return HttpResponse(data, mimetype='text/plain')
+def autocomplete_file(request):
+ if not request.GET.get('term'):
+ return HttpResponse(mimetype='text/plain')
+ q = request.GET.get('term')
+ query = Q()
+ for q in q.split(' '):
+ extra = Q(internal_reference__icontains=q) | \
+ Q(towns__name__icontains=q)
+ try:
+ value = int(q)
+ extra = extra | Q(year=q) | Q(numeric_reference=q)
+ except ValueError:
+ pass
+ query = query & extra
+ limit = 15
+ files = models.File.objects.filter(query)[:limit]
+ data = json.dumps([{'id':file.pk, 'value':unicode(file)}
+ for file in files])
+ return HttpResponse(data, mimetype='text/plain')
+
def autocomplete_organization(request):
if not request.GET.get('term'):
return HttpResponse(mimetype='text/plain')
@@ -120,3 +140,6 @@ def action(request, action_slug, obj_id=None, *args, **kwargs):
def file_creation(request, dct, obj_id, *args, **kwargs):
return file_creation_wizard(request, *args, **kwargs)
+def file_modification(request, dct, obj_id, *args, **kwargs):
+ return file_modification_wizard(request, *args, **kwargs)
+
diff --git a/ishtar/templates/confirm_wizard.html b/ishtar/templates/confirm_wizard.html
index c83134dfb..78b39fb35 100644
--- a/ishtar/templates/confirm_wizard.html
+++ b/ishtar/templates/confirm_wizard.html
@@ -5,21 +5,24 @@
<form action="." method="post">{% csrf_token %}
<ul id='form_path'>
{% for step in previous_steps %}
- <li>&raquo; <button name="form_prev_step" value="{{forloop.counter0}}">{{step.form_label}}</button></li>
+ <li>&raquo;&nbsp;<button name="form_prev_step" value="{{forloop.counter0}}">{{step.form_label}}</button></li>
{% endfor %}
- <li class='current'>&raquo; <a href='#'>{{current_step.form_label}}</a></li>
+ <li class='current'>&raquo;&nbsp;<a href='#'>{{current_step.form_label}}</a></li>
</ul>
<div class='form'>
-<p>{% trans "You have entered the following informations:" %}</p>
-<table>
-{% for label, data in datas %}
-<tr><th>{{label}}</th><td>{{data}}</td></th>
-{% endfor %}
-</table>
-<p>{% trans "Would you like to save them?" %}</p>
-<input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />
-{{ previous_fields|safe }}
-<input type="submit" value="{% trans "Validate" %}"/>
+ <p>{% trans "You have entered the following informations:" %}</p>
+ {% for form_label, form_data in datas %}
+ <table class='confirm'>
+ <caption>{{form_label}}</caption>
+ {% for label, data, cls in form_data %}
+ <tr{%if cls%} class='{{cls}}'{%endif%}><th>{{label}}</th><td>{{data}}</td></th>
+ {% endfor %}
+ </table>
+ {% endfor %}
+ <p>{% trans "Would you like to save them?" %}</p>
+ <input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />
+ {{ previous_fields|safe }}
+ <input type="submit" value="{% trans "Validate" %}"/>
</div>
</form>
{% endblock %}
diff --git a/ishtar/templates/default_wizard.html b/ishtar/templates/default_wizard.html
index 83f02539b..8607f3e19 100644
--- a/ishtar/templates/default_wizard.html
+++ b/ishtar/templates/default_wizard.html
@@ -5,9 +5,9 @@
<form action="." method="post">{% csrf_token %}
<ul id='form_path'>
{% for step in previous_steps %}
- <li>&raquo; <button name="form_prev_step" value="{{forloop.counter0}}">{{step.form_label}}</button></li>
+ <li>&raquo;&nbsp;<button name="form_prev_step" value="{{forloop.counter0}}">{{step.form_label}}</button></li>
{% endfor %}
- <li class='current'>&raquo; <a href='#'>{{current_step.form_label}}</a></li>
+ <li class='current'>&raquo;&nbsp;<a href='#'>{{current_step.form_label}}</a></li>
</ul>
<div class='form'>
{% if form.forms %}
diff --git a/ishtar/templates/wizard_done.html b/ishtar/templates/wizard_done.html
index 468e8ed6a..a7068bbab 100644
--- a/ishtar/templates/wizard_done.html
+++ b/ishtar/templates/wizard_done.html
@@ -1,12 +1,6 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
-<ul id='form_path'>
-{% for step in previous_steps %}
- <li>&raquo; <a href='?form_prev_step={{forloop.counter0}}'>{{step.form_label}}</a></li>
-{% endfor %}
- <li class='current'>&raquo; <a href='#'>{{current_step.form_label}}</a></li>
-</ul>
<p>{%trans "Item successfully saved"%}</p>
</div>
{% endblock %}
diff --git a/static/media/style.css b/static/media/style.css
index 3d1768702..036c04021 100644
--- a/static/media/style.css
+++ b/static/media/style.css
@@ -110,7 +110,7 @@ div#content{
ul#form_path{
text-align:left;
- margin:10px 60px;
+ margin:10px 0;
}
ul#form_path li{
@@ -139,6 +139,7 @@ ul#form_path button {
div.form {
margin-left:auto;
margin-right:auto;
+ margin-bottom:40px;
padding:1em;
display:block;
width:500px;
@@ -152,10 +153,12 @@ div.form table{
padding:0.2em;
margin-left:auto;
margin-right:auto;
+ width:100%;
}
div.form table th{
text-align:left;
+ width:150px;
}
div.form .errorlist{
@@ -189,4 +192,6 @@ div.form .errorlist{
text-align:center;
}
-
+table.confirm tr.spacer td:last-child{
+ border-bottom:1px solid #922;
+}