diff --git a/ippisite/ippidb/forms.py b/ippisite/ippidb/forms.py index 9b368d7fc5b6a940f46c79dbbb88f9dd77ebe8a8..ec1fdaf1a7d35654160835dc0d7879635c0c2de6 100644 --- a/ippisite/ippidb/forms.py +++ b/ippisite/ippidb/forms.py @@ -1,13 +1,15 @@ """ iPPI-DB django forms """ +import itertools +from collections import OrderedDict from django import forms from django.contrib import messages from django.core.validators import RegexValidator, MinValueValidator from django.db.models.functions import Upper from django.forms import ModelForm, modelformset_factory, formset_factory, inlineformset_factory -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import ugettext_lazy as _, ugettext from ippidb.ws import get_pdb_uniprot_mapping from .models import * @@ -451,6 +453,45 @@ def compound_formset_factory(min_num: int = None, max_num: int = None): CompoundFormSet = compound_formset_factory(min_num=1) + +""" Step 8.0 : Toolkit for inlined formet """ + + +class BaseInlineNestedFormSet(forms.BaseInlineFormSet): + def add_fields(self, form, index): + super().add_fields(form, index) + delete_field = form.fields.pop('DELETE') + delete_field.widget.attrs["onclick"] = "delete_button_clicked(this)" + delete_field.widget.attrs["class"] = delete_field.widget.attrs.get("class", "") + " formset-item-delete" + delete_field.label = _("DELETE_label") + delete_help_text = ugettext("DELETE_help_text") + if delete_help_text != "DELETE_help_text": + delete_field.help_text = delete_help_text + form.fields = OrderedDict( + itertools.chain([('DELETE', delete_field)], form.fields.items()) + ) + + def is_valid(self): + result = super().is_valid() + print(self.has_changed()) + + if self.is_bound: + for form in self.forms: + result = result and form.is_valid() + if hasattr(form, 'nested'): + result = result and form.nested.is_valid() + + return result + + def save(self, commit=True): + result = super().save(commit=commit) + + for form in self.forms: + if hasattr(form, 'nested'): + if not self._should_delete_form(form): + form.nested.save(commit=commit) + return result + """ Step 8.1 : TestActivityDescriptionForm """ @@ -500,6 +541,7 @@ CompoundActivityResultInlineFormset = inlineformset_factory( parent_model=TestActivityDescription, model=CompoundActivityResult, form=CompoundActivityResultForm, + formset=BaseInlineNestedFormSet, extra=1, can_delete=True, ) @@ -520,7 +562,8 @@ class TestActivityDescriptionBaseModelFormSet(forms.BaseModelFormSet): ) -TestActivityDescriptionFormSet = modelformset_factory( +TestActivityDescriptionFormSet = inlineformset_factory( + parent_model=Ppi, model=TestActivityDescription, form=TestActivityDescriptionForm, formset=TestActivityDescriptionBaseModelFormSet, diff --git a/ippisite/ippidb/static/css/admin-session.css b/ippisite/ippidb/static/css/admin-session.css index d66df4eba90937cd5fe12cc6ce2b7f0c6b004096..d45f1fbc1a3728c04e59ca4892dae80c1b3b78fc 100644 --- a/ippisite/ippidb/static/css/admin-session.css +++ b/ippisite/ippidb/static/css/admin-session.css @@ -306,7 +306,7 @@ Description: IPPI-DB Theme .formset-item.delete-checked .form-group:not(.formset-item-delete-host), .formset-item.delete-checked h3, -.formset-item.delete-checked .formset-nested-encloser, +.formset-item.delete-checked .formset-nested-container, .formset-nested-item.delete-checked .form-group:not(.formset-item-delete-host), .formset-nested-item.delete-checked h3{ display:none; @@ -314,7 +314,7 @@ Description: IPPI-DB Theme } .formset-item-inline-grid>.formset-item-delete-host, -.formset-item-inline-grid>.formset-nested-encloser{ +.formset-item-inline-grid>.formset-nested-container{ grid-column: 1/-1; } @@ -1313,7 +1313,8 @@ Description: IPPI-DB Theme @media (min-width: 980px) { .inline_box_complex_long{ - display: inline-flex; + padding-top:40px; + display: inline-flex; } } diff --git a/ippisite/ippidb/static/js/ippidb.js b/ippisite/ippidb/static/js/ippidb.js index e69ce55da2f03fbd225bf1e0c5947a67f6745c94..550151d001b3b65319ffc97a9f452d06b263a185 100644 --- a/ippisite/ippidb/static/js/ippidb.js +++ b/ippisite/ippidb/static/js/ippidb.js @@ -165,8 +165,8 @@ function change_test_selector() { } function add_form_to_formset(source, prefix){ - let input_total=$(source).closest(".formset-encloser").find("[name='"+prefix+"-TOTAL_FORMS']"); - let empty_form_as_str = $(source).closest(".formset-encloser").find(".empty_form").prop('innerHTML'); + let input_total=$(source).closest(".formset-container").find("[name='"+prefix+"-TOTAL_FORMS']"); + let empty_form_as_str = $(source).closest(".formset-container").find(".empty_form").prop('innerHTML'); empty_form_as_str = empty_form_as_str.replace( /__prefix__/g, input_total.val() @@ -178,14 +178,16 @@ function add_form_to_formset(source, prefix){ return empty_form; } -function formsetItemDelete(src){ - let fi = $(src).closest('.formset-nested-item'); - if(fi.length==0){ - fi = $(src).closest('.formset-item'); +function delete_button_clicked(source) { + let item = $(source).closest(".form-group"); + $(item).addClass("formset-item-delete-host"); + item = $(item).closest(".formset-nested-item"); + if (item.length==0){ + item = $(source).closest(".formset-item"); + } + if ($(source).prop("checked")){ + $(item).addClass("delete-checked"); + }else{ + $(item).removeClass("delete-checked"); } - fi.toggleClass('delete-checked'); - fi.find('input:not([type=\'checkbox\'])').prop('disabled', function(i, v) { return !v; }); - fi.find('textarea:not([type=\'checkbox\'])').prop('disabled', function(i, v) { return !v; }); - fi.find('select').prop('disabled', function(i, v) { return !v; }); - } \ No newline at end of file diff --git a/ippisite/ippidb/static/js/wizard_formset_with_nested_formset.js b/ippisite/ippidb/static/js/wizard_formset_with_nested_formset.js index 788a5d2db4e75761a8e6fa1cc0dc759c8dbbaa8a..a9f55282d81170fdc81d8b52b91b8ecb997da182 100644 --- a/ippisite/ippidb/static/js/wizard_formset_with_nested_formset.js +++ b/ippisite/ippidb/static/js/wizard_formset_with_nested_formset.js @@ -1,6 +1,6 @@ -function add_form_to_nested_formset_parent(source, prefix){ - let input_total=$(source).closest(".formset-encloser").find("[name='"+prefix+"-TOTAL_FORMS']"); - let empty_form_as_str = $(source).closest(".formset-encloser").find(".empty_form").prop('innerHTML'); +function add_form_to_nested_formset(source, prefix){ + let input_total=$(source).closest(".formset-container").find("[name='"+prefix+"-TOTAL_FORMS']"); + let empty_form_as_str = $(source).closest(".formset-container").find(".empty_form").prop('innerHTML'); empty_form_as_str = empty_form_as_str.replace( new RegExp(prefix+"-__prefix__","g"), prefix+"-"+input_total.val() @@ -8,21 +8,19 @@ function add_form_to_nested_formset_parent(source, prefix){ empty_form=$(empty_form_as_str ); empty_form.find(".formset-nested-item").first().remove(); empty_form.insertBefore($(source).parent()); - empty_form.find("select.test-selector").change(change_test_selector); input_total.val(parseInt(input_total.val())+1); return empty_form; } -function add_form_to_nested_formset(source, prefix, parent_prefix){ +function add_nested_form_to_nested_formset(source, prefix, parent_prefix){ let empty_form_as_str = $(source) - .closest(".formset-encloser") + .closest(".formset-container") .find(".empty_form") - .find(".formset-nested-encloser") .find(".formset-nested-item")[0] .outerHTML; - current_item_name = $(source).closest(".formset-item").children()[0].name; + current_item_name = $(source).closest(".formset-item").children("input")[0].name; current_item_name = current_item_name.substring(parent_prefix.length+1,current_item_name.indexOf('-',parent_prefix.length+1)); empty_form_as_str = empty_form_as_str.replace( new RegExp(parent_prefix+"-__prefix__","g"), @@ -30,7 +28,7 @@ function add_form_to_nested_formset(source, prefix, parent_prefix){ ); - let input_total=$(source).closest(".formset-nested-encloser").find("[name='"+prefix+"-TOTAL_FORMS']"); + let input_total=$(source).closest(".formset-item").find("[name='"+prefix+"-TOTAL_FORMS']"); empty_form_as_str = empty_form_as_str.replace( new RegExp(prefix+"-__prefix__","g"), prefix+"-"+input_total.val() @@ -38,7 +36,28 @@ function add_form_to_nested_formset(source, prefix, parent_prefix){ let empty_form=$(empty_form_as_str); empty_form.insertBefore($(source).parent()); - empty_form.find("select.test-selector").change(change_test_selector); input_total.val(parseInt(input_total.val())+1); return empty_form; -} \ No newline at end of file +} + +function delete_button_clicked(source) { + let item = $(source).closest(".form-group"); + $(item).addClass("formset-item-delete-host"); + item = $(item).closest(".formset-nested-item"); + if (item.length==0){ + item = $(source).closest(".formset-item"); + } + if ($(source).prop("checked")){ + $(item).find("select").prop("disabled",true); + $(item).find(":not(.formset-item-delete-host) input:visible").prop("disabled",true); + $(item).addClass("delete-checked"); + }else{ + $(item).removeClass("delete-checked"); + $(item).find("select").prop("disabled",false); + $(item).find("input").prop("disabled",false); + } +} + +window.onload = function() { + $(".formset-item-delete:checked").each(function(i,o){delete_button_clicked(o);}); +}; \ No newline at end of file diff --git a/ippisite/ippidb/templates/add.html b/ippisite/ippidb/templates/add.html index 7b208869453b52385de1957b51d31b5fd36e2961..f91ccdca066bf40cb811f8d00ead14a46d879121 100644 --- a/ippisite/ippidb/templates/add.html +++ b/ippisite/ippidb/templates/add.html @@ -8,7 +8,7 @@ {{block.super}} <script type="text/javascript"> window.onload = function() { - $(".formset-item-delete:checked").each(function(i,o){formsetItemDelete(o);}); + $(".formset-item-delete:checked").each(function(i,o){delete_button_clicked(o);}); }; </script> {% endblock extra_js %} @@ -69,7 +69,7 @@ window.onload = function() { </ul> </div> </nav> - <div id="Form" class="formset-encloser"> + <div id="Form" class="formset-container"> <div class="step_desc"> <h1 class="step_title"> {% with wizard.steps.current|add:"_title" as step_title %} diff --git a/ippisite/ippidb/templates/form_with_nested_formset.html b/ippisite/ippidb/templates/form_with_nested_formset.html index fba49496ce311a4b9ab61b9091c9237e2c1b42ce..3ec0b2cdaaf1eb3d8d324ebae2bea62bb8d2df52 100644 --- a/ippisite/ippidb/templates/form_with_nested_formset.html +++ b/ippisite/ippidb/templates/form_with_nested_formset.html @@ -2,7 +2,7 @@ {% load customtags %} <div class="formset-item formset-item-inline-grid"> {{form|bootstrap}} - <div class="formset-nested-encloser"> + <div class="formset-nested-container"> {{ form.nested.management_form }} {{ form.nested.non_form_errors|bootstrap }} {% if nested_form %} @@ -19,7 +19,7 @@ <input type="button" class="add-button" value="{%if add_another_nested_one %}{{add_another_nested_one}} {%else%}Add another one{%endif%}" - onclick="add_form_to_nested_formset(this,'{{form.nested.prefix}}','{{parent_prefix}}');"/> + onclick="add_nested_form_to_nested_formset(this,'{{form.nested.prefix}}','{{parent_prefix}}');"/> </div> </div> </div> \ No newline at end of file diff --git a/ippisite/ippidb/templates/wizard_formset_with_nested_formset.html b/ippisite/ippidb/templates/wizard_formset_with_nested_formset.html index 26f8ebb653c0e761469bba853e530d4646c3dd08..2a714959eea382571c3da0bf7d4833f495ef64ef 100644 --- a/ippisite/ippidb/templates/wizard_formset_with_nested_formset.html +++ b/ippisite/ippidb/templates/wizard_formset_with_nested_formset.html @@ -15,7 +15,7 @@ {{ wizard.non_form_errors }} {{ wizard.form.management_form }} - {{ wizard.form.non_field_errors}} + {{ wizard.form.non_field_errors|bootstrap}} {% for form in wizard.form.forms %} {% include "form_with_nested_formset.html" with form=form nested_forms=form.nested.forms nested_form=None add_another_nested_one="Add another result" parent_prefix=wizard.form.prefix %} @@ -24,7 +24,7 @@ <input type="button" class="add-button" value="{%block add_another_one %}Add another test{%endblock%}" - onclick="add_form_to_nested_formset_parent(this,'{{wizard.form.prefix}}');"/> + onclick="add_form_to_nested_formset(this,'{{wizard.form.prefix}}');"/> </div> </div> {% endblock %} diff --git a/ippisite/ippidb/templatetags/customtags.py b/ippisite/ippidb/templatetags/customtags.py index e6e524fa09ce8165d2b8c7a4277dda6524028356..138a79b784d2cc1dbf9fb46cacf310534ca84578 100644 --- a/ippisite/ippidb/templatetags/customtags.py +++ b/ippisite/ippidb/templatetags/customtags.py @@ -56,7 +56,7 @@ def bootstrap_core(object): css_classes.add("form-control") if field.name == "DELETE": # HACK : If the field is the DELETE button of the formset - attrs["onchange"] = "formsetItemDelete(this);" + attrs["onchange"] = "delete_button_clicked(this);" field.label = ugettext("DELETE_label") wrapping_classes += " formset-item-delete-host" css_classes.add("formset-item-delete")