Пример #1
0
 def management_form(self):
     # the management form is required for Django formsets
     return hg.BaseElement(
         # management forms, for housekeeping of inline forms
         hg.F(lambda c: Form(
             c[self.formname][self.fieldname].formset.management_form,
             *[
                 FormField(
                     f, no_wrapper=True, no_label=True, no_helptext=True)
                 for f in c[self.formname][self.fieldname].formset.
                 management_form.fields
             ],
             standalone=False,
         )),
         # Empty form as template for new entries. The script tag works very well
         # for this since we need a single, raw, unescaped HTML string
         hg.SCRIPT(
             Form(
                 hg.C(f"{self.formname}.{self.fieldname}.formset.empty_form"
                      ),
                 hg.WithContext(
                     self.content,
                     **{
                         DEFAULT_FORMSET_CONTEXTNAME:
                         hg.
                         C(f"{self.formname}.{self.fieldname}.formset.empty_form"
                           )
                     },
                 ),
                 standalone=False,
             ),
             id=hg.BaseElement(
                 "empty_",
                 hg.C(f"{self.formname}.{self.fieldname}.formset.prefix"),
                 "_form",
             ),
             type="text/plain",
         ),
         hg.SCRIPT(
             mark_safe(
                 "document.addEventListener('DOMContentLoaded', e => init_formset('"
             ),
             hg.C(f"{self.formname}.{self.fieldname}.formset.prefix"),
             mark_safe("'));"),
         ),
         hg.SPAN(onload=hg.BaseElement(
             mark_safe("init_formset('"),
             hg.C(f"{self.formname}.{self.fieldname}.formset.prefix"),
             mark_safe("');"),
         ), ),
     )
Пример #2
0
    def __init__(
        self,
        label=None,
        help_text=None,
        errors=None,
        inputelement_attrs=None,
        boundfield=None,
        backend=None,
        **attributes,
    ):
        """
        :param SearchBackendConfig backend: Where and how to get search results
        """
        inputelement_attrs = inputelement_attrs or {}

        # This works inside a formset. Might need to be changed for other usages.

        widget_id = inputelement_attrs.get("id")
        resultcontainerid = hg.format("search-result-{}", widget_id)
        tag_id = hg.format("{}-tag", widget_id)
        super().__init__(
            label,
            Tag(
                hg.F(lambda c: hg.resolve_lazy(boundfield, c).field.to_python(
                    hg.resolve_lazy(boundfield, c).value()))
                if boundfield else "",
                id=tag_id,
                style=hg.If(
                    inputelement_attrs.get("value"),
                    hg.BaseElement(""),
                    hg.BaseElement("display: none;"),
                ),
                onclick="return false;",
            ),
            self.get_input_element(inputelement_attrs, errors, type="hidden"),
            Search(
                backend=backend,
                resultcontainerid=resultcontainerid,
                resultcontainer_onload_js=_resultcontainer_onload_js(
                    backend, resultcontainerid, tag_id, widget_id),
                size="lg",
                disabled=inputelement_attrs.get("disabled", False),
                widgetattributes={"id": hg.format("search__{}", widget_id)},
            ),
            help_text,
            errors,
            **hg.merge_html_attrs(attributes,
                                  {"_class": "bx--text-input-wrapper"}),
        )
Пример #3
0
def variable_size_header_part(platform, company, searchbar, searchbar_position):
    return hg.BaseElement(
        hg.A(
            logo(),
            platform,
            _class="bx--header__name",
            style="font-weight: 400",  # override carbon design
            href=hg.F(lambda c: c["request"].META["SCRIPT_NAME"] or "/"),
        ),
        hg.If(
            searchbar,
            hg.SPAN(
                searchbar,
                style=f"position: absolute; left: {searchbar_position}",
                _class="theme-gray-100",
            ),
            "",
        ),
        hg.A(
            hg.SPAN(
                company,
                style=hg.format(
                    "position: absolute; left: {}",
                    hg.If(searchbar, "50%", searchbar_position),
                ),
            ),
            _class="bx--header__name",
            style="font-weight: 400",  # override carbon design
            href=hg.F(lambda c: c["request"].META["SCRIPT_NAME"] or "/"),
        ),
    )
def personform_shortcut(request, formlayout):
    return hg.BaseElement(
        layout.grid.Grid(
            editperson_head(request),
            formlayout,
            gutter=False,
        ))
