summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2021-07-07 09:39:29 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2021-10-25 12:06:02 +0200
commit62823edbc5cb453869f5a07f690658580ed8df71 (patch)
tree52fd5556d11e905b775dc8e4cf8bf7b41c88b8ee
parent2d0512c72b2a8feb6fa10c3cd8b8c53bc74a9ba6 (diff)
downloadIshtar-62823edbc5cb453869f5a07f690658580ed8df71.tar.bz2
Ishtar-62823edbc5cb453869f5a07f690658580ed8df71.zip
Preventive file - inline forms
-rw-r--r--DEVELOP.md7
-rw-r--r--archaeological_files/forms.py87
-rw-r--r--archaeological_files/templates/ishtar/forms/preventive_detail.html45
-rw-r--r--archaeological_files/views.py9
-rw-r--r--ishtar_common/static/js/ishtar.js23
-rw-r--r--ishtar_common/templates/base.html4
-rw-r--r--ishtar_common/templates/blocks/bs_field_snippet.html2
-rw-r--r--ishtar_common/templates/blocks/bs_formset_snippet.html20
-rw-r--r--ishtar_common/templates/ishtar/forms/base_form.html5
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 %}
+<div class="card">
+ <div class="card-body">
+ <div class="w-100 pb-3 text-center">
+ <div class="btn-group btn-group-toggle" data-toggle="buttons">
+ <label class="btn btn-lg btn-secondary active">
+ <input value="true" type="radio" name="planned-toggle" id="planned-toggle-true" autocomplete="off" checked>
+ {% trans "Planned" %}
+ </label>
+ <label class="btn btn-lg btn-secondary">
+ <input value="false" type="radio" name="planned-toggle" id="planned-toggle-false" autocomplete="off">
+ {% trans "Worked" %}
+ </label>
+ </div>
+ </div>
+ <div class="w-100 pb-3 text-center">
+ <button class="btn btn-secondary btn-sm form-planned" type="button">{% trans "Add default costs" %}</button>
+ </div>
+ <div class="w-100 pb-3 text-center">
+ <button class="btn btn-secondary btn-sm form-worked" type="button">{% trans "Copy planned costs" %}</button>
+ </div>
+ {{block.super}}
+ </div>
+</div>
+{% endblock %}
+
+{# <script type='text/javascript'> #}
+{% block end_js %}
+ {{block.super}}
+ var check_planned_value = function() {
+ if (this.value == 'false'){
+ $(".form-planned").parent().hide()
+ $(".form-worked").parent().show()
+ } else {
+ $(".form-planned").parent().show()
+ $(".form-worked").parent().hide()
+ }
+ };
+ $('input[type=radio][name=planned-toggle]').change(check_planned_value);
+ $(document).ready(check_planned_value);
+{% endblock %}
+{# </script> #}
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 @@
<div id='message'>
<div class='information'><i class="fa fa-info-circle" aria-hidden="true"></i> <span class='content'></span></div>
</div>
+ <script type='text/javascript'>
+ {% block end_js %}
+ {% endblock %}
+ </script>
</body>
</html>
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 %}
- <div id="main_div-{{field.auto_id}}" class="form-group{% if not field.label %} no-label{% endif %} {% if field.field.widget.attrs.cols or force_large_col %}col-lg-12{% else %}col-lg-6{% endif %}{% if field.errors %} is-invalid{% endif %}{% if field.field.required %} required{% endif %}{% if force_large_col %} full-width{% endif %}"
+ <div id="main_div-{{field.auto_id}}" class="form-group{% if not field.label %} no-label{% endif %} {% if bs_col_width %}{{bs_col_width}}{% elif field.field.widget.attrs.bs_col_width %}{{field.field.widget.attrs.bs_col_width}}{% else %}{% if field.field.widget.attrs.cols or force_large_col %}col-lg-12{% else %}col-lg-6{% endif %}{% endif %}{% if field.errors %} is-invalid{% endif %}{% if field.field.required %} required{% endif %}{% if force_large_col %} full-width{% endif %}"
data-alt-name="{{field.field.alt_name}}">
{% if field.label %}{{ field.label_tag }}{% endif %}
{% if extra_field_label %}<label><em>{{extra_field_label}}</em></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 %}
-<div class="form-row">
+<div id="formset-container-{{formset.prefix}}">
+ {{ formset.non_form_errors.as_ul }}
+ {{ formset.management_form }}
{% for form in formset %}
+ <div class="form-row form-{{formset.prefix}}">
{% if form.non_field_errors and not no_error %}
<div class="alert alert-danger" role="alert">
{{form.non_field_errors}}
@@ -16,11 +19,26 @@
{% csrf_token %}
{% for field in form.visible_fields %}
+ {% with bs_col_width='col-3' %}
{% include "blocks/bs_field_snippet.html" %}
+ {% endwith %}
{% endfor %}
{% if form.extra_render %}
{{form.extra_render|safe}}
{% endif %}
+ </div>
{% endfor %}
+ {% if formset.dynamic_add %}
+ <div class="form-row pb-2" id="div-add-form-{{formset.prefix}}">
+ <div class="col">
+ <button class="btn btn-secondary" id="add-form-{{formset.prefix}}" type="button">{% trans "Add" %}</button>
+ </div>
+ </div>
+ <script>
+ $(document).ready(function(){
+ inline_register_add_button("{{formset.prefix}}");
+ });
+ </script>
+ {% endif %}
</div>
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 %}
+ <h4>{{inline.form_label}}</h4>
{% bs_formset inline 0 True %}
{% endfor %}
+ {% endblock %}
</div>
{% endblock %}