From 8355b16b1ae2f213de8d9f98221227f587e3b29f Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 27 Nov 2020 11:26:55 +0100 Subject: Documents: dynamic filter of support and medium by document type - collapse related fields on edition --- ishtar_common/forms.py | 116 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 110 insertions(+), 6 deletions(-) (limited to 'ishtar_common/forms.py') diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py index 6193c72c4..f1e5b34ca 100644 --- a/ishtar_common/forms.py +++ b/ishtar_common/forms.py @@ -622,6 +622,7 @@ class FormHeader(object): class IshtarForm(forms.Form, BSForm): TYPES = [] # FieldType list CONDITIONAL_FIELDS = [] # dynamic conditions on field display + # can be dynamic with "get_conditional_fields" PROFILE_FILTER = {} # profile key associated to field list HEADERS = {} # field key associated to FormHeader instance # permission check for widget options, ex: forms_common.DocumentForm @@ -668,14 +669,19 @@ class IshtarForm(forms.Form, BSForm): self.fields[field.key].choices = field.get_choices() self.fields[field.key].help_text = field.get_help() + def get_headers(self): + return self.HEADERS + def headers(self, key): - if key not in self.HEADERS: + headers = self.get_headers() + if key not in headers: return - self.current_header = self.HEADERS[key] + self.current_header = headers[key] return self.current_header def extra_render(self): - return self.get_conditional() + return (self.get_conditional() or "") + ( + self.get_conditional_filters() or "") HIDE_JS_TEMPLATE = """ var %(id)s_item_show_list = ['%(item_list)s']; @@ -688,7 +694,6 @@ class IshtarForm(forms.Form, BSForm): var %(id)s_item_show_list = ['%(item_list)s']; var %(id)s_hide_display = function(){ var current_val = $("#id_%(name)s").val(); - console.log("#id_%(name)s"); if (%(id)s_check_list.indexOf(current_val) != -1){ for (idx in %(id)s_item_show_list){ $("#main_div-id_" + %(id)s_item_show_list[idx]).removeClass("d-none"); @@ -707,12 +712,15 @@ class IshtarForm(forms.Form, BSForm): """ def get_conditional(self): - if not self.CONDITIONAL_FIELDS or not self.TYPES: + conditional_fields = self.CONDITIONAL_FIELDS + if hasattr(self, 'get_conditional_fields'): + conditional_fields = self.get_conditional_fields() + if not conditional_fields or not self.TYPES: return type_dict = dict([(typ.key, typ.model) for typ in self.TYPES]) html = "" - for condition, target_names in self.CONDITIONAL_FIELDS: + for condition, target_names in conditional_fields: condition_field, condition_attr, condition_val = condition if condition_field not in type_dict: continue @@ -740,6 +748,102 @@ class IshtarForm(forms.Form, BSForm): html = "" return html + CONDITIONAL_FILTER_JS_TEMPLATE = """ + %(filter_list)s; + var %(id)s_prefix = "%(prefix)s"; + var %(id)s_filter_display = function(){ + var current_val = $("#id_%(name)s").val(); + if (current_val in %(id)s_filter_list){ + for (var k in %(id)s_filter_list[current_val]){ + var cname = k; + if (%(id)s_prefix) cname = %(id)s_prefix + cname; + update_select_widget( + cname, + %(id)s_all_value_list[k], + %(id)s_filter_list[current_val][k]); + } + } else { + for (var k in %(id)s_exclude_list){ + var cname = k; + if (%(id)s_prefix) cname = %(id)s_prefix + cname; + update_select_widget( + cname, + %(id)s_all_value_list[k], + null, + %(id)s_exclude_list[k]); + } + } + }; + + $("#id_%(name)s").change(%(id)s_filter_display); + setTimeout(function(){ + %(id)s_filter_display(); + }, 500); + """ + + def get_conditional_filters(self): + if not hasattr(self, 'get_conditional_filter_fields'): + return + conditional_fields, excluded_fields, all_values = \ + self.get_conditional_filter_fields() + + types = [typ.key for typ in self.TYPES] + html = "" + + outputs = set() + for input_key in conditional_fields: + if input_key not in types: + continue + name = input_key + if self.prefix: + name = self.prefix + "-" + input_key + cidx = name.replace("-", "_") + filter_list = "var %s_filter_list = {\n" % cidx + for idx, input_pk in enumerate(conditional_fields[input_key]): + if idx: + filter_list += ",\n" + filter_list += ' "%s": {\n' % input_pk + for idx2, output in enumerate( + conditional_fields[input_key][input_pk]): + if idx2: + filter_list += ",\n" + if output[0] in excluded_fields: + outputs.add(output[0]) + filter_list += ' "{}": [{}]'.format(*output) + filter_list += " }" + filter_list += "};\n" + + html += self.CONDITIONAL_FILTER_JS_TEMPLATE % { + "id": cidx, + "name": name, + "filter_list": filter_list, + "prefix": self.prefix or "" + } + html += "var %s_other_widget_list = [" % cidx + for idx, k in enumerate(all_values): + if idx: + html += ", " + html += '"' + k + '"' + html += "];\n" + + html += "var %s_exclude_list = {\n" % cidx + for idx, output in enumerate(outputs): + if idx: + html += ",\n" + html += ' "%s": [%s]' % (output, excluded_fields[output]) + html += "\n};\n" + + html += "var %s_all_value_list = {\n" % cidx + for idx, k in enumerate(all_values): + if idx: + html += ",\n" + html += ' "%s": %s' % (k, all_values[k]) + html += "\n};\n" + + if html: + html = "" + return html + class TableSelect(IshtarForm): def __init__(self, *args, **kwargs): -- cgit v1.2.3