Пример #5
0
    def get_layout(self):
        if hasattr(self, "layout") and self.layout is not None:
            ret = self.layout
        else:
            formfields = filter_fieldlist(
                self.model,
                [f for f in self.fields if isinstance(f, str)] if self.fields else None,
                for_form=True,
            )
            ret = hg.BaseElement()
            for field in self.fields or formfields:
                if field in formfields:
                    ret.append(breadlayout.forms.FormField(field))
                else:
                    ret.append(field)

        if self.ajax_urlparameter in self.request.GET:
            return breadlayout.forms.Form(hg.C("form"), ret)

        # wrap with form will add a submit button
        return hg.DIV(
            header(),
            breadlayout.tile.Tile(
                breadlayout.forms.Form(
                    hg.C("form"), ret, breadlayout.forms.helpers.Submit()
                ),
                _class="theme-white",
            ),
        )
def generalsettings(request):

    if request.method == "POST":
        form = global_preference_form_builder(
            preferences=["general__organizationname"]
        )(request.POST, request.FILES)
        if form.is_valid():
            form.update_preferences()
    else:
        form = global_preference_form_builder(
            preferences=["general__organizationname"]
        )()

    return layout.grid.Grid(
        R(C(hg.H3(_("Settings")))),
        R(C(hg.H4(_("General")))),
        R(C(hg.H5(_("Information about our organization")))),
        R(
            C(
                layout.forms.Form(
                    form,
                    hg.BaseElement(F("general__organizationname")),
                    layout.forms.helpers.Submit(),
                    style="max-width: 480px",
                )
            )
        ),
        gutter=False,
    )
    def get_layout(self):
        if self.section_name:
            section_names = [self.section_name]
        else:
            section_names = self.form_class.registry.section_objects.keys()
        section_fields = {}
        for section in section_names:
            section_fields[section] = []
            for field in self.form_class.registry[section]:
                section_fields[section].append(f"{section}__{field}")

        return breadlayout.forms.Form(
            hg.C("form"),
            hg.H3(_("Global preferences")),
            Tabs(
                *[
                    Tab(
                        self.form_class.registry.section_objects[section].
                        verbose_name,
                        hg.BaseElement(*[
                            breadlayout.forms.FormField(f)
                            for f in section_fields.get(section)
                        ]),
                    ) for section in section_fields.keys()
                ],
                tabpanel_attributes={"style": "padding-left:0;"},
            ),
            breadlayout.forms.helpers.Submit(),
        )
Пример #8
0
 def get_layout(self):
     return hg.If(
         hg.C("validlink"),
         auth_page(
             layout.forms.Form(
                 hg.C("form"),
                 layout.forms.FormField(
                     "new_password1",
                     inputelement_attrs={"_class": "field-02-background"},
                     style="width: 100%",
                 ),
                 layout.forms.FormField(
                     "new_password2",
                     inputelement_attrs={"_class": "field-02-background"},
                 ),
                 id="authform",
             ),
             _("Change password"),
         ),
         auth_page(
             hg.BaseElement(
                 hg.FORM(id="authform", action=reverse("login")),
                 layout.notification.InlineNotification(
                     _("Invalid password reset link"),
                     _(
                         "The password reset link was invalid, possibly because it has already been used. Please request a new password reset."
                     ),
                     kind="error",
                     lowcontrast=True,
                     style="margin-bottom: 4rem",
                 ),
             ),
             _("Back to Login"),
         ),
     )
Пример #9
0
    def preview(self):
        columns = []
        for column in self.columns.all():
            columns.append(
                DataTableColumn(column.header,
                                layout.FC(f"row.{column.column}")))
        qs = self.queryset
        if qs is None:
            return hg.BaseElement("Model does no longer exists!")

        return hg.BaseElement(
            hg.HR(),
            hg.H3(_("Preview"), style="margin-top: 1rem"),
            layout.datatable.DataTable.from_queryset(qs[:25],
                                                     columns=columns,
                                                     primary_button=""),
        )
Пример #10
0
 def wrapper_func(context):
     _classlist = []
     for _class in _classes:
         _classlist.append(_class)
         _classlist.append(" ")
     ret = hg.resolve_lazy(lazy_attrs, context) or {}
     ret["_class"] = hg.BaseElement(ret.get("_class", ""), " ", *_classlist)
     return ret
