diff options
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 |
commit | e87f791d0fa450da71ead7148437ba95151c8eeb (patch) | |
tree | 7492ddacc34a309d671b34ba539f5f8095e6c62f | |
parent | 3259ae9642a0d86f9cca2c94bfba510cd55549c1 (diff) | |
download | Ishtar-e87f791d0fa450da71ead7148437ba95151c8eeb.tar.bz2 Ishtar-e87f791d0fa450da71ead7148437ba95151c8eeb.zip |
Better style. Better confirmation page. Better management of wizard steps. (closes #63)
-rw-r--r-- | ishtar/furnitures/forms.py | 98 | ||||
-rw-r--r-- | ishtar/furnitures/models.py | 6 | ||||
-rw-r--r-- | ishtar/furnitures/urls.py | 6 | ||||
-rw-r--r-- | ishtar/furnitures/views.py | 25 | ||||
-rw-r--r-- | ishtar/templates/confirm_wizard.html | 27 | ||||
-rw-r--r-- | ishtar/templates/default_wizard.html | 4 | ||||
-rw-r--r-- | ishtar/templates/wizard_done.html | 6 | ||||
-rw-r--r-- | static/media/style.css | 9 |
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>» <button name="form_prev_step" value="{{forloop.counter0}}">{{step.form_label}}</button></li> + <li>» <button name="form_prev_step" value="{{forloop.counter0}}">{{step.form_label}}</button></li> {% endfor %} - <li class='current'>» <a href='#'>{{current_step.form_label}}</a></li> + <li class='current'>» <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>» <button name="form_prev_step" value="{{forloop.counter0}}">{{step.form_label}}</button></li> + <li>» <button name="form_prev_step" value="{{forloop.counter0}}">{{step.form_label}}</button></li> {% endfor %} - <li class='current'>» <a href='#'>{{current_step.form_label}}</a></li> + <li class='current'>» <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>» <a href='?form_prev_step={{forloop.counter0}}'>{{step.form_label}}</a></li> -{% endfor %} - <li class='current'>» <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; +} |