Chapter 1: Creating A Configuration UI

For this tutorial we’ll be using 2 new pieces of trexjacket, dialogs and settings. By the end of this chapter you’ll be configuring settings in the dashboard as well as opening popup windows outside of Tableau.

Get started by downloading the starter Tableau workbook here and cloning the starter app here. After downloading both of those items, add your extension to your dashboard just like you did in Chapter 1 of the Chat Tutorial here: Chapter 1: Setting up the environment

Once you’ve cloned the starter app and added your trex file, you’ll see 3 things in the Client Code section of Anvil:

  1. A Homepage form: This will be the main page of our extension

  2. A Configure form: This will be the configure page of our extension

  3. A module named startup (set as the startup module): We’ll use this page to define our default settings and open the Homepage form. When our extension loads, this module will run first.

https://extension-documentation.s3.amazonaws.com/tutorials/value-override/code_section.PNG

Startup module

In the startup module, let’s set some default values for our settings by adding the following code:

 1from trexjacket import api, dialogs
 2
 3from .Configure import Configure
 4
 5api.get_dashboard().settings.setdefaults({
 6  "worksheet": None,
 7  "id_field": None,
 8  "override_field": None,
 9  "username": None
10})
11
12dialogs.open_start_form('Homepage')

Here we define our default values for the workbook settings as well as open our Homepage form. In order to open dialogs we must open our primary form using dialogs.open_start_form.

Homepage

In the Homepage form, add a button component named btn_configure with its “click” event handler registered to a method named btn_configure_click.

Anvil tip: Adding buttons

To add a button with Anvil, simply drag and drop the component from the Toolbox right into the form’s design pane:

https://extension-documentation.s3.amazonaws.com/tutorials/value-override/button_event_click.gif

When adding buttons, don’t forget to give the component a descriptive name (btn_configure above), as well as register the event handling function in the Toolbox view:

https://extension-documentation.s3.amazonaws.com/tutorials/value-override/container_properties.PNG

In the above example we bind the btn_configure_click method to the button’s click event. Now each time a user clicks our button, the btn_configure_click method of our form will run!

Then add the following code to Homepage (note that the btn_configure_click method here is the same method we added in the “Container properties” section of the button component!):

 1from ._anvil_designer import HomepageTemplate
 2import anvil
 3
 4from trexjacket.api import get_dashboard
 5from trexjacket import dialogs
 6
 7class Homepage(HomepageTemplate):
 8  def __init__(self, **properties):
 9    self.dashboard = get_dashboard()
10    self.init_components(**properties)
11
12  # When a user clicks the configure button, we'll use the dialogs
13  # module to open our configure form in a new window
14  def btn_configure_click(self, **event_args):
15    dialogs.show_form('configure_form', width=900, height=900)
16    self.refresh_data_bindings()

Configure

Finally, let’s set up our Configure form. Start by adding 4 labels, 4 drop down components, and a button. Once you’re done, the UI of the Configure form should look like this:

https://extension-documentation.s3.amazonaws.com/tutorials/value-override/configure_form.PNG

Use the table below to configure the data bindings for the drop down components (be sure to check the “writeback” and “include placeholder” option for each drop down component):

Drop down data bindings

Component name

Data binding

drop_down_worksheet

selected_value to self.dashboard.settings['worksheet']

drop_down_worksheet

change event bound to drop_down_sheet_change

drop_down_id_field

selected_value to self.dashboard.settings['id_field']

drop_down_override_field

selected_value to self.dashboard.settings['override_field']

drop_down_username

selected_value to self.dashboard.settings['username']

btn_submit

click event to self.btn_submit_click

Important!

By binding a drop down’s selected value to the keys in our dashboard settings, we can provide a quick and easy way to configure settings. Now whenever a user chooses from the drop down menu, our settings are saved! These values can be retrieved anywhere in our application using their name, just like how dictionaries work: dashboard.settings[keyname]. Settings can make your extensions configurable and extensible, allowing you to reuse extensions in different dashboards.

Now that we have our UI elements, let’s add our code to Configure:

 1from ._anvil_designer import ConfigureTemplate
 2import anvil
 3
 4from trexjacket import api, dialogs
 5
 6# In order for our Configure form to be able to be opened in
 7# a popup window we need to register it using the @dialogs.dialog_form decorator.
 8@dialogs.dialog_form('configure_form')
 9class Configure(ConfigureTemplate):
10  def __init__(self, **properties):
11    self.dashboard = api.get_dashboard()
12    self.drop_down_worksheet.items = [ws.name for ws in self.dashboard.worksheets]
13    self.show_fields()
14    self.init_components(**properties)
15
16  # Here we call self.raise_event('x-close-alert')
17  # to close the dialog window once we're done
18  def btn_submit_click(self, **event_args):
19    self.raise_event('x-close-alert')
20
21  def show_fields(self):
22    fields = []
23    if self.dashboard.settings['worksheet']:
24
25      # This is our first time accessing settings, reading the value of the 'worksheet' key to
26      # to dynamically get a worksheet from our dashboard.
27      ws = self.dashboard.get_worksheet(self.dashboard.settings['worksheet'])
28
29      records = ws.get_summary_data()
30      if not records:
31        ph = "No summary fields in worksheet!"
32      else:
33        ph = "Pick a field"
34        fields = [f for f in records[0]]
35    else:
36      ph = "Pick a worksheet first"
37
38    for dropdown in [
39      self.drop_down_id_field,
40      self.drop_down_override_field,
41      self.drop_down_username,
42    ]:
43      dropdown.placeholder = ph
44      dropdown.items = fields
45
46  def drop_down_sheet_change(self, **event_args):
47    self.show_fields()

Important!

Notice that the string we passed to @dialogs.dialog_form is the string we used in our Homepage form to open our dialog box.

Summary

Now that we’ve configured our forms, clicking the “Configure” inside our extension should open a popup window like the one below:

https://extension-documentation.s3.amazonaws.com/tutorials/value-override/configure_settings.gif

Go ahead and open the configure form of your extension and select the Sale Map, State, AGG(Profit Ratio), and username options (in that order!) for each drop down. Click submit to close the dialog window.

In the next chapter we’ll enable users to add an override from the Homepage form.