From 9bfbe22abdd7aac42b508ab0d750b2c7d27d2743 Mon Sep 17 00:00:00 2001 From: Maxim Belyayev Date: Thu, 26 Dec 2024 11:04:43 -0500 Subject: [PATCH 1/3] Add support for dynamic attrs with attr_dict --- widget_tweaks/templatetags/widget_tweaks.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/widget_tweaks/templatetags/widget_tweaks.py b/widget_tweaks/templatetags/widget_tweaks.py index 116b3c3..73538ec 100644 --- a/widget_tweaks/templatetags/widget_tweaks.py +++ b/widget_tweaks/templatetags/widget_tweaks.py @@ -215,11 +215,20 @@ def render(self, context): bounded_field = append_attr( bounded_field, f"class:{context['WIDGET_REQUIRED_CLASS']}" ) + attr_dict = {} for k, v in self.set_attrs: + if k == "attr_dict": + resolved_dict = v.resolve(context) + if not isinstance(resolved_dict, dict): + raise ValueError(f"{k} must be of type dict.") + attr_dict.update(resolved_dict) + else: + attr_dict[k] = v.resolve(context) + for k, v in attr_dict.items(): if k == "type": - bounded_field.field.widget.input_type = v.resolve(context) + bounded_field.field.widget.input_type = v else: - bounded_field = set_attr(bounded_field, f"{k}:{v.resolve(context)}") + bounded_field = set_attr(bounded_field, f"{k}:{v}") for k, v in self.append_attrs: bounded_field = append_attr(bounded_field, f"{k}:{v.resolve(context)}") return str(bounded_field) From 40869d46e5ac8dac8c6aa2148900f76e219735cd Mon Sep 17 00:00:00 2001 From: Maxim Belyayev Date: Thu, 26 Dec 2024 11:24:46 -0500 Subject: [PATCH 2/3] Update README --- README.rst | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/README.rst b/README.rst index ef848a1..3830131 100644 --- a/README.rst +++ b/README.rst @@ -103,6 +103,42 @@ You can be creative with these variables: e.g. a context processor could set a default CSS error class on all fields rendered by ``{% render_field %}``. +In addition, it is possible to dynamically set attributes using a variable of type dict from context +and setting it equal to ``attr_dict``. The content of ``attr_dict`` its order around explicitly named +attributes matters; it is possible to set a default attribute that will be overwritten by ``attr_dict`` +by positioning it to the left, or conversely to have an attribute always overwrite one in ``attr_dict`` +by positioning it to the right. + +Examples: + +Let context_dict_var be: + +.. code-block:: html+django + + context_dict_var = {"type":"text", id="my_username_id", placeholder="Login"} + +The following line: +.. code-block:: html+django + + {% render_field form.field attr_dict=context_dict %} + +returns: + +.. code-block:: html+django + + + +The following line: +.. code-block:: html+django + + {% render_field form.field id="default_id" label="default_label" attr_dict=context_dict placeholder="Overwrite" %} + +returns: + +.. code-block:: html+django + + + attr ---- Adds or replaces any single html attribute for the form field. From af07e24234a7257baf0cd46dbcedc0ba6e97f09e Mon Sep 17 00:00:00 2001 From: Maxim Belyayev Date: Wed, 8 Jan 2025 09:50:23 -0500 Subject: [PATCH 3/3] Remove attr if dynamic attr value is None --- widget_tweaks/templatetags/widget_tweaks.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/widget_tweaks/templatetags/widget_tweaks.py b/widget_tweaks/templatetags/widget_tweaks.py index 73538ec..069b8b7 100644 --- a/widget_tweaks/templatetags/widget_tweaks.py +++ b/widget_tweaks/templatetags/widget_tweaks.py @@ -225,10 +225,15 @@ def render(self, context): else: attr_dict[k] = v.resolve(context) for k, v in attr_dict.items(): - if k == "type": - bounded_field.field.widget.input_type = v + if v: + if isinstance(v, bool): + bounded_field = set_attr(bounded_field, f"{k}") + if k == "type": + bounded_field.field.widget.input_type = v + else: + bounded_field = set_attr(bounded_field, f"{k}:{v}") else: - bounded_field = set_attr(bounded_field, f"{k}:{v}") + bounded_field = remove_attr(bounded_field, k) for k, v in self.append_attrs: bounded_field = append_attr(bounded_field, f"{k}:{v.resolve(context)}") return str(bounded_field)