I am looking to add some structure to my client side code and have been reading about knockout.js
. I have been reading the documentations and have a simple question
You can add custom attributes to your fields in the Form's Meta definition with widgets.
class SomeForm(forms.ModelForm):
class Meta:
model = SomeModel
widgets = {'field_name1': forms.Textarea(attrs={'data-bind':'value: field1'}),
'field_name2': forms.TextInput(attrs={'data-bind':'value: field2'})}
For example, the first field would be rendered:
<textarea id="id_field_name1" name="field_name1" data-bind="value: field1"></textarea>
Update: as a bonus here is an easy way to change an attribute for every field in a form, for example if they all need a specific class (helpful for other js addons or css styling)
def __init__(self, *args, **kwargs):
super(SomeForm, self).__init__(*args, **kwargs)
for name, field in self.fields.items():
field.widget.attrs['class'] = 'some_form_field'
# this could be used in your case if the Django field name is the
# same as the KO.js field name
field.widget.attrs['data-bind'] = 'value: %s' % name
Another way is to use django-crispy-forms and define data-bind
attributes in the layout:
def __init__(self, *args, **kwargs):
super(SomeForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.layout = Layout(
Div('field_1',
Field('field_2', data_bind='value: field_2')),
HTML("{% if success %} <p data-bind="css: { success: success_flag }">Operation was successful</p> {% endif %}"),
)
Then in the template you only do:
{% crispy form form.helper %}
and voila.
Cripsy-forms is even more powerful than that and allows you to define your own layout templates etc.