widgets.py¶
OptionalWidget¶
OptionalWidget - A two-component MultiField
: a checkbox that indicates optional value and a field itself
(widget_class
= Textarea
by default). The field itself is enabled / disabled according to the checkbox state
via client-side $.optionalInput plugin, implemented in plugins.js:
from django_jinja_knockout.widgets import OptionalWidget
OptionalWidget(attrs={'class': 'autogrow vLargeTextField', 'cols': 40, 'rows': 2})
See also vLargeTextField usage, although it’s optional and is not the requirement for OptionalWidget.
DisplayText¶
DisplayText - Read-only widget for existing ModelForm
bound objects. Assign to ModelForm.widgets
or to
ModelForm.fields.widget
to make selected form fields displayed as read-only text.
Use DisplayModelMetaclass
from django_jinja_knockout.forms
to set all field widgets of form as
DisplayText
, making the whole form read-only.
In last case the form will have special renderer with table like view. See Displaying read-only “forms” for more info.
Widget allows to specify custom formatting callback to display complex fields, including foreign relationships,
pre-defined string mapping for scalar True
/ False
/ None
and layout override for bs_form()
/ bs_inline_formsets() macros. Note that it’s possible to call these macros from Django language
templates like this:
{% jinja 'bs_form.htm' with _render_=1 form=form action=view_action opts=opts %}
For example, to override Member
model note
field DisplayText widget html output via get_text_method()
:
class MemberDisplayForm(WidgetInstancesMixin, RendererModelForm, metaclass=DisplayModelMetaclass):
class Meta:
def get_note(self, value):
# self.instance.accepted_license.version
if self.instance is None or self.instance.note.strip() == '':
# Do not display empty row.
self.skip_output = True
return None
return format_html_attrs(
'<button {attrs}>Read</button>',
attrs={
'class': 'component btn btn-info',
'data-component-class': 'Dialog',
'data-event': 'click',
'data-component-options': {
'title': '<b>Note for </b> <i>{}</i>'.format(self.instance.profile),
'message': format_html('<div class="preformatted">{}</div>', self.instance.note),
'method': 'alert'
}
}
)
model = Member
fields = '__all__'
widgets = {
'note': DisplayText(get_text_method=get_note)
}
See Component IoC how to register custom Javascript data-component-class
.
See DisplayText sample for the complete example.
ForeignKeyGridWidget¶
Implements django.admin -like widget to select the foreign key value with the optional support of in-place CRUD editing of foreign key table rows.
See ForeignKeyGridWidget section of Datatables for the detailed explanation.
Here is the screenshot of the ForeignKeyGridWidget running djk_sample project:
MultipleKeyGridWidget¶
django.admin -like widget to select multiple foreign key values for the form relation.
See MultipleKeyGridWidget section of Datatables for the detailed explanation.
PrefillWidget¶
PrefillWidget - Django form input field which supports both free text and quick filling of input text value from
the list of prefilled choices. ListQuerySet has prefill_choices()
method, which allows to generate lists of
choices for PrefillWidget initial values like this:
from django_jinja_knockout.widgets import PrefillWidget
from django_jinja_knockout.query import ListQuerySet
# ...
self.related_members_qs = ListQuerySet(
Member.objects.filter(
club__id=self.request.resolver_match.kwargs.get('club_id', None)
)
)
if self.related_members_qs.count() > 1 and isinstance(form, MemberForm):
# Replace standard Django CharField widget to PrefillWidget with incorporated standard field widget:
form.fields['note'].widget = PrefillWidget(
data_widget=form.fields['note'].widget,
choices=self.related_members_qs.prefill_choices('note')
)
# Replace one more field widget to PrefillWidget:
form.fields['name'].widget = PrefillWidget(
data_widget=form.fields['name'].widget,
choices=self.related_members_qs.prefill_choices('name')
)
See djk-sample
project for the sample of PrefillWidget usage with inline formsets. It is even simpler to use this
widget in single ModelForm without the inline formsets.
See widget_prefill_dropdown.htm macro for the default rendering of PrefillWidget.