Пример #11
0
def _generate_formset_class(
    request,
    model,
    modelfield,
    baseinlineformclass,
    formsetfieldelement,
    instance,
    cache_querysets,
):
    """Returns a FormSet class which handles inline forms correctly."""

    formfieldelements = _get_form_fields_from_layout(
        hg.BaseElement(*formsetfieldelement)
    )  # make sure the _layout.forms.FormsetField does not be considered recursively

    formclass = breadmodelform_factory(
        request=request,
        model=modelfield.related_model,
        layout=formfieldelements,
        instance=instance,
        baseformclass=baseinlineformclass,
        cache_querysets=cache_querysets,
    )

    base_formset_kwargs = {
        "fields": [field.fieldname for field in formfieldelements],
        "form": formclass,
        "extra": 0,
        "can_delete": True,
    }
    if modelfield.one_to_one:
        base_formset_kwargs["absolute_max"] = 1
        base_formset_kwargs["min_num"] = 0
        base_formset_kwargs["max_num"] = 1
        base_formset_kwargs["extra"] = 1

    base_formset_kwargs.update(formsetfieldelement.formsetfactory_kwargs)
    if isinstance(modelfield, GenericRelation):
        return generic_inlineformset_factory(
            modelfield.related_model,
            ct_field=modelfield.content_type_field_name,
            fk_field=modelfield.object_id_field_name,
            formset=GenericInlineFormSetWithLimits,
            formfield_callback=lambda field: _formfield_callback_with_request(
                field, request, modelfield.related_model, instance,
                cache_querysets),
            **base_formset_kwargs,
        )
    else:
        return forms.models.inlineformset_factory(
            model,
            modelfield.related_model,
            formset=InlineFormSetWithLimits,
            formfield_callback=lambda field: _formfield_callback_with_request(
                field, request, model, instance, cache_querysets),
            fk_name=modelfield.field.name,
            **base_formset_kwargs,
        )
Пример #12
0
    def __init__(
        self,
        size="xl",
        placeholder=None,
        widgetattributes=None,
        backend=None,
        resultcontainerid=None,
        show_result_container=True,
        resultcontainer_onload_js=None,
        disabled=False,
        **kwargs,
    ):
        """
        :param SearchBackendConfig backend: Where and how to get search results
        """
        kwargs["_class"] = kwargs.get("_class", "") + f" bx--search bx--search--{size}"
        kwargs["data_search"] = True
        kwargs["role"] = "search"
        width = kwargs.get("width", None)
        if width:
            kwargs["style"] = kwargs.get("style", "") + f"width:{width};"

        widgetattributes = {
            "id": "search__" + hg.html_id(self),
            "_class": "bx--search-input",
            "type": "text",
            "placeholder": placeholder or _("Search"),
            "autocomplete": "off",
            **(widgetattributes or {}),
        }
        if backend:
            if resultcontainerid is None:
                resultcontainerid = f"search-result-{hg.html_id((self, backend.url))}"
            widgetattributes["hx_get"] = backend.url
            widgetattributes["hx_trigger"] = "changed, click, keyup changed delay:500ms"
            widgetattributes["hx_target"] = hg.format("#{}", resultcontainerid)
            widgetattributes["hx_indicator"] = hg.format(
                "#{}-indicator", resultcontainerid
            )
            widgetattributes["name"] = backend.query_parameter

        self.close_button = _close_button(resultcontainerid, widgetattributes)

        super().__init__(
            hg.DIV(
                hg.LABEL(_("Search"), _class="bx--label", _for=widgetattributes["id"]),
                hg.INPUT(**widgetattributes),
                _search_icon(),
                self.close_button,
                hg.If(backend is not None, _loading_indicator(resultcontainerid)),
                **kwargs,
            ),
            hg.If(
                backend is not None and show_result_container,
                _result_container(resultcontainerid, resultcontainer_onload_js, width),
            ),
            style=hg.If(disabled, hg.BaseElement("display: none")),
        )
