Forms
First, let’s take a closer look at the code that makes our extension work. Open up AccountDashboard/extension.py and let’s dive in.
When a user selects our form, the Caliper SDK server is called through a special POST request.
When a user first hits our form, their request will be sent to the
self.default
method.
Here’s the code:
async def default(self):
template = self.get_template('index.html.jinja2', {})
html = self.get_tecton_form(
"AccountDashboard",
custom_template=template,
routing_key="submit"
)
return html
Above, we are generating a Q2Form with the name of our extension as a header: AccountDashboard. Our form renders a custom HTML template, which we’ll discuss further in “Templates”. You’ll also notice a routing_key argument, which we’ll explain in the next step.
For our account dashboard, a great place to start would be to fetch and display a list of the accounts belonging
to the active user. Luckily, our request handler has access to this information without us having to do a thing: it is
automatically accessible via the self.account_list
object.
Here’s the code to obtain our account list. Overwrite your default()
method with this one:
async def default(self):
account_models = []
for account in self.account_list:
account_models.append({
'account_num': account.host_acct_id,
'account_name': account.product_name,
'account_balance': account.balance_to_display
})
template = self.get_template('index.html.jinja2', {
'accounts': account_models
})
html = self.get_tecton_form(
"AccountDashboard",
custom_template=template,
routing_key="submit"
)
return html
Here is the code to display our account list. In AccountDashboard/templates
, overwrite your index.html.jinja2
file with this:
<div class="table-wrapper">
<table>
<thead>
<tr>
<th width="150">
Host Account ID
</th>
<th>
Account Name
</th>
<th class="text-right">
Account Balance
</th>
</tr>
</thead>
<tbody>
{% for account in accounts %}
<tr>
<td>{{ account.account_num }}</td>
<td>{{ account.account_name }}</td>
<td class="text-right">{{ account.account_balance }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<q2-input
name='account_id'
id='account_id'
label="Account ID">
</q2-input>
We start with an empty account_models list, then we iterate through our self.account_list
and append an account
object to the list with details for each account. The accounts are passed to the custom template, where we can again
iterate through the accounts to display the account details.
You’ll notice our input field is still there. It’s not just any field, it’s a
q2-input. Tecton components start with q2-
, and provide all kinds of
benefits from built-in accessibility improvements to consistency with your chosen
platform. We’ll use it in the next step.
If you want to make your data look extra nice, add this style block to the top
of your index.html.jinja2
, above the first <div>
:
<style>
table {
table-layout: fixed;
text-align: left;
}
td {
vertical-align: top;
}
td,
th {
padding: 15px 10px;
}
th {
box-shadow: inset 0 -2px 0 0 #cccccc;
}
td {
box-shadow: inset 0 -1px 0 0 #eeeeee;
}
.text-right {
text-align: right;
}
</style>
Load up your form again, and make sure it displays your user’s accounts. In the next couple steps, this static form will take an input
and respond with data from our database. First, let’s take a look at how the Q2RequestHandler
routes requests to different methods.