def set_default_field_value(self, field_name, value):
        """
        updates the initial value of a form field,
        both on the form itself and on the ng model it is bound to
        :param field_name: name of field to update
        :param value: value to set
        :return: None
        """

        field = self.fields[field_name]
        field.initial = value

        # TODO: ANOTHER WAY TO GET INITIAL DATA FROM THE CUSTOMIZATION
        # TODO: IS TO ADD SOMETHING LIKE: "ng-init='{{form.get_initial_data|jsonify|safe}}'"
        # TODO: TO THE TEMPLATE (THE RESULT NEEDS TO BE MASSAGED A BIT TO USE QUALIFIED NAMES,
        # TODO: I'M NOT SURE WHICH APPROACH IS BETTER; FOR NOW I'M DOING IT EXPLICITLY HERE

        update_field_widget_attributes(
            field,
            {
                # notice I am calling the "init_value" fn, rather than just specifying "field_name=value" in ng-init
                # this bit of indirection ensures the property is loaded by the controller before setting its value
                # see comments in "q_ng_editor.js#init_value" for more info
                "ng-init": "init_value('{0}', {1})".format(field_name, json.dumps(value))
            },
        )
def bootstrap_field(field):
    bootstrap_classes = {
        "class": "form-control",
    }
    update_field_widget_attributes(field, bootstrap_classes)
    if not isinstance(field, BooleanField):
        set_field_widget_attributes(field, {
            "placeholder": field.label,
        })
Exemple #3
0
 def __init__(self, *args, **kwargs):
     super(QCategoryCustomizationForm, self).__init__(*args, **kwargs)
     if not self.instance.pk:
         # I don't need to reset the key b/c "get_new_customizations" passes it in via initial
         pass
     else:
         # TODO: DOUBLE-CHECK THAT I SHOULD SET ".initial[key]" and not ".fields[key].initial"
         # self.fields["key"].initial = self.instance.get_key()
         self.initial["key"] = self.instance.get_key()
     set_field_widget_attributes(self.fields["documentation"], {"rows": 2})
     update_field_widget_attributes(self.fields["order"], {"ng-disabled": "true"})
    def __init__(self, *args, **kwargs):

        super(QUserProfileForm, self).__init__(*args, **kwargs)

        profile = self.instance
        user = profile.user

        self.fields["first_name"].initial = user.first_name
        self.fields["last_name"].initial = user.last_name
        self.fields["email"].initial = user.email

        update_field_widget_attributes(self.fields["email"], {"readonly": True})
        set_field_widget_attributes(self.fields["description"], {"rows": 2})
        update_field_widget_attributes(self.fields["institute"], {"class": "select single show-tick"})
