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. diff --git a/widget_tweaks/templatetags/widget_tweaks.py b/widget_tweaks/templatetags/widget_tweaks.py index 116b3c3..069b8b7 100644 --- a/widget_tweaks/templatetags/widget_tweaks.py +++ b/widget_tweaks/templatetags/widget_tweaks.py @@ -215,11 +215,25 @@ 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 == "type": - bounded_field.field.widget.input_type = v.resolve(context) + 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: - bounded_field = set_attr(bounded_field, f"{k}:{v.resolve(context)}") + attr_dict[k] = v.resolve(context) + for k, v in attr_dict.items(): + 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 = 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)