-
Notifications
You must be signed in to change notification settings - Fork 0
How to add new fields (non relationship fields)
Issue 21: allow more input types in application is a good example to get started. Below summarize the changes needed for a simple field, no complex relationship like one-to-one, one-to-many or many-to-many relationship. We use adding the field notes
to application
as an example:
application.ts
, add the new field, for interface, model class, etc.
application-component.ts
, add a block for displaying the new field.
If the new field can reuse existing field components like link
, input
(simple one-line text/time/...), etc, then can skip this step. Otherwise we create a field component. In the case for application.notes
, it's a rich text field that uses component CKeditor
to generate rich content.
In form-factory/
, create a directory for the new field. Each field requires two types of files: a FormField
component, and a FormFieldMeta
class. It's the easiest to copy an existing field's directory to shadow all the things you need to configure.
The most important part here is the FormField
component. Here we create a FormRichTextField
. We use Formik
's <Field>
to scaffold the form infrastructures. The changes needed depends on the type of field you are creating, but the basic ideas are:
- Initial value: you can retrieve the initial value by
field.value
, use this as either placeholder or initial value (like loading existing data, think case of edit) for the low-level component (<CKeditor>
in this case). Thefield
is provided by Formik<Field>
'srender={(field, ...) => ...}
. - OnChange: when using a non-trivial low level component other than
<input >
, the way foronChange
to retrieve the UI's value is oftentime different than a typical<input>
, which is something likeevent.target.value
. In our case, our low-level component<CKeditor>
useseditor.getData()
to retrieve value. You will get error if you just use{...field}
to pass over everything onto<CKeditor>
, because formik'sonChange
by default uses the<input>
way (event.target.value
). As a result, you need to explicitly implementonChange
and take care of setting the formik field value. Luckily, this is not so hard. Basically you useform.setFieldValue(field.name, <the low level component value here>)
to inform formik to sync the field's value. Here. - Label: this will not affect the actual data, just for UI and readability purpose. This label is specified when instantiating the meta class, and in the field component file here you can use
this.props.label
to show the label.
And that's most of the cases what you need!
In our example, the field notes
belongs to application
, so we want to add our notes
form field component to the application form component. In application form field, you'll new the meta class and add it to this.formFieldPropsList
. You can look at the existing newed metas in the list to help you finish.
After adding the meta instance, we should now see the new field appearing in the application form!
You'll add a field to the model class. Then do manage.py makemigrations
and then migrate
.
For the application serializer, you'll add the new field to fields = (...., 'new_field_here')
, so that it appears in the json response, and will accept this field in POST requests.
Check:
- Press
create application
to open the form. Does the new field appeared? - Type something in the field, and press saved. Does the display component show the changed field value?
- Re-login to the app, does the server data gives the changed field value? If so, you can rest assure that the data is propagated to database!