Exemple #5
0
    def __init__(self, *args, **kwargs):
        super(QModelCustomizationForm, self).__init__(*args, **kwargs)

        # deal w/ customization_fields...
        self.unbootstrap_field("is_default")
        set_field_widget_attributes(self.fields["description"], {"rows": 2})

        # deal w/ document_fields...
        self.unbootstrap_field("model_show_all_categories")
        set_field_widget_attributes(self.fields["model_description"], {"rows": 2})

        # TODO: MAKE SURE THIS LINE IS NOT REPLICATED IN SUBFORMS
        update_field_widget_attributes(self.fields["name"], {
            # notice I'm using ng-blur instead of ng-change
            # ...this is much more efficient
            "ng-blur": "update_names({field_scope})".format(
                field_scope=self.get_qualified_model_field_name("name"),
            ),
        })
    def __init__(self, *args, **kwargs):
        super(QModelCustomizationForm, self).__init__(*args, **kwargs)

        # deal w/ customization_fields...
        self.unbootstrap_field("is_default")
        self.add_server_errors_to_field("name")
        self.add_server_errors_to_field("is_default")
        set_field_widget_attributes(self.fields["documentation"], {"rows": 2})

        # deal w/ document_fields...
        self.unbootstrap_field("model_show_empty_categories")
        set_field_widget_attributes(self.fields["model_description"], {"rows": 2})

        update_field_widget_attributes(self.fields["name"], {
            # notice I'm using ng-blur instead of ng-change
            # ...this is much more efficient
            "ng-blur": "update_names({field_scope})".format(
                field_scope=self.get_qualified_model_field_name("name"),
            ),
        })
 def __init__(self, *args, **kwargs):
     super(QCategoryCustomizationForm, self).__init__(*args, **kwargs)
     self.unbootstrap_field("is_hidden")
     update_field_widget_attributes(self.fields["category_title"], {"class": "form-control form-control-small"})
     update_field_widget_attributes(self.fields["category_description"], {"class": "form-control form-control-small"})
     set_field_widget_attributes(self.fields["category_description"], {"rows": 2})
     update_field_widget_attributes(self.fields["order"], {"ng-disabled": "true", "disabled": "disabled"})
    def __init__(self, *args, **kwargs):

        # customizers was passed in via curry() in the factory function below
        customizers = kwargs.pop("customizers", None)

        # RIGHT, THIS CAUSED AN AWFUL LOT OF CONFUSION
        # THE CALL TO super() CAN TAKE A "customizer" ARGUMENT
        # BUT I CAN ONLY FIND THAT CUSTOMIZER BY MATCHING IT AGAINST THE VALUE OF "proxy"
        # THAT REQUIRES CALLING get_current_field_value() WHICH CHECKS THE PREFIX OF A FORM
        # BUT THAT PREFIX - AND SOME OTHER THINGS TOO - IS ONLY SET FROM DEEP W/IN THE __init__ FN
        # OF A BASE CLASS; SO I CALL super FIRST W/OUT A "customizer" ARGUMENT AND THEN CUSTOMIZE
        # AT THE END OF THIS __init__ FN

        super(MetadataScientificPropertyForm, self).__init__(*args, **kwargs)

        if customizers:
            proxy_pk = int(self.get_current_field_value("proxy"))
            customizer = find_in_sequence(lambda c: c.proxy.pk == proxy_pk, customizers)
            assert(customizer.name == self.get_current_field_value("name"))  # this is new code; just make sure it works
        else:
            customizer = None

        is_enumeration = self.get_current_field_value("is_enumeration", False)

        if self.instance.pk and is_enumeration:
            # ordinarily, this is done in create_scientific_property_form_data above
            # but if this is an existing model, I still need to do this jiggery-pokery someplace
            current_enumeration_value = self.get_current_field_value("enumeration_value")
            if isinstance(current_enumeration_value, basestring) and customizer.enumeration_multi:
                self.initial["enumeration_value"] = current_enumeration_value.split("|")

        if not is_enumeration:
            update_field_widget_attributes(self.fields["atomic_value"], {"onchange": "copy_value(this,'%s-scientific_property_value');" % self.prefix})
            update_field_widget_attributes(self.fields["atomic_value"], {"class": "atomic_value changer"})
        else:
            # this is handled via the "multiselect" widget in JS rather than here (b/c the widget is created dynamically via JS and has no _standard_ onchange event)
            # update_field_widget_attributes(self.fields["enumeration_value"], {"onchange": "copy_value(this,'%s-scientific_property_value');" % self.prefix})
            update_field_widget_attributes(self.fields["enumeration_value"], {"class": "multiselect"})

        if customizer:
            # HUH, WHY AM I CALLING THIS EXPLICITLY HERE, WHEN IT OUGHT TO BE CALLED AUTOMATICALLY IN super() ABOVE?
            # B/C customizer IS NOT PASSED TO super() B/C IT NEEDS TO BE FOUND BASED ON THE CURRENT PROXY
            # WHICH GETS RETURNED BY get_current_field_value()
            # WHICH HAS TO HAVE THIS FORM MOSTLY SET UP BEFORE IT WILL WORK
            # WHICH HAPPENS IN THE CALL TO super()
            # (SEE ABOVE)
            self.customize(customizer)
    def __init__(self, *args, **kwargs):
        super(QScientificPropertyCustomizationForm, self).__init__(*args, **kwargs)

        is_new_property = not self.instance.pk
        proxy = self.get_proxy()
        field_type = self.get_field_type()

        if field_type == QPropertyTypes.ATOMIC:
            # things to do for ATOMIC fields...
            # TODO: THIS IS NO LONGER TRUE; "atomic_type" IS NOW A REQUIRED FIELD W/ A DEFAULT VALUE
            # # since atomic_fields only shows up if this is an ATOMIC field, it cannot be required
            # # but when I do display it, I can force users to make a choice
            # atomic_type_field = self.fields["atomic_type"]
            # atomic_type_field.required = True
            # atomic_type_field.empty_label = None
            # atomic_type_field.choices.remove(EMPTY_CHOICE[0])
            set_field_widget_attributes(self.fields["atomic_suggestions"], {"rows": 2})
            update_field_widget_attributes(self.fields["atomic_type"], {"class": "select single show-tick"})

        elif field_type == QPropertyTypes.ENUMERATION:
            # things to do for ENUMERATION fields...
            self.unbootstrap_fields(["enumeration_open", "enumeration_multi", "enumeration_nullable", ])
            choices = proxy.enumeration_choices.split('|')
            enumeration_choices_field = self.fields["enumeration_choices"]
            enumeration_default_field = self.fields["enumeration_default"]
            enumeration_choices_field.set_choices(choices)
            enumeration_default_field.set_choices(choices)
            update_field_widget_attributes(enumeration_choices_field, {"class": "select multiple show-tick"})
            update_field_widget_attributes(enumeration_default_field, {"class": "select multiple show-tick"})
            if is_new_property:
                self.initial["enumeration_choices"] = choices

        else:  # field_type == QPropertyTypes.RELATIONSHIP
            msg = "ScientificProperties cannot be RELATIONSHIPS"
            raise QError(msg)

        # things to do for ALL fields...

        # TODO: DOUBLE-CHECK THAT I SHOULD SET ".initial[key]" and not ".fields[key].initial"
        self.initial["key"] = self.instance.get_key()
        self.initial["category_key"] = self.instance.category.get_key()

        self.unbootstrap_fields(self._extra_fields + ["displayed", "required", "editable", "unique", "inline_help", ])
        set_field_widget_attributes(self.fields["documentation"], {"rows": 2})
    def __init__(self, *args, **kwargs):
        super(QStandardPropertyCustomizationForm, self).__init__(*args, **kwargs)

        is_new_property = not self.instance.pk
        proxy = self.get_proxy()
        field_type = self.get_field_type()

        if field_type == QPropertyTypes.ATOMIC:
            # things to do for ATOMIC fields...
            # TODO: THIS IS NO LONGER TRUE; "atomic_type" IS NOW A REQUIRED FIELD W/ A DEFAULT VALUE
            # # since atomic_fields only shows up if this is an ATOMIC field, it cannot be required
            # # but when I do display it, I can force users to make a choice
            # atomic_type_field = self.fields["atomic_type"]
            # atomic_type_field.required = True
            # atomic_type_field.empty_label = None
            # atomic_type_field.choices.remove(EMPTY_CHOICE[0])
            set_field_widget_attributes(self.fields["atomic_suggestions"], {"rows": 2})
            update_field_widget_attributes(self.fields["atomic_type"], {"class": "select single show-tick"})

        elif field_type == QPropertyTypes.ENUMERATION:
            # things to do for ENUMERATION fields...
            self.unbootstrap_fields(["enumeration_open", "enumeration_multi", "enumeration_nullable", ])
            choices = proxy.enumeration_choices.split('|')
            enumeration_choices_field = self.fields["enumeration_choices"]
            enumeration_default_field = self.fields["enumeration_default"]
            enumeration_choices_field.set_choices(choices)
            enumeration_default_field.set_choices(choices)
            update_field_widget_attributes(enumeration_choices_field, {"class": "select multiple show-tick"})
            update_field_widget_attributes(enumeration_default_field, {"class": "select multiple show-tick"})
            if is_new_property:
                self.initial["enumeration_choices"] = choices

        else:  # field_type == QPropertyTypes.RELATIONSHIP
            # things to do for RELATIONSHIP fields...
            self.unbootstrap_fields(["relationship_show_subform"])
            update_field_widget_attributes(self.fields["relationship_show_subform"], {
                "ng-disabled": "true",
                "readonly": "readonly",
            })
            update_field_widget_attributes(self.fields["cardinality"], {
                "class": "cardinality",
            })

        # things to do for ALL fields...

        # TODO: DOUBLE-CHECK THAT I SHOULD SET ".initial[key]" and not ".fields[key].initial"
        self.initial["key"] = self.instance.get_key()
        try:
            self.initial["category_key"] = self.instance.category.get_key()
        except AttributeError:
            # sometimes properties in subforms don't have categories
            # ...that's okay
            pass

        if proxy.is_required():
            # if a property is required by the CIM
            # (then property.reset() will have set the "required" field to True)
            # then don't allow users to change the "required" or "displayed" fields
            update_field_widget_attributes(self.fields["required"], {
                "ng-disabled": "true",
                "readonly": "readonly",
            })
            update_field_widget_attributes(self.fields["displayed"], {
                "ng-disabled": "true",
                "readonly": "readonly",
            })

        self.unbootstrap_fields(["displayed", "required", "editable", "unique", "inline_help", "inherited", ])
        set_field_widget_attributes(self.fields["documentation"], {"rows": 2})
    def customize(self, customization):

        field_type = self.get_current_field_value("field_type")
        proxy = self.instance.proxy
        assert customization.proxy == proxy, "in QPropertyRealizationForm, customization.proxy doesn't equal instance.proxy"

        # customize form...
        self.inline_help = customization.inline_help
        self.is_nillable = customization.is_nillable
        self.is_required = customization.is_required
        self.is_hidden = customization.is_hidden
        self.is_editable = customization.is_editable
        self.is_hierarchical = customization.relationship_is_hierarchical
        self.render = not (self.is_hidden or self.is_hierarchical)  # tells the template whether or not I plan on rendering the form

        # customize fields...
        self.value_field.help_text = customization.property_description
        self.value_field.label = customization.property_title
        self.value_field.required = customization.is_required
        self.value_field.editable = customization.is_editable

        if not customization.is_editable:
            set_field_widget_attributes(self.value_field, {
                "ng-disabled": "true",
                "readonly": "readonly",
            })
            set_field_widget_attributes(self.fields["is_nil"], {
                "ng-disabled": "true",
                "readonly": "readonly",
            })
            set_field_widget_attributes(self.fields["nil_reason"], {
                "ng-disabled": "true",
                "readonly": "readonly",
            })

        # more in-depth customization...

        if field_type == QPropertyTypes.ATOMIC:
            atomic_value_field = self.fields["atomic_value"]
            existing_widget_attrs = atomic_value_field.widget.attrs
            custom_widget_class, custom_widget_args = ATOMIC_PROPERTY_MAP[customization.atomic_type]
            atomic_value_field.widget = custom_widget_class(custom_widget_args)
            update_field_widget_attributes(atomic_value_field, existing_widget_attrs)
            if self.instance.is_new:
                default_values = customization.default_values
                if default_values:
                    # TODO: WILL NEED TO REWRITE THIS TO COPE W/ "cardinality_max" > 1 FOR ATOMIC FIELDS
                    # TODO: (IN THAT CASE, I SHOULD PROBABLY MAKE "atomic_value" A QJSONField
                    assert len(default_values) == 1, "need to rewrite this to cope w/ 'cardinality_max' > 1 for atomic fields"
                    self.set_default_field_value("atomic_value", default_values[0])
                    self.set_default_field_value("is_complete", True)
                if customization.is_required:
                    update_field_widget_attributes(atomic_value_field, {
                        "ng-blur": "update_property_completion()",
                    })
                else:
                    self.set_default_field_value("is_complete", True)

            if customization.atomic_suggestions:
                atomic_suggestions_list = customization.atomic_suggestions.split('|')
                set_field_widget_attributes(atomic_value_field, {
                    "uib-typeahead": "option for option in [{0}] | filter:$viewValue | limitTo:{1}".format(
                        ",".join(["'{0}'".format(mark_safe(suggestion)) for suggestion in atomic_suggestions_list]),
                        TYPEAHEAD_LIMIT
                    )
                })

        elif field_type == QPropertyTypes.ENUMERATION:
            enumeration_value_field = self.fields["enumeration_value"]
            enumeration_other_value_field = self.fields["enumeration_other_value"]
            enumeration_choices = copy.copy(proxy.enumeration_choices)  # (make a copy of the value so that possibly updating it below doesn't modify the original
            if customization.enumeration_is_open:
                enumeration_choices.append({
                    "value": ENUMERATION_OTHER_CHOICE,
                    "documentation": ENUMERATION_OTHER_DOCUMENTATION,
                    "order": len(enumeration_choices) + 1,
                })
            enumeration_value_field._complete_choices = enumeration_choices

            if customization.is_required:
                update_field_widget_attributes(enumeration_value_field, {
                    "ng-blur": "update_property_completion()",
                })
                update_field_widget_attributes(enumeration_other_value_field, {
                    "ng-blur": "update_property_completion()",
                })
            else:
                self.set_default_field_value("is_complete", True)
                update_field_widget_attributes(enumeration_other_value_field, {
                    "ng-blur": "update_property_completion()",
                })

        else:  # field_type == QPropertyTypes.RELATIONSHIP
            if not customization.relationship_is_hierarchical:
                # only have to render non-hierarchical relationships in a property form...
                self.use_subforms = customization.use_subforms
                self.use_references = customization.use_references
                self.cardinality_min = customization.cardinality_min
                self.cardinality_max = customization.cardinality_max
            if not customization.is_required:
                self.set_default_field_value("is_complete", True)

        self.customization = customization
    def __init__(self, *args, **kwargs):
        super(QPropertyCustomizationForm, self).__init__(*args, **kwargs)

        set_field_widget_attributes(self.fields["property_description"], {"rows": 2})
        set_field_widget_attributes(self.fields["cardinality"], {"readonly": True, "ng-disabled": "true"})
        update_field_widget_attributes(self.fields["cardinality"], {"class": "form-control-auto"})
        self.unbootstrap_fields(["inline_help", "is_required", "is_hidden", "is_editable", "is_nillable"])

        field_type = self.get_current_field_value("field_type")
        if field_type == QPropertyTypes.ATOMIC:
            update_field_widget_attributes(self.fields["atomic_type"], {"class": "select single show-tick"})
            set_field_widget_attributes(self.fields["atomic_suggestions"], {"rows": 2})
            set_field_widget_attributes(self.fields["default_values"], {"rows": 2})
        elif field_type == QPropertyTypes.ENUMERATION:
            set_field_widget_attributes(self.fields["default_values"], {"rows": 2})
            self.unbootstrap_fields(["enumeration_is_open"])
        elif field_type == QPropertyTypes.RELATIONSHIP:
            update_field_widget_attributes(self.fields["relationship_show_subforms"], {"readonly": True, "ng-disabled": "true"})
            update_field_widget_attributes(self.fields["relationship_is_hierarchical"], {"readonly": True, "ng-disabled": "true"})
            self.unbootstrap_fields(["relationship_show_subforms", "relationship_is_hierarchical"])
        else:
            msg = "Unknown field type: {0}".format(field_type)
            raise QError(msg)

        if self.instance.proxy.is_required:
            update_field_widget_attributes(self.fields["is_required"], {"readonly": True, "ng-disabled": "true"})

        if self.instance.has_specialized_values:
            update_field_widget_attributes(self.fields["default_values"], {"readonly": True, "ng-disabled": "true"})
            update_field_widget_attributes(self.fields["is_editable"], {"readonly": True, "ng-disabled": "true"})
 def __init__(self, *args, **kwargs):
     super(QProjectForm, self).__init__(*args, **kwargs)
     for field in self.fields.itervalues():
         update_field_widget_attributes(field, {"class": "form-control form-control-md"})
     set_field_widget_attributes(self.fields["name"], {"readonly": True, "ng-disabled": "true"})
     set_field_widget_attributes(self.fields["description"], {"rows": 2})
 def __init__(self, *args, **kwargs):
     super(QOntologyAdminForm,self).__init__(*args, **kwargs)
     current_model_proxies = self.instance.model_proxies.all()
     self.fields["model_proxies"].queryset = current_model_proxies
     self.fields["model_proxies"].initial = current_model_proxies
     update_field_widget_attributes(self.fields["model_proxies"], {"disabled": "disabled"})
 def __init__(self, *args, **kwargs):
     super(QVocabularyAdminForm, self).__init__(*args, **kwargs)
     current_component_proxies = self.instance.component_proxies.all()
     self.fields["component_proxies"].queryset = current_component_proxies
     self.fields["component_proxies"].initial = current_component_proxies
     update_field_widget_attributes(self.fields["component_proxies"], {"disabled": "disabled"})
