AJAX Support
When building extensions with the SDK, there may come a time when you’d like to simply call back to your extension for data to update the existing page, bypassing the traditional method of switching routes to display new content.
For this, and other scenarios you may encounter, you can use tecton.requestExtensionData to request data from your existing Q2TectonServerRequestHandler
, Q2TectonClientRequestHandler
.
The tecton.requestExtensionData method is already available to you when using self.get_tecton_form to render your initial HTML template, but there are a few updates you’ll need to make when creating your new ajax target route.
For this, and other scenarios you may encounter, you can use q2_ajax
to request data from your existing Online Extension
.
The q2_ajax
method is already available to you when using Q2Form to render your initial HTML template,
but there are a few updates you’ll need to make when creating your new ajax target route.
Warning
This @ajax decorator is not needed for a Client Side Rendered modules as all methods in a CSR module return JSON. @ajax’s behavior happens by default.
Server-Side Python
Please add the following import to extension.py
from q2_sdk.core.web import ajax
This module is a decorator used to wrap your ajax target method to ensure proper formatting of the request and response.
Here is an example of an ajax target method
from q2_sdk.core.web import ajax
from q2_sdk.models.tecton import Success, BadRequest, InternalServerError
@ajax
async def ajax_target(self):
value = self.form_fields.get('key1') # access key value from form_fields
if value is "approved value":
return Success({
'data': value
})
elif value is "client sent bad data":
return BadRequest({
'data': "you sent bad data!"
})
elif value is "server had an error":
return InternalServerError({
'data': "sorry I made a mistake"
})
from q2_sdk.core.web import ajax
@ajax
async def ajax_target(self):
value = self.form_fields.get('key1') # access key value from form_fields
return {
'data': value
}
You will always return a dictionary or TectonResponse from this method, which will ultimately become JSON to parse as a response.
You can name your method whatever you like, but please keep in mind that you will need to add this routing key to your router
along with default
and submit
that should already be in place.
Frontend JavaScript
So far, we have handled the python requirements for making data only requests.
Here is a JavaScript example required for your extension.
// handle click event
$('.test-btn').click(function () {
var payload = {
'route': 'ajax_target',
'body': {
"key1": "value",
"key2": "value"
}
};
tecton.sources.requestExtensionData(payload).then(function(data) {
// {"statusText":"success","data":{ ... your returned data here ... },"status":200}
}).catch(function(data) {
// {"statusText":"success","fail/error":{ ... your returned data here ... },"status":400/500}
});
});
function onSuccess(response) {
render(response)
}
function onFailure(response) {
// handle failure
}
// handle click event
$('.test-btn').click(function () {
var routingKey = 'ajax_target';
var userDefinedObject = {
"key1": "value",
"key2": "value"
};
q2_ajax(userDefinedObject, routingKey, onSuccess, onFailure);
});
// jQuery can be used to add HTML here
function render(response) {
var extensionResponse = JSON.parse(response.data.forms[0]);
}
/*
When making the ``q2_ajax`` request, the userDefinedObject will be accessible as ``self.form_fields`` in extension.py.
When rendering the extension response, you can use jQuery to append elements or make updates to the DOM as needed.
*/