From 577438f9ea0f25f5596aa1bb8e262d3c5a30173f Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Wed, 7 Jul 2021 09:39:29 +0200 Subject: Preventive file - inline forms --- DEVELOP.md | 7 +- archaeological_files/forms.py | 87 +++++++++++++--------- .../templates/ishtar/forms/preventive_detail.html | 45 ++++++++++- archaeological_files/views.py | 9 ++- ishtar_common/static/js/ishtar.js | 23 ++++++ ishtar_common/templates/base.html | 4 + .../templates/blocks/bs_field_snippet.html | 2 +- .../templates/blocks/bs_formset_snippet.html | 20 ++++- .../templates/ishtar/forms/base_form.html | 5 ++ 9 files changed, 160 insertions(+), 42 deletions(-) diff --git a/DEVELOP.md b/DEVELOP.md index e91ca3ccf..2c9c6aaf3 100644 --- a/DEVELOP.md +++ b/DEVELOP.md @@ -42,10 +42,12 @@ cd ishtar ISHTAR_PATH=`pwd` cp example_project/local_settings.py.sample example_project/local_settings.py editor example_project/local_settings.py -# edit settings: SECRET_KEY, DATABASE +# edit settings: SECRET_KEY, DATABASE, comment STATIC_URL and MEDIA_URL ``` ``` python +SECRET_KEY = "change-this-secret" + DATABASES = { 'default': { 'NAME': 'ishtar', @@ -56,6 +58,9 @@ DATABASES = { 'PASSWORD': 'mypassword', }, } + +# STATIC_URL = BASE_URL + 'static/' +# MEDIA_URL = BASE_URL + 'mydomain/media/' ``` ``` bash diff --git a/archaeological_files/forms.py b/archaeological_files/forms.py index 51d1fdeb0..1710a5560 100644 --- a/archaeological_files/forms.py +++ b/archaeological_files/forms.py @@ -528,14 +528,20 @@ class FileFormPreventiveDetail(forms.ModelForm, CustomForm, ManageOldType): pk = forms.IntegerField(label="", required=False, widget=forms.HiddenInput) start_date = forms.DateField( - label=_("Start date"), widget=DatePicker, required=False + label=_("Start date"), required=False, + widget=DatePicker(attrs={"bs_col_width": "col-6 col-lg-3"}), + ) + end_date = forms.DateField( + label=_("End date"), required=False, + widget=DatePicker(attrs={"bs_col_width": "col-6 col-lg-3"}), ) - end_date = forms.DateField(label=_("End date"), widget=DatePicker, required=False) ground_start_date = forms.DateField( - label=_("Ground start date"), widget=DatePicker, required=False + label=_("Ground start date"), required=False, + widget=DatePicker(attrs={"bs_col_width": "col-6 col-lg-3"}), ) ground_end_date = forms.DateField( - label=_("Ground end date"), widget=DatePicker, required=False + label=_("Ground end date"), required=False, + widget=DatePicker(attrs={"bs_col_width": "col-6 col-lg-3"}), ) study_period = forms.CharField( label=_("Study period"), @@ -543,10 +549,11 @@ class FileFormPreventiveDetail(forms.ModelForm, CustomForm, ManageOldType): required=False, ) execution_report_date = forms.DateField( - label=_("Execution report date"), widget=DatePicker, required=False + label=_("Execution report date"), required=False, + widget=DatePicker(attrs={"bs_col_width": "col-6 col-lg-3"}), ) total_developed_surface = forms.FloatField( - widget=widgets.AreaWidget, + widget=widgets.AreaWidget(attrs={"bs_col_width": "col-6 col-lg-3"}), label=_("Total developed surface (m2)"), required=False, validators=[ @@ -556,7 +563,7 @@ class FileFormPreventiveDetail(forms.ModelForm, CustomForm, ManageOldType): ) total_surface = forms.FloatField( required=False, - widget=widgets.AreaWidget, + widget=widgets.AreaWidget(attrs={"bs_col_width": "col-6 col-lg-3"}), label=_("Total surface (m2)"), validators=[ validators.MinValueValidator(0), @@ -565,7 +572,7 @@ class FileFormPreventiveDetail(forms.ModelForm, CustomForm, ManageOldType): ) linear_meter = forms.IntegerField( label=_("Linear meter (m)"), required=False, - widget=widgets.MeterKilometerWidget, + widget=widgets.MeterKilometerWidget(attrs={"bs_col_width": "col-6 col-lg-3"}), ) def __init__(self, *args, **kwargs): @@ -586,17 +593,32 @@ class FileBaseFormset(forms.BaseModelFormSet): self.queryset = self.model.objects.filter(file_id=self.instance.pk) +INLINE_JOB_FIELDS = ["man_by_day_planned", "days_planned", "man_by_day_worked", + "days_worked"] +JOB_WIDGETS = { + "man_by_day_planned": forms.NumberInput(attrs={"class": "w-50 form-planned"}), + "days_planned": forms.NumberInput(attrs={"class": "w-50 form-planned"}), + "man_by_day_worked": forms.NumberInput(attrs={"class": "w-50 form-worked"}), + "days_worked": forms.NumberInput(attrs={"class": "w-50 form-worked"}) +} + +JOB_LABELS = { + "man_by_day_planned": _("Man by day"), + "days_planned": _("Days"), + "man_by_day_worked": _("Man by day"), + "days_worked": _("Days"), +} + class PreventiveFileJobForm(forms.ModelForm): file_id = forms.IntegerField(widget=forms.HiddenInput) - job = forms.ChoiceField(choices=[]) - man_by_day_planned = forms.FloatField(_("Man by day - planned"), required=False) - days_planned = forms.FloatField(_("Days - planned"), required=False) - man_by_day_worked = forms.FloatField(_("Man by day - worked"), required=False) - days_worked = forms.FloatField(_("Days - worked"), required=False) class Meta: model = models.PreventiveFileJob + fields = ["job"] + INLINE_JOB_FIELDS exclude = ["file"] + widgets = JOB_WIDGETS + labels = JOB_LABELS + class PreventiveFileJobBaseFormSet(FileBaseFormset): @@ -605,22 +627,20 @@ class PreventiveFileJobBaseFormSet(FileBaseFormset): PreventiveFileJobFormSet = formset_factory( PreventiveFileJobForm, formset=PreventiveFileJobBaseFormSet, can_delete=True) -PreventiveFileJobFormSet.form_label = _("Preventive - Jobs") +PreventiveFileJobFormSet.form_label = _("Jobs") PreventiveFileJobFormSet.form_admin_name = _("Preventive file - 030 - Jobs") PreventiveFileJobFormSet.form_slug = "preventive-030-jobs" +PreventiveFileJobFormSet.dynamic_add = True class PreventiveFileGroundJobForm(forms.ModelForm): file_id = forms.IntegerField(widget=forms.HiddenInput) - ground_job = forms.ChoiceField(choices=[]) - man_by_day_planned = forms.FloatField(_("Man by day - planned"), required=False) - days_planned = forms.FloatField(_("Days - planned"), required=False) - man_by_day_worked = forms.FloatField(_("Man by day - worked"), required=False) - days_worked = forms.FloatField(_("Days - worked"), required=False) class Meta: model = models.PreventiveFileGroundJob - exclude = ["file"] + fields = ["job"] + INLINE_JOB_FIELDS + widgets = JOB_WIDGETS + labels = JOB_LABELS class PreventiveFileGroundJobBaseFormSet(FileBaseFormset): @@ -631,24 +651,22 @@ PreventiveFileGroundJobFormSet = formset_factory( PreventiveFileGroundJobForm, formset=PreventiveFileGroundJobBaseFormSet, can_delete=True ) -PreventiveFileGroundJobFormSet.form_label = _("Preventive - Ground jobs") +PreventiveFileGroundJobFormSet.form_label = _("Ground jobs") PreventiveFileGroundJobFormSet.form_admin_name = _( "Preventive file - 040 - Ground jobs" ) PreventiveFileGroundJobFormSet.form_slug = "preventive-040-ground-jobs" +PreventiveFileGroundJobFormSet.dynamic_add = True class PreventiveFileEquipmentForm(forms.ModelForm): file_id = forms.IntegerField(widget=forms.HiddenInput) - equipment = forms.ChoiceField(choices=[]) - man_by_day_planned = forms.FloatField(_("Man by day - planned"), required=False) - days_planned = forms.FloatField(_("Days - planned"), required=False) - man_by_day_worked = forms.FloatField(_("Man by day - worked"), required=False) - days_worked = forms.FloatField(_("Days - worked"), required=False) class Meta: model = models.PreventiveFileEquipmentCost - exclude = ["file"] + fields = ["equipment_cost"] + INLINE_JOB_FIELDS + widgets = JOB_WIDGETS + labels = JOB_LABELS class PreventiveFileEquipmentBaseFormSet(FileBaseFormset): @@ -659,22 +677,20 @@ PreventiveFileEquipmentFormSet = formset_factory( PreventiveFileEquipmentForm, formset=PreventiveFileEquipmentBaseFormSet, can_delete=True ) -PreventiveFileEquipmentFormSet.form_label = _("Preventive - Equipment") +PreventiveFileEquipmentFormSet.form_label = _("Equipment") PreventiveFileEquipmentFormSet.form_admin_name = _("Preventive file - 050 - Equipments") PreventiveFileEquipmentFormSet.form_slug = "preventive-050-equipments" +PreventiveFileEquipmentFormSet.dynamic_add = True class PreventiveFileTechnicalServiceForm(forms.ModelForm): file_id = forms.IntegerField(widget=forms.HiddenInput) - technical_service = forms.ChoiceField(choices=[]) - man_by_day_planned = forms.FloatField(_("Man by day - planned"), required=False) - days_planned = forms.FloatField(_("Days - planned"), required=False) - man_by_day_worked = forms.FloatField(_("Man by day - worked"), required=False) - days_worked = forms.FloatField(_("Days - worked"), required=False) class Meta: model = models.PreventiveFileTechnicalServiceCost - exclude = ["file"] + fields = ["technical_service_cost"] + INLINE_JOB_FIELDS + widgets = JOB_WIDGETS + labels = JOB_LABELS class PreventiveFileTechnicalServiceBaseFormSet(FileBaseFormset): @@ -685,11 +701,12 @@ PreventiveFileTechnicalServiceFormSet = formset_factory( PreventiveFileTechnicalServiceForm, formset=PreventiveFileTechnicalServiceBaseFormSet, can_delete=True ) -PreventiveFileTechnicalServiceFormSet.form_label = _("Preventive - Technical Services") +PreventiveFileTechnicalServiceFormSet.form_label = _("Technical Services") PreventiveFileTechnicalServiceFormSet.form_admin_name = _( "Preventive file - 060 - TechnicalServices" ) PreventiveFileTechnicalServiceFormSet.form_slug = "preventive-060-technical_services" +PreventiveFileTechnicalServiceFormSet.dynamic_add = True class AdministrativeActFileModifySelect(TableSelect): diff --git a/archaeological_files/templates/ishtar/forms/preventive_detail.html b/archaeological_files/templates/ishtar/forms/preventive_detail.html index 3cdfb3da0..20adcccfb 100644 --- a/archaeological_files/templates/ishtar/forms/preventive_detail.html +++ b/archaeological_files/templates/ishtar/forms/preventive_detail.html @@ -1,2 +1,45 @@ {% extends "ishtar/forms/base_form.html" %} -{% load i18n %} +{% load i18n table_form %} + +{% block bs_form_inlines %} +
+
+
+
+ + +
+
+
+ +
+
+ +
+ {{block.super}} +
+
+{% endblock %} + +{# #} diff --git a/archaeological_files/views.py b/archaeological_files/views.py index a927a94e6..366ef3754 100644 --- a/archaeological_files/views.py +++ b/archaeological_files/views.py @@ -364,15 +364,19 @@ class MixFormFormsetUpdateView(UpdateView): def get(self, request, *args, **kwargs): self.object = self.get_object() self.inline_forms = [ - inline(instance=self.object) for inline in self.form_inlines_class + inline(instance=self.object, + prefix=getattr(inline, "form_slug", "form")) + for inline in self.form_inlines_class ] return super(MixFormFormsetUpdateView, self).get(request, *args, **kwargs) def post(self, request, *args, **kwargs): self.object = self.get_object() + attrs = {"instance": self.object} form = self.form_class(data=request.POST, instance=self.object) inline_forms = [ - inline(instance=self.object, data=request.POST) + inline(instance=self.object, data=request.POST, + prefix=getattr(inline, "form_slug", "form")) for inline in self.form_inlines_class ] if form.is_valid() and all((inline.is_valid() for inline in inline_forms)): @@ -410,7 +414,6 @@ class PreventiveEditView(IshtarMixin, LoginRequiredMixin, MixFormFormsetUpdateVi template_name = "ishtar/forms/preventive_detail.html" model = models.File - def get_success_url(self): return reverse("file_modification") + "?open_item={}".format(self.object.pk) diff --git a/ishtar_common/static/js/ishtar.js b/ishtar_common/static/js/ishtar.js index 897356fe3..3fa293deb 100644 --- a/ishtar_common/static/js/ishtar.js +++ b/ishtar_common/static/js/ishtar.js @@ -1874,4 +1874,27 @@ var update_select_widget = function(input_name, values, only_values, excluded_va } } $("#id_" + input_name).html(options); +}; + +var inline_register_add_button = function(slug){ + let inline_form = document.querySelectorAll(".form-" + slug); + let inline_container = document.querySelector("#formset-container-" + slug); + let inline_add_button = document.querySelector("#add-form-" + slug); + let inline_div_add_button = document.querySelector("#div-add-form-" + slug); + let inline_total_forms = document.querySelector("#id_" + slug + "-TOTAL_FORMS"); + let inline_form_num = inline_form.length - 1; + inline_add_button.addEventListener( + 'click', function(e){ + e.preventDefault(); + let new_form = inline_form[0].cloneNode(true); + let form_regex_var = slug + '(\\d){1}-'; + let form_regex = new RegExp(form_regex_var, 'g'); + inline_form_num++; + console.log(new_form); + new_form.innerHTML = new_form.innerHTML.replace( + form_regex, slug + `-${inline_form_num}-`); + inline_container.insertBefore(new_form, inline_div_add_button); + inline_total_forms.setAttribute('value', `${inline_form_num+1}`); + } + ); }; \ No newline at end of file diff --git a/ishtar_common/templates/base.html b/ishtar_common/templates/base.html index f9feef533..af4396be3 100644 --- a/ishtar_common/templates/base.html +++ b/ishtar_common/templates/base.html @@ -265,6 +265,10 @@
+ diff --git a/ishtar_common/templates/blocks/bs_field_snippet.html b/ishtar_common/templates/blocks/bs_field_snippet.html index dcee87f7f..beecf624f 100644 --- a/ishtar_common/templates/blocks/bs_field_snippet.html +++ b/ishtar_common/templates/blocks/bs_field_snippet.html @@ -1,5 +1,5 @@ {% load i18n %} -
{% if field.label %}{{ field.label_tag }}{% endif %} {% if extra_field_label %}{% endif %} diff --git a/ishtar_common/templates/blocks/bs_formset_snippet.html b/ishtar_common/templates/blocks/bs_formset_snippet.html index 0d089ee1b..3a7e537d3 100644 --- a/ishtar_common/templates/blocks/bs_formset_snippet.html +++ b/ishtar_common/templates/blocks/bs_formset_snippet.html @@ -1,6 +1,9 @@ {% load i18n from_dict %} -
+
+ {{ formset.non_form_errors.as_ul }} + {{ formset.management_form }} {% for form in formset %} +
{% if form.non_field_errors and not no_error %} {% endfor %} + {% if formset.dynamic_add %} +
+
+ +
+
+ + {% endif %}
diff --git a/ishtar_common/templates/ishtar/forms/base_form.html b/ishtar_common/templates/ishtar/forms/base_form.html index fb1fc997f..3f069e7d6 100644 --- a/ishtar_common/templates/ishtar/forms/base_form.html +++ b/ishtar_common/templates/ishtar/forms/base_form.html @@ -23,10 +23,15 @@ {% endif %} {% block form_head %} {% endblock %} + {% block bs_form %} {% bs_form form 0 True %} + {% endblock %} + {% block bs_form_inlines %} {% for inline in inline_forms %} +

{{inline.form_label}}

{% bs_formset inline 0 True %} {% endfor %} + {% endblock %}
{% endblock %} -- cgit v1.2.3