datetime.datetime(2008, 5, 27, 17, 0)
The gathering point is at the main entrance of Linuxtag conference (Messe Berlin).
Aidas Bendoraitis on development with Django, Python, and JavaScript. I am migrating this blog to djangotricks.com
datetime.datetime(2008, 5, 27, 17, 0)
input[type=checkbox]
and similar in CSS are not supported by IE so people working with templates and CSS obviously need some other way to select and style specific types of input fields.<span class="form_checkbox">
{{ form.is_privacy_policy_confirmed }}
</span>
class FormExample(forms.Form):
is_privacy_policy_confirmed = forms.BooleanField(
required=True,
widget=CheckboxInput(attrs={'class': 'form_checkbox'}),
)
render
of the Widget
class draws the input field in HTML. As it takes a parameter attrs
for additional input field attributes, my idea was to create a decorator which modifies the incoming parameters and adds a CSS class "form_TYPE"
, where TYPE
is the input field type.input_type
of the Widget class is used for forming the CSS class name (N.B. not all widgets have this attribute).from django.newforms.widgets import Input, CheckboxInput, RadioSelect, CheckboxSelectMultiple
### adding class="form_*" to all html input fields ###
def add_css_class(css_class=""):
def modify_input_class(function):
_css_class = css_class
def new_function(*args, **kwargs):
arg_names = function.func_code.co_varnames
new_kwargs = dict(zip(arg_names, args))
new_kwargs.update(kwargs)
css_class = _css_class or "form_%s" % getattr(
new_kwargs['self'],
"input_type",
"undefined",
)
self = new_kwargs.pop("self")
attrs = getattr(self, "attrs", None) or {}
if "class" in attrs:
css_classes = attrs["class"].split()
if css_class not in css_classes:
css_classes.append(css_class)
attrs["class"] = " ".join(css_classes)
else:
attrs["class"] = css_class
self.attrs = attrs
return function(self, **new_kwargs)
return new_function
return modify_input_class
Input.render = add_css_class()(Input.render)
CheckboxInput.render = add_css_class("form_checkbox")(CheckboxInput.render)
RadioSelect.render = add_css_class("form_radio")(RadioSelect.render)
CheckboxSelectMultiple.render = add_css_class("form_checkbox")(CheckboxSelectMultiple.render)
models.py
file in your project.css_class
isn't recognized by the sub-child function new_function
directly although the scope of the variable css_class
should let it be accessed there. Anyway, the value got easily accessible when I reassigned it to another variable like _css_class
in the child function modify_input_class
.attrs
argument from the decorated function as it was not clear whether it would be passed as a positional or as a named argument. The first three lines of the function new_function
collects all the incoming arguments to a dictionary new_kwargs
. They can be modified and then passed to the original function to decorate.