diff options
author | Étienne Loks <etienne.loks@peacefrogs.net> | 2013-09-03 01:26:53 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@peacefrogs.net> | 2013-09-03 01:38:30 +0200 |
commit | f7abfdbcc4066121d79bd09a389535a19359edc1 (patch) | |
tree | b3547fddea0b516f4f329708e4a9f51995a34157 /archaeological_operations | |
parent | 68c2fdd71ac6dc7b90a08790acef6b7d1722605a (diff) | |
download | Ishtar-f7abfdbcc4066121d79bd09a389535a19359edc1.tar.bz2 Ishtar-f7abfdbcc4066121d79bd09a389535a19359edc1.zip |
Add a widget to do free input parcel additions (refs #809)
Diffstat (limited to 'archaeological_operations')
-rw-r--r-- | archaeological_operations/forms.py | 88 | ||||
-rw-r--r-- | archaeological_operations/widgets.py | 9 | ||||
-rw-r--r-- | archaeological_operations/wizards.py | 10 |
3 files changed, 96 insertions, 11 deletions
diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py index 1fc081ea4..2071dd00f 100644 --- a/archaeological_operations/forms.py +++ b/archaeological_operations/forms.py @@ -27,16 +27,19 @@ from django.conf import settings from django.core import validators from django.core.exceptions import ObjectDoesNotExist from django.db.models import Max -from django.forms.formsets import DELETION_FIELD_NAME +from django.forms.formsets import DELETION_FIELD_NAME, TOTAL_FORM_COUNT from django.shortcuts import render_to_response from django.template import RequestContext from django.utils.translation import ugettext_lazy as _ +from django.utils.safestring import mark_safe from ishtar_common.models import valid_id, PersonType, Person, Town from archaeological_files.models import File import models -from widgets import ParcelWidget + +from widgets import ParcelWidget, SelectParcelWidget from ishtar_common import widgets + from ishtar_common.forms import BaseFormSet, FinalForm, FormSet, \ ClosingDateFormSelection, formset_factory, get_now, reverse_lazy, \ get_form_selection, TableSelect @@ -44,6 +47,8 @@ from ishtar_common.forms_common import TownForm, TownFormSet, TownFormset, \ AuthorFormset, SourceForm, SourceSelect, \ SourceDeletionForm, get_town_field +from archaeological_operations.utils import parse_parcels + class ParcelField(forms.MultiValueField): def __init__(self, *args, **kwargs): if 'widget' not in kwargs: @@ -96,15 +101,84 @@ class ParcelForm(forms.Form): u"fields are required.")) return self.cleaned_data +class ParcelSelectionForm(forms.Form): + _parcel_selection = forms.CharField(label=_(u"Full text input"), + widget=SelectParcelWidget(attrs={'class':'parcel-select'}), + max_length=100, help_text=_(u"example: \"2013: XD:1 to "\ + u"13,24,33 to 39, YD:24\" or \"AB:24,AC:42\""), + required=False) + class ParcelFormSet(FormSet): + SELECTION_FORM = ParcelSelectionForm + + def __init__(self, *args, **kwargs): + super(FormSet, self).__init__(*args, **kwargs) + if self.forms[0].__class__.__name__ == 'ParcelForm': + self.selection_form = ParcelSelectionForm() + + def as_table(self): + # add dynamic widget + render = self.selection_form.as_table() + render += super(FormSet, self).as_table() + return mark_safe(render) + + def as_p(self): + # add dynamic widget + render = self.selection_form.as_p() + render += super(FormSet, self).as_p() + return mark_safe(render) + + def as_ul(self): + # add dynamic widget + render = self.selection_form.as_ul() + render += super(FormSet, self).as_ul() + return mark_safe(render) + def add_fields(self, form, index): super(FormSet, self).add_fields(form, index) def clean(self): - """Checks that no parcels are duplicated.""" - return self.check_duplicate(('town', 'section', - 'parcel_number', 'year'), - _(u"There are identical parcels.")) + # manage parcel selection + last_town, parcels = None, [] + if hasattr(self, 'cleaned_data') and self.cleaned_data: + for parcel in reversed(self.cleaned_data): + if parcel.get('town'): + last_town = parcel.get('town') + break + if not last_town: + towns = self.forms[0].fields['town'].choices + if towns: + towns.pop(0) # remove first empty + if towns: + last_town = towns[0][0] + if self.data.get('_parcel_selection'): + parcels = parse_parcels(self.data['_parcel_selection']) + if last_town: + for idx, parcel in enumerate(parcels): + parcel['town'] = last_town + parcel['DELETE'] = False + parcels[idx] = parcel + c_max = self.total_form_count() + # pop the last extra form + extra_form = self.forms.pop() + for idx, parcel in enumerate(parcels): + form = self._construct_form(idx + c_max) + for k in parcel: + self.data[form.prefix+'-'+k] = parcel[k] + # reconstruct with correct binded data + form = self._construct_form(idx + c_max) + form.cleaned_data = parcel + self.forms.append(form) + self._errors.append(None) + self.forms.append(extra_form) + self.data[self.prefix+'-'+TOTAL_FORM_COUNT] = c_max + len(parcels) + self.management_form.data = self.data + self.management_form.is_valid() + # Checks that no parcels are duplicated. + self.check_duplicate(('town', 'section', 'parcel_number', + 'year'), _(u"There are identical parcels.")) + if hasattr(self, 'cleaned_data') and self.cleaned_data: + return self.cleaned_data ParcelFormSet = formset_factory(ParcelForm, can_delete=True, formset=ParcelFormSet) @@ -171,7 +245,7 @@ class OperationFormSelection(forms.Form): return cleaned_data class OperationCodeInput(forms.TextInput): - """Manage auto complete whene changing year in form""" + """Manage auto complete when changing year in form""" def render(self, *args, **kwargs): name, value = args base_name = '-'.join(name.split('-')[:-1]) diff --git a/archaeological_operations/widgets.py b/archaeological_operations/widgets.py index 0e84b2047..6c4ebe79a 100644 --- a/archaeological_operations/widgets.py +++ b/archaeological_operations/widgets.py @@ -19,6 +19,8 @@ from django import forms from django.forms import widgets +from django.utils.safestring import mark_safe +from django.utils.translation import ugettext_lazy as _ class ParcelWidget(widgets.MultiWidget): def __init__(self, attrs=None): @@ -41,3 +43,10 @@ class ParcelWidget(widgets.MultiWidget): def format_output(self, rendered_widgets): return u' / '.join(rendered_widgets) + +class SelectParcelWidget(widgets.TextInput): + def render(self, *args, **kwargs): + render = super(SelectParcelWidget, self).render(*args, **kwargs) + render += u" <button name='formset_add' value='add'>%s</button>" \ + % _(u"Add") + return mark_safe(render) diff --git a/archaeological_operations/wizards.py b/archaeological_operations/wizards.py index d24b380dd..91f4be3d4 100644 --- a/archaeological_operations/wizards.py +++ b/archaeological_operations/wizards.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2012 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> +# Copyright (C) 2012-2013 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -138,6 +138,8 @@ class OperationWizard(Wizard): def get_form_initial(self, step, data=None): initial = super(OperationWizard, self).get_form_initial(step) + return initial + ''' self.form_initialized = False if not step.startswith(self.parcel_step_key): return initial @@ -147,7 +149,7 @@ class OperationWizard(Wizard): default.pop('parcel_number') initial.append(default) # necessary to get the appropriate form number - self.form_initialized = True + #self.form_initialized = True elif data: numbers, keys = set(), set() for k in data: @@ -160,8 +162,8 @@ class OperationWizard(Wizard): if numbers and max(numbers) - 1 > 0: initial = [dict([(k, data[step+'-'+unicode(max(numbers)-1)+'-'+k]) for k in keys if k != 'parcel_number'])] - self.form_initialized = True - return initial + #self.form_initialized = True + return initial''' class OperationModificationWizard(OperationWizard): modification = True |