From 14d63bc43b3d7308bfd55c581d3770319ecb9fb6 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 16 Nov 2018 12:12:18 +0100 Subject: Datatable: JS to disable submit button when multiple or none is selected --- ishtar_common/widgets.py | 1 - 1 file changed, 1 deletion(-) (limited to 'ishtar_common/widgets.py') diff --git a/ishtar_common/widgets.py b/ishtar_common/widgets.py index 7d9e06926..3fd48fa0d 100644 --- a/ishtar_common/widgets.py +++ b/ishtar_common/widgets.py @@ -1055,7 +1055,6 @@ class DataTable(Select2Media, forms.RadioSelect): if hasattr(self.associated_model, "QUICK_ACTIONS"): dct['quick_actions'] = \ self.associated_model.get_quick_actions(user=self.user) - self.multiple_select = True source = unicode(self.source) dct.update({'name': name, 'col_names': col_names, -- cgit v1.2.3 From 9a71511b55615c2b83d8dee18e1863391ab95654 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 16 Nov 2018 17:55:00 +0100 Subject: Wizard: display selected on final wizard panel --- archaeological_finds/forms.py | 16 +++++++++++-- archaeological_finds/models_treatments.py | 2 +- archaeological_finds/wizards.py | 20 +++++++++++----- ishtar_common/forms.py | 32 ++++++++++++++++++++++++++ ishtar_common/static/js/ishtar.js | 11 +++++++++ ishtar_common/templates/blocks/DataTables.html | 6 ++++- ishtar_common/widgets.py | 2 +- ishtar_common/wizards.py | 2 +- scss/custom.scss | 5 ++++ 9 files changed, 84 insertions(+), 12 deletions(-) (limited to 'ishtar_common/widgets.py') diff --git a/archaeological_finds/forms.py b/archaeological_finds/forms.py index 663ab3663..4df6629e1 100644 --- a/archaeological_finds/forms.py +++ b/archaeological_finds/forms.py @@ -53,7 +53,8 @@ from bootstrap_datepicker.widgets import DatePicker from ishtar_common import widgets from ishtar_common.forms import CustomForm, CustomFormSearch, FormSet, \ FloatField, reverse_lazy, TableSelect, get_now, FinalForm, \ - ManageOldType, FieldType, IshtarForm, FormHeader, QAForm, HistorySelect + ManageOldType, FieldType, IshtarForm, FormHeader, QAForm, HistorySelect, \ + PkWizardSearch from ishtar_common.forms_common import get_town_field from ishtar_common.models import valid_id, valid_ids, get_current_profile, \ SpatialReferenceSystem, Area, OperationType @@ -910,8 +911,19 @@ class FindDeletionForm(FinalForm): confirm_end_msg = _(u"Would you like to delete this find?") -class UpstreamFindFormSelection(FindFormSelection): +class UpstreamFindFormSelection(PkWizardSearch, FindFormSelection): form_label = _(u"Upstream find") + current_model = models.Find + pk_key = 'resulting_pk' + + pk = forms.CharField( + label="", required=False, + widget=widgets.DataTable( + reverse_lazy('get-find'), + FindSelect, current_model, + multiple_select=True, + source_full=reverse_lazy('get-find-full')), + validators=[valid_ids(current_model)]) def __init__(self, *args, **kwargs): super(UpstreamFindFormSelection, self).__init__(*args, **kwargs) diff --git a/archaeological_finds/models_treatments.py b/archaeological_finds/models_treatments.py index 61d4ce5be..160e9d32d 100644 --- a/archaeological_finds/models_treatments.py +++ b/archaeological_finds/models_treatments.py @@ -68,7 +68,7 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem, "upstream_cached_label": _(u"Upstream find"), "treatment_types__label": _(u"Type"), "treatment_state__label": _(u"State"), - 'person__cached_label': _(u"Responsible"), + "person__cached_label": _(u"Responsible"), } # extra keys than can be passed to save method EXTRA_SAVED_KEYS = ('items', 'user') diff --git a/archaeological_finds/wizards.py b/archaeological_finds/wizards.py index e90fa745c..3314759d1 100644 --- a/archaeological_finds/wizards.py +++ b/archaeological_finds/wizards.py @@ -119,14 +119,17 @@ class TreatmentWizard(Wizard): kwargs['user'] = self.request.user return kwargs - def get_current_find(self): + def get_current_finds(self): step = self.steps.current if not step: return find_form_key = 'selecfind-treatment_creation' - find_id = self.session_get_value(find_form_key, "resulting_pk") + find_ids = self.session_get_value(find_form_key, "resulting_pk") try: - return models.Find.objects.get(pk=int(find_id)) + return [ + models.Find.objects.get(pk=int(find_id.strip())) + for find_id in find_ids.split(u',') + ] except(TypeError, ValueError, ObjectDoesNotExist): pass @@ -134,12 +137,17 @@ class TreatmentWizard(Wizard): initial = super(TreatmentWizard, self).get_form_initial(step) if step != 'basetreatment-treatment_creation': return initial - find = self.get_current_find() - if not find or not find.container: + finds = self.get_current_finds() + if not finds: + return initial + locations = [find.container.location.pk for find in finds + if find.container] + # no location or multiple locations + if not locations or len(set(locations)) != 1: return initial if not initial: initial = {} - initial['location'] = find.container.location.pk + initial['location'] = locations[0] return initial def get_extra_model(self, dct, form_list): diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py index 20c65971e..63551ede2 100644 --- a/ishtar_common/forms.py +++ b/ishtar_common/forms.py @@ -341,6 +341,38 @@ class CustomForm(BSForm): return sorted(customs, key=lambda x: x[1]) +class PkWizardSearch(object): + current_model = None + pk_key = None + + @classmethod + def get_formated_datas(cls, cleaned_datas): + if not cls.current_model or not cls.pk_key: + return [] + items = [] + for data in cleaned_datas: + if not data or cls.pk_key not in data or not data[cls.pk_key]: + continue + pks = data[cls.pk_key] + for pk in unicode(pks).split(u','): + if not pk: + continue + try: + items.append( + unicode(cls.current_model.objects.get(pk=int(pk))) + ) + except (cls.current_model.DoesNotExist, ValueError): + continue + return [ + (u"", + mark_safe( + u"" + )) + ] + + + class CustomFormSearch(forms.Form): need_user_for_initialization = True diff --git a/ishtar_common/static/js/ishtar.js b/ishtar_common/static/js/ishtar.js index e4e80d681..ea0ccc516 100644 --- a/ishtar_common/static/js/ishtar.js +++ b/ishtar_common/static/js/ishtar.js @@ -968,3 +968,14 @@ var dt_single_enable_disable_submit_button = function(e, dt, type, indexes){ $("#validation-bar #submit_form").prop('disabled', true); } }; + +var dt_multi_enable_disable_submit_button = function(e, dt, type, indexes){ + var rows = dt.rows( { selected: true } ).count(); + if (rows >= 1) { + $("#validation-bar #submit_form").prop('title', ""); + $("#validation-bar #submit_form").prop('disabled', false); + } else { + $("#validation-bar #submit_form").prop('title', select_only_one_msg); + $("#validation-bar #submit_form").prop('disabled', true); + } +}; diff --git a/ishtar_common/templates/blocks/DataTables.html b/ishtar_common/templates/blocks/DataTables.html index e1966787b..096650115 100644 --- a/ishtar_common/templates/blocks/DataTables.html +++ b/ishtar_common/templates/blocks/DataTables.html @@ -194,7 +194,8 @@ jQuery(document).ready(function(){ ], "initComplete": function(settings, json) { var api = new $.fn.dataTable.Api(settings); - dt_single_enable_disable_submit_button(null, api); + {% if not multiple_select %}dt_single_enable_disable_submit_button(null, api); + {% else %}dt_multi_enable_disable_submit_button(null, api);{% endif %} } }; @@ -207,6 +208,9 @@ jQuery(document).ready(function(){ {% if not multiple_select %} datatable_{{sname}}.on('select', dt_single_enable_disable_submit_button); datatable_{{sname}}.on('deselect', dt_single_enable_disable_submit_button); + {% else %} + datatable_{{sname}}.on('select', dt_multi_enable_disable_submit_button); + datatable_{{sname}}.on('deselect', dt_multi_enable_disable_submit_button); {% endif %} {% if multiple %} diff --git a/ishtar_common/widgets.py b/ishtar_common/widgets.py index 3fd48fa0d..f668ee534 100644 --- a/ishtar_common/widgets.py +++ b/ishtar_common/widgets.py @@ -927,7 +927,7 @@ class DataTable(Select2Media, forms.RadioSelect): :param new: :param new_message: :param source_full: url to get full listing - :param multiple_select: + :param multiple_select: select multiple is available :param sortname: column name (model attribute) to use to sort :param col_prefix: prefix to remove to col_names """ diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index a439cc014..7fd19f721 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -1181,7 +1181,7 @@ class Wizard(IshtarWizard): return vals def get_current_object(self): - """Get the current object for an instancied wizard""" + """Get the current object for an instanced wizard""" current_obj = None for key in self.main_item_select_keys: main_form_key = key + self.url_name diff --git a/scss/custom.scss b/scss/custom.scss index 788220466..f0168d469 100644 --- a/scss/custom.scss +++ b/scss/custom.scss @@ -477,6 +477,11 @@ div#foot a:hover { list-style: none; } +ul.compact{ + padding: 0; + margin: 0; +} + .help-text{ max-height: 250px; overflow: auto; -- cgit v1.2.3 From 40006039c77f3e6a689ad75e53e8ede6b8e531ec Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Mon, 3 Dec 2018 17:41:46 +0100 Subject: cm->m / g->kg widget --- archaeological_finds/forms.py | 27 ++++++++++++------- .../templates/blocks/CentimeterMeterWidget.html | 21 +++++++++++++++ .../templates/blocks/GramKilogramWidget.html | 21 +++++++++++++++ ishtar_common/widgets.py | 30 ++++++++++++++++++++++ 4 files changed, 90 insertions(+), 9 deletions(-) create mode 100644 ishtar_common/templates/blocks/CentimeterMeterWidget.html create mode 100644 ishtar_common/templates/blocks/GramKilogramWidget.html (limited to 'ishtar_common/widgets.py') diff --git a/archaeological_finds/forms.py b/archaeological_finds/forms.py index 66f99d08b..9e64a901a 100644 --- a/archaeological_finds/forms.py +++ b/archaeological_finds/forms.py @@ -199,19 +199,28 @@ class BaseFindForm(CustomForm, ManageOldType): label=_(u"Comment on dating"), required=False, widget=forms.Textarea) HEADERS['length'] = FormHeader(_(u"Dimensions")) - length = FloatField(label=_(u"Length (cm)"), required=False) - width = FloatField(label=_(u"Width (cm)"), required=False) - height = FloatField(label=_(u"Height (cm)"), required=False) - diameter = FloatField(label=_(u"Diameter (cm)"), required=False) - thickness = FloatField(label=_(u"Thickness (cm)"), required=False) + length = FloatField(label=_(u"Length (cm)"), + widget=widgets.CentimeterMeterWidget, required=False) + width = FloatField(label=_(u"Width (cm)"), required=False, + widget=widgets.CentimeterMeterWidget) + height = FloatField(label=_(u"Height (cm)"), + widget=widgets.CentimeterMeterWidget, required=False) + thickness = FloatField(label=_(u"Thickness (cm)"), + widget=widgets.CentimeterMeterWidget, required=False) + diameter = FloatField(label=_(u"Diameter (cm)"), + widget=widgets.CentimeterMeterWidget, required=False) volume = FloatField(label=_(u"Volume (l)"), required=False) - weight = FloatField(label=_(u"Weight (g)"), required=False) + weight = FloatField(label=_(u"Weight (g)"), + widget=widgets.GramKilogramWidget, required=False) clutter_long_side = FloatField( - label=_(u"Clutter long side (cm)"), required=False) + label=_(u"Clutter long side (cm)"), + widget=widgets.CentimeterMeterWidget, required=False) clutter_short_side = FloatField( - label=_(u"Clutter short side (cm)"), required=False) + label=_(u"Clutter short side (cm)"), + widget=widgets.CentimeterMeterWidget, required=False) clutter_height = FloatField( - label=_(u"Clutter height (cm)"), required=False) + label=_(u"Clutter height (cm)"), + widget=widgets.CentimeterMeterWidget, required=False) dimensions_comment = forms.CharField( label=_(u"Dimensions comment"), required=False, widget=forms.Textarea) diff --git a/ishtar_common/templates/blocks/CentimeterMeterWidget.html b/ishtar_common/templates/blocks/CentimeterMeterWidget.html new file mode 100644 index 000000000..00c1614b5 --- /dev/null +++ b/ishtar_common/templates/blocks/CentimeterMeterWidget.html @@ -0,0 +1,21 @@ +
+ +
+
+ {{unit}} (0 m) +
+
+
+ diff --git a/ishtar_common/templates/blocks/GramKilogramWidget.html b/ishtar_common/templates/blocks/GramKilogramWidget.html new file mode 100644 index 000000000..27c066d13 --- /dev/null +++ b/ishtar_common/templates/blocks/GramKilogramWidget.html @@ -0,0 +1,21 @@ +
+ +
+
+ {{unit}} (0 kg) +
+
+
+ diff --git a/ishtar_common/widgets.py b/ishtar_common/widgets.py index f668ee534..326966064 100644 --- a/ishtar_common/widgets.py +++ b/ishtar_common/widgets.py @@ -470,6 +470,36 @@ class SquareMeterWidget(forms.TextInput): return mark_safe(rendered) +class GramKilogramWidget(forms.TextInput): + def render(self, name, value, attrs=None, renderer=None): + if not value: + value = u"" + final_attrs = flatatt( + self.build_attrs(attrs, {"name": name, "value": value})) + dct = {'final_attrs': final_attrs, + 'unit': u"g", + 'id': attrs['id'], + "safe_id": attrs['id'].replace('-', '_')} + t = loader.get_template('blocks/GramKilogramWidget.html') + rendered = t.render(dct) + return mark_safe(rendered) + + +class CentimeterMeterWidget(forms.TextInput): + def render(self, name, value, attrs=None, renderer=None): + if not value: + value = u"" + final_attrs = flatatt( + self.build_attrs(attrs, {"name": name, "value": value})) + dct = {'final_attrs': final_attrs, + 'unit': u"cm", + 'id': attrs['id'], + "safe_id": attrs['id'].replace('-', '_')} + t = loader.get_template('blocks/CentimeterMeterWidget.html') + rendered = t.render(dct) + return mark_safe(rendered) + + AreaWidget = forms.TextInput if settings.SURFACE_UNIT == 'square-metre': -- cgit v1.2.3 From 4b3ff3e9279ca0bb645f9ef6f9f471422af55a1b Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Wed, 12 Dec 2018 17:46:24 +0100 Subject: Adjust multiple fields --- ishtar_common/widgets.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'ishtar_common/widgets.py') diff --git a/ishtar_common/widgets.py b/ishtar_common/widgets.py index 326966064..95b51ffb4 100644 --- a/ishtar_common/widgets.py +++ b/ishtar_common/widgets.py @@ -300,7 +300,7 @@ class CheckboxSelectMultiple(CheckboxSelectMultipleBase): def render(self, name, value, attrs=None, choices=()): if type(value) in (str, unicode): value = value.split(',') - if type(value) not in (list, tuple): + if not isinstance(value, (list, tuple)): value = [value] return super(CheckboxSelectMultiple, self).render(name, value, attrs) @@ -356,6 +356,14 @@ class Select2BaseField(object): class Select2MultipleField(Select2BaseField, forms.MultipleChoiceField): multiple = True + def to_python(self, value): + if not isinstance(value, (list, tuple)): + if value: + value = value.split(',') + else: + value = [] + return super(Select2MultipleField, self).to_python(value) + class Select2SimpleField(Select2BaseField, forms.ChoiceField): pass -- cgit v1.2.3 From 2f0bfdd8283b7191789de1032f73f14ebb2df337 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 4 Jan 2019 11:48:06 +0100 Subject: Select2widget: fix bad initialization --- archaeological_finds/views.py | 3 --- ishtar_common/widgets.py | 6 ++++-- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'ishtar_common/widgets.py') diff --git a/archaeological_finds/views.py b/archaeological_finds/views.py index 3442ed2f4..fb5cdc11e 100644 --- a/archaeological_finds/views.py +++ b/archaeological_finds/views.py @@ -293,14 +293,11 @@ def find_modify(request, pk): q = models.Find.objects.filter(pk=pk) if not q.count(): raise Http404() - step = "selecrecord-find_modification" - ''' step = 'find-find_modification' find = q.all()[0] if find.base_finds.count() > 1: step = 'simplefind-find_modification' - ''' return redirect( reverse('find_modification', kwargs={'step': step})) diff --git a/ishtar_common/widgets.py b/ishtar_common/widgets.py index 95b51ffb4..5853c9675 100644 --- a/ishtar_common/widgets.py +++ b/ishtar_common/widgets.py @@ -224,6 +224,10 @@ class Select2Base(Select2Media): else: attrs['style'] = "width: 370px" + if value: + if type(value) not in (list, tuple): + value = value.split(',') + options = "" if self.remote: options = """{ @@ -248,8 +252,6 @@ class Select2Base(Select2Media): }""" % self.remote if value: choices = [] - if type(value) not in (list, tuple): - value = value.split(',') for v in value: try: choices.append((v, self.model.objects.get(pk=v))) -- cgit v1.2.3