Exemple #16
0
    def __init__(self, *args, **kwargs):
        super(QPropertyCustomizationForm, self).__init__(*args, **kwargs)

        proxy = self.get_proxy()
        field_type = self.get_field_type()

        if field_type == QPropertyTypes.ATOMIC:
            # things to do for ATOMIC fields...
            # TODO: THIS IS NO LONGER TRUE; "atomic_type" IS NOW A REQUIRED FIELD W/ A DEFAULT VALUE
            # # since atomic_fields only shows up if this is an ATOMIC field, it cannot be required
            # # but when I do display it, I can force users to make a choice
            # atomic_type_field = self.fields["atomic_type"]
            # atomic_type_field.required = True
            # atomic_type_field.empty_label = None
            # atomic_type_field.choices.remove(EMPTY_CHOICE[0])
            set_field_widget_attributes(self.fields["atomic_suggestions"], {"rows": 2})
            update_field_widget_attributes(self.fields["atomic_type"], {"class": "select single show-tick"})

        elif field_type == QPropertyTypes.ENUMERATION:
            # things to do for ENUMERATION fields...
            self.unbootstrap_fields(["enumeration_open", ])
            # choices = proxy.enumeration_choices.split('|')
            # enumeration_choices_field = self.fields["enumeration_choices"]
            # enumeration_default_field = self.fields["enumeration_default"]
            # enumeration_choices_field.set_choices(choices)
            # enumeration_default_field.set_choices(choices)
            # update_field_widget_attributes(enumeration_choices_field, {"class": "select multiple show-tick"})
            # update_field_widget_attributes(enumeration_default_field, {"class": "select multiple show-tick"})
            # if is_new_property:
            #     self.initial["enumeration_choices"] = choices

        else:  # field_type == QPropertyTypes.RELATIONSHIP
            # things to do for RELATIONSHIP fields...
            self.unbootstrap_fields(["relationship_show_subform"])
            update_field_widget_attributes(self.fields["relationship_show_subform"], {
                "ng-disabled": "true",
                "readonly": "readonly",
            })
            self.fields["subform_targets"].choices = [
                (relationship_subform_customization.get_key(), str(relationship_subform_customization.proxy))
                for relationship_subform_customization in self.instance.relationship_target_model_customizations(manager="allow_unsaved_relationship_target_model_customizations_manager").all()
            ]
            update_field_widget_attributes(self.fields["subform_targets"], {"class": "select single show-tick"})

        # things to do for ALL fields...

        # TODO: DOUBLE-CHECK THAT I SHOULD SET ".initial[key]" and not ".fields[key].initial"
        self.initial["key"] = self.instance.get_key()
        self.initial["category_key"] = self.instance.category.get_key()

        if proxy.is_required():
            # if a property is required by the CIM
            # (then property.reset() will have set the "required" field to True)
            # then don't allow users to change the "is_required" or "is_hidden" fields
            update_field_widget_attributes(self.fields["is_required"], {
                "ng-disabled": "true",
                "readonly": "readonly",
            })
            update_field_widget_attributes(self.fields["is_hidden"], {
                "ng-disabled": "true",
                "readonly": "readonly",
            })

        self.unbootstrap_fields(["is_hidden", "is_required", "is_editable", "is_nillable", "inline_help", ])
        set_field_widget_attributes(self.fields["documentation"], {"rows": 2})
    def customize(self, customizer):

        # customization is done in the form and in the template

        value_field_name = self.get_value_field_name()

        self.fields[value_field_name].help_text = customizer.documentation

        # you can customize the category of scientific properties,
        # so set it here...
        category_customizer = customizer.category
        self.initial["category_key"] = category_customizer.get_key()

        if customizer.field_type != "ENUMERATION":
            atomic_type = customizer.atomic_type
            if atomic_type:
                if atomic_type != MetadataAtomicFieldTypes.DEFAULT:
                    custom_widget_class = METADATA_ATOMICFIELD_MAP[atomic_type][0]
                    custom_widget_args = METADATA_ATOMICFIELD_MAP[atomic_type][1]
                    self.fields["atomic_value"].widget = custom_widget_class(**custom_widget_args)
                    # if I changed the widget, then I have to re-add the attributes that were updated in __init__ above
                    # b/c they will have been lost (I only have to do this for atomic fields b/c the widget for enumerations cannot change)
                    update_field_widget_attributes(self.fields["atomic_value"], {"onchange": "copy_value(this,'%s-scientific_property_value');" % self.prefix})
                    update_field_widget_attributes(self.fields["atomic_value"], {"class": "atomic_value changer"})

                update_field_widget_attributes(self.fields["atomic_value"], {"class": atomic_type.lower()})

        else:
            widget_attributes = {"class": "multiselect", }
            all_enumeration_choices = [(choice, choice) for choice in customizer.enumeration_choices]
            if customizer.enumeration_nullable:
                all_enumeration_choices += NULL_CHOICE
                widget_attributes["class"] += " nullable"
            if customizer.enumeration_open:
                all_enumeration_choices += OTHER_CHOICE
                widget_attributes["class"] += " open"
            if customizer.enumeration_multi:
                widget_attributes["class"] += " multiple"
                self.fields["enumeration_value"].set_choices(all_enumeration_choices, multi=True)
            else:
                widget_attributes["class"] += " single"
                # all_enumeration_choices = EMPTY_CHOICE + all_enumeration_choices
                self.fields["enumeration_value"].set_choices(all_enumeration_choices, multi=False)

            update_field_widget_attributes(self.fields["enumeration_value"], widget_attributes)
            update_field_widget_attributes(self.fields["enumeration_other_value"], {"class": "other"})

        # extra_attributes...
        if not customizer.edit_extra_standard_name:
            update_field_widget_attributes(self.fields["extra_standard_name"], {"class": "readonly", "readonly": "readonly"})

        if not customizer.edit_extra_description:
            update_field_widget_attributes(self.fields["extra_description"], {"class": "readonly", "readonly": "readonly"})

        if not customizer.edit_extra_units:
            update_field_widget_attributes(self.fields["extra_units"], {"class": "readonly", "readonly": "readonly"})

        set_field_widget_attributes(self.fields["extra_description"], {"cols": "60", "rows": "4"})

        self.customizer = customizer