Пример #13
0
    def get_layout(self):
        modelclass = self.object.model.model_class()
        if modelclass is None:
            return layout.notification.InlineNotification(
                "Error",
                f"Model '{self.object.model}' does no longer exist.",
                kind="error",
            )
        column_helper = layout.get_attribute_description_modal(modelclass)

        F = layout.forms.FormField

        fieldstable = layout.forms.FormsetField.as_datatable(
            "columns",
            ["header", "column", "sortingname"],
            formsetfield_kwargs={
                "extra": 1,
                "can_order": True,
            },
        )
        fieldstable[0][1].insert(
            0,
            layout.button.Button(_("Help"),
                                 buttontype="ghost",
                                 **column_helper.openerattributes),
        )
        fieldstable.append(hg.DIV(style="height: 1rem"))
        ret = hg.BaseElement(
            views.header(),
            layout.forms.Form(
                hg.C("form"),
                hg.DIV(
                    _("Base model"),
                    ": ",
                    hg.C("object.model"),
                    style="margin: 2rem 0 2rem 0",
                ),
                F("name"),
                F(
                    "filter",
                    inputelement_attrs={"rows": 1},
                    style="width: 100%",
                ),
                fieldstable,
                layout.tile.ExpandableTile(
                    hg.H4(_("Extended settings")),
                    hg.DIV(
                        F("custom_queryset"),
                        F("pagination"),
                    ),
                ),
                layout.forms.helpers.Submit(style="margin-top: 1rem"),
                column_helper,
            ),
            hg.C("object.preview"),
        )
        return ret
Пример #14
0
def header():

    editbutton = breadlayout.button.Button(
        _("Edit"),
        buttontype="ghost",
        icon="edit",
        notext=True,
    ).as_href(ModelHref.from_object(hg.C("object"), "edit"))
    readbutton = breadlayout.button.Button(
        _("Read"),
        buttontype="ghost",
        icon="view",
        notext=True,
    ).as_href(ModelHref.from_object(hg.C("object"), "read"))

    deletebutton = breadlayout.button.Button(
        _("Delete"),
        buttontype="tertiary",
        icon="trash-can",
        notext=True,
        style="border-color: red; background-color: inherit",
    ).as_href(ModelHref.from_object(hg.C("object"), "delete"))
    deletebutton[1].attributes["style"] = "fill: red; color: red;"

    copybutton = breadlayout.button.Button(
        _("Copy"),
        buttontype="ghost",
        icon="copy",
        notext=True,
    ).as_href(ModelHref.from_object(hg.C("object"), "copy"))

    return hg.DIV(
        hg.H3(
            hg.If(
                hg.C("object"),
                hg.BaseElement(
                    hg.SPAN(hg.C("object")),
                    hg.SPAN(
                        hg.If(
                            hg.C("request").resolver_match.url_name.endswith(".read"),
                            editbutton,
                            readbutton,
                        ),
                        copybutton,
                        breadlayout.button.PrintPageButton(buttontype="ghost"),
                        deletebutton,
                        _class="no-print",
                        style="margin-bottom: 1rem; margin-left: 1rem",
                        width=3,
                    ),
                ),
                hg.SPAN(hg.format(_("Add {}"), hg.C("view").model._meta.verbose_name)),
            ),
        ),
        style="padding-top: 1rem",
    )
Пример #15
0
def tile_col_edit_modal_displayed_fields(heading, model: type, action: str,
                                         icon: Icon, displayed_fields: List):
    return tile_with_icon(
        icon,
        hg.BaseElement(
            hg.H4(heading),
            *displayed_fields,
            open_modal_popup_button(heading, model, action),
        ),
    )
Пример #16
0
 def get_layout(self):
     fields = hg.BaseElement(
         *[layout.forms.FormField(f) for f in self.object.active_fields()]
     )
     return hg.BaseElement(
         hg.H1(self.object, style="margin-bottom: 2rem"),
         hg.DIV(
             hg.DIV(
                 layout.forms.Form(
                     hg.C("form"), fields, layout.forms.helpers.Submit()
                 ),
                 style="padding: 1rem",
             ),
             hg.DIV(
                 self.object.as_svg(), style="width: 40%; border: 1px solid gray"
             ),
             style="display: flex",
         ),
     )
Пример #17
0
 def get_context_data(self, *args, **kwargs):
     layout = hg.BaseElement(
         hg.H3(_("Add %s") % pretty_modelname(self.model), ),
         self._get_layout_cached(),
     )
     return {
         **super().get_context_data(*args, **kwargs),
         "layout": layout,
         "pagetitle": _("Add %s") % pretty_modelname(self.model),
     }
Пример #18
0
    def __init__(
        self,
        fieldname,
        content,
        formname,
        formsetinitial=None,
        **formsetfactory_kwargs,
    ):
        self.fieldname = fieldname
        self.formname = formname
        self.formsetfactory_kwargs = formsetfactory_kwargs
        self.formsetinitial = formsetinitial
        self.content = content
        if isinstance(self.content, FormFieldMarker):
            self.content = hg.BaseElement(self.content)

        # search fields which have explicitly been defined in the content element
        declared_fields = set(f.fieldname for f in self.content.filter(
            lambda e, ancestors: isinstance(e, FormFieldMarker)))

        # append all additional fields of the form which are not rendered explicitly
        # These should be internal, hidden fields (can we test this somehow?)
        self.content.append(
            hg.F(lambda c: hg.BaseElement(*[
                FormField(
                    field,
                    formname=DEFAULT_FORMSET_CONTEXTNAME,
                    no_wrapper=True,
                    no_label=True,
                    no_helptext=True,
                ) for field in c[self.formname][
                    self.fieldname].formset.empty_form.fields if field not in
                declared_fields and field != forms.formsets.DELETION_FIELD_NAME
            ])))

        super().__init__(
            iterator=hg.C(f"{self.formname}.{self.fieldname}.formset"),
            loopvariable=DEFAULT_FORMSET_CONTEXTNAME,
            content=Form(hg.C(DEFAULT_FORMSET_CONTEXTNAME),
                         self.content,
                         standalone=False),
        )
Пример #19
0
 def __init__(self, helptext, disabled=False):
     super().__init__(
         helptext,
         hg.DIV(
             helptext,
             _class=hg.BaseElement(
                 "bx--form__helper-text",
                 hg.If(disabled, " bx--form__helper-text--disabled"),
             ),
         ),
     )
Пример #20
0
 def __init__(self, platform, company, searchbar, actions=(), *args, **kwargs):
     super().__init__(
         hg.If(
             HasBreadCookieValue("sidenav-hidden", "true"),
             variable_size_header_part(hg.BaseElement(), company, searchbar, "5rem"),
             variable_size_header_part(
                 hg.SPAN(platform, _class="bx--header__name--prefix"),
                 company,
                 searchbar,
                 "18rem",
             ),
         ),
         hg.DIV(
             hg.If(
                 hg.F(lambda c: c["request"].user.is_authenticated),
                 hg.A(
                     hg.SPAN(
                         hg.C("request.user.get_username"),
                         _class="bx--header__name--prefix",
                     ),
                     _class="bx--header__name",
                     href=reverse("userprofile"),
                     title=hg.C("request.user.get_username"),
                     style="padding: 0; margin-right: 1rem",
                 ),
             ),
             hg.If(
                 hg.F(lambda c: c["request"].user.is_authenticated),
                 hg.BUTTON(
                     Icon(
                         "logout",
                         size=20,
                         _class="bx--navigation-menu-panel-expand-icon",
                         aria_hidden="true",
                     ),
                     Icon(
                         "logout",
                         size=20,
                         _class="bx--navigation-menu-panel-collapse-icon",
                         aria_hidden="true",
                     ),
                     _class="bx--header__menu-trigger bx--header__action",
                     title=_("Logout"),
                     data_navigation_menu_panel_label_expand=_("Logout"),
                     data_navigation_menu_panel_label_collapse=_("Close"),
                     onclick=f"document.location = '{reverse('logout')}'",
                 ),
             ),
             _class="bx--header__global",
         ),
         _class="bx--header",
         data_header=True,
     )
Пример #21
0
def profile_field_password(fieldname):
    ret = profile_field(fieldname)
    ret[1] = C(
        hg.BaseElement(
            "●●●●●●●●●●●●",
            hg.A(
                _("Request reset"),
                href=reverse("userprofile.password_reset"),
                style="float: right",
            ),
        ))
    return ret
Пример #22
0
 def __init__(self, label, tabid, panelid, selected):
     super().__init__(
         hg.A(
             label,
             tabindex="0",
             id=tabid,
             _class="bx--tabs__nav-link",
             href="javascript:void(0)",
             aria_controls=panelid,
             aria_selected=hg.If(selected, "true", "false"),
             role="tab",
         ),
         _class=hg.BaseElement(
             "bx--tabs__nav-item",
             hg.If(selected, " bx--tabs__nav-item--selected"),
         ),
         data_target="#" + panelid,
         aria_selected=hg.If(selected, "true", "false"),
         role="tab",
         onclick=hg.BaseElement("setBreadCookie('selected-tab', '", tabid,
                                "')"),
     )
Пример #23
0
def _display_email_without_subscription(email):
    modal_add = modal_add_subscription(email)
    return hg.BaseElement(
        hg.DIV(email.email, style="font-weight: bold;"),
        hg.DIV(_("No subscription yet for "), email.email),
        layout.button.Button(
            _("Add subscription"),
            buttontype="ghost",
            icon="add",
            **modal_add.openerattributes,
        ),
        modal_add,
    )
Пример #24
0
def maintenance_database_optimization(request):
    database_path = settings.DATABASES["default"]["NAME"]
    current_db_size = os.stat(database_path).st_size / 1000

    class OptimizeForm(forms.Form):
        previous = forms.DecimalField(
            widget=forms.HiddenInput,
            initial=current_db_size,
        )

    form: OptimizeForm
    ret = hg.BaseElement()
    received_post = False

    if request.method == "POST":
        form = OptimizeForm(request.POST)
        if form.is_valid() and "previous" in form.cleaned_data:
            received_post = True
            connection.cursor().execute("VACUUM;")
            # get the previous size
            previous_size = form.cleaned_data["previous"]
            current_db_size = os.stat(database_path).st_size / 1000

            # try adding some message here.
            messages.info(
                request,
                _("The database size has been minimized from %.2f kB to %.2f kB."
                  ) % (previous_size, current_db_size),
            )

            ret.append(
                hg.H5(
                    _("Previous Size: %.2f kB") %
                    form.cleaned_data["previous"]))

    if not received_post:
        form = OptimizeForm()

    optimize_btn = Form(
        form,
        FormField("previous"),
        Button(
            _("Optimize"),
            type="submit",
        ),
    )

    ret.append(hg.H5(_("Current Size: %.2f kB") % current_db_size))
    ret.append(optimize_btn)

    return ret
Пример #25
0
 def add_button(self, container_css_selector, label=_("Add"), **kwargs):
     prefix = hg.C(f"{self.formname}.{self.fieldname}.formset.prefix")
     defaults = {
         "icon":
         "add",
         "notext":
         True,
         "buttontype":
         "tertiary",
         "id":
         hg.BaseElement(
             "add_", prefix,
             "_button"),  # required for javascript to work correctly
         "onclick":
         hg.BaseElement(
             "formset_add('",
             prefix,
             "', '",
             container_css_selector,
             "');",
         ),
     }
     return Button(label, **{**defaults, **kwargs})
Пример #26
0
 def as_plain(*args, add_label=_("Add"), **kwargs):
     """Shortcut to render a complete formset with add-button"""
     formset = FormsetField(*args, **kwargs)
     id = hg.html_id(formset, prefix="formset-")
     return hg.BaseElement(
         hg.DIV(formset, id=id),
         formset.management_form,
         formset.add_button(
             buttontype="ghost",
             notext=False,
             label=add_label,
             container_css_selector=f"#{id}",
         ),
     )
Пример #27
0
 def get_layout(self):
     return auth_page(
         hg.BaseElement(
             layout.notification.InlineNotification(
                 _("Password successfully changed"),
                 _("Please login again"),
                 kind="success",
                 lowcontrast=True,
                 style="margin-bottom: 4rem",
             ),
             hg.FORM(action=reverse("login"), id="authform"),
         ),
         _("Back to Login"),
     )
def common_tiles(request):
    return hg.BaseElement(
        R(
            tags(),
            addresses.email(request),
        ),
        R(
            addresses.postals(),
            addresses.numbers(request),
        ),
        R(
            other(),
            addresses.urls(request),
        ),
    )
Пример #29
0
def _close_button(resultcontainerid, widgetattributes):
    kwargs = {
        "_class": hg.BaseElement(
            "bx--search-close",
            hg.If(widgetattributes.get("value"), None, " bx--search-close--hidden"),
        ),
        "title": _("Clear search input"),
        "aria_label": _("Clear search input"),
        "type": "button",
    }
    if resultcontainerid is not None:
        kwargs["onclick"] = hg.format(
            "document.getElementById('{}').innerHTML = '';", resultcontainerid
        )
    return hg.BUTTON(Icon("close", size=20, _class="bx--search-clear"), **kwargs)
def contact_details_naturalperson(request):
    return hg.BaseElement(
        R(
            addresses.postals(),
            addresses.numbers(request),
        ),
        R(
            addresses.email(request),
            addresses.urls(request),
        ),
        R(
            base_data.tags(),
            base_data.other(),
        ),
    )