JavaScript API¶
New in version 2.11.
This document describes the JavaScript API available for django-jsonform widget.
Some use cases:
Dynamically modifying schema directly in the browser
Enabling/disabling inputs dynamically
Updating choices dynamically
Making AJAX requests on value changes
API¶
Note
django-jsonform uses react-json-form under the hood.
So, this is a shortened documentation of the actual API. We’ll only look at the functions which concern the widget.
reactJsonForm.getFormInstance(id)
¶
Use this function to get an instance of the form widget.
The id
is the ID of the widget container which looks like this: id_<field-name>_jsonform
.
E.g., if your model’s JSONField is called “my_field”, then the container id will be
id_my_field_jsonform
.
You can also do Right-click > Inspect element on the form widget to view the ID of the container.
var form = reactJsonForm.getFormInstance('id_my_field_jsonform');
formInstance.addEventListener(event, callback)
¶
Use this function to add a callback
function for an event
. It will be called
every time the event occurs.
The callback will receive an object containing these keys:
data
: The data of the widgetschema
: The schema of the widgetprevData
: Previous data (before the event)prevSchema
: Previous schema (before the event)
function onChangeHandler(e) {
// do something ...
}
var form = reactJsonForm.getFormInstance('id_my_field_jsonform');
form.addEventListener('change', onChangeHandler);
formInstance.update(config)
¶
Use this function to update the schema or the data of the widget.
The config
is a JavaScript object (dict) which looks like this:
var config = {
schema: ...,
data: ...,
}
form.update(config);
Important
If you call the update
function from a change
event listener, it is important
that you call it conditionally. Otherwise, it might lead to an infinite loop.
For example, call this function if the current data (data
) and the previous data
(prevData
) are not the same. This way you can avoid the infinite loop.
formInstance.getData()
¶
Returns the current data of the form instance.
formInstance.getSchema()
¶
Returns the current schema of the form instance.
Practical example¶
Updating choices dynamically: Let’s look at an example where there are two select inputs and choices of the second input depends on the first input.
Interactive Demo¶
In the following demo, Vehicle input’s choices
and helpText
will change
dynamically depending upon the value of the Category input.
Schema¶
The schema for this demo:
{
'type': 'object',
'title': 'Mode of transportation',
'keys': {
'category': {
'type': 'string',
'choices': ['Land', 'Water', 'Air']
},
'vehicle': {
'type': 'string',
'choices': [] # vehicle choices will be added dynamically
}
}
}
JavaScript code¶
Following is the code which is used in the demo above:
// my-script.js
window.addEventListener('load', function() {
/* We want to run this code after all other scripts have been loaded */
if (window.reactJsonForm) {
/* We put this inside a condition because
* we only want it to run on those pages where
* django-jsonform widget is loaded
*/
var form = reactJsonForm.getFormInstance('id_my_field_jsonform');
form.addEventListener('change', onJsonFormChange);
}
});
var vehicleChoiceMap = {
'Land': ['Car', 'Bus', 'Train'],
'Water': ['Ship', 'Boat', 'Submarine'],
'Air': ['Aeroplane', 'Rocket'],
};
function onJsonFormChange(e) {
var data = e.data; // current data
var prevData = e.prevData; // previous data (before this event)
var schema = e.schema; // current schema
var prevSchema = e.prevSchema; // previous schema (before this event)
var selectedCategory = data.category;
if (!selectedCategory) {
/* no category selected yet, exit the function */
return;
}
if (selectedCategory === prevData.category) {
/* category hasn't changed, no need to update choices */
return;
}
schema.keys.vehicle.choices = vehicleChoiceMap[selectedCategory];
schema.keys.vehicle.helpText = "Select " + selectedCategory + " vehicle";
data.vehicle = ''; // reset previously selected vehicle
form.update({
schema: schema,
data: data
})
}
Loading your custom JS file on the admin page¶
You can use the Media
class to load your custom JS files in the admin page.
Quickest way is via your admin class:
# models.py
class MyAdmin(admin.ModelAdmin):
...
class Media:
js = ('path/to/my-script.js',)
There are other ways as well (and perhaps more suitable in certain cases) for loading your custom files, such as by subclassing the widget.
See also
- Form Assets (the Media class)
Django’s documentation on the
Media
class.