Chapter 6: Displaying comments

In the last chapter we saved the comments to a database. In this chapter we’ll build the UI that shows what comments have already been made.

https://extension-documentation.s3.amazonaws.com/tutorials/chat/createdatagrid.gif

Click the “Design” button on Main in Anvil. Then, let’s drag a Data Grid component on to the page and name it dg_comments. Set the Name and Key property for each column to the following:

Data Grid Details

Name

Key

Comment

comment

By

user

At

at

State

id

Profit Ratio

value

Note

Data grids are special in that when you add one to your UI, a repeating panel is automatically created inside of it. In this case, the data grid we created will create a Repeating Panel component named repeating_panel_1, which you will see in the code block below.

Additionally, when we defined the “Key” for each column in the data grid, the repeating panel will use that key to access a value from whatever we pass in to the repeating panels items attribute. In our case we’re setting items to rows from the comments table, and using the column names as its keys.

Now let’s update our __init__ method to populate the data grid with the rows from the comments table.

# imports omitted

class Main(MainTemplate):
    def __init__(self, **properties):
      self.state_name = None
      self.profit = None
      self.logged_in_user = None
      self.repeating_panel_1.items = app_tables.comments.search()
      self.init_components(**properties)
      dashboard.register_event_handler('selection_changed', self.selection_changed_event_handler)

    # selection_changed_event_handler and btn_save_click omitted

and our btn_save_click to update when a new comment is made:

# Main code omitted

def btn_save_click(self, **event_args):
    app_tables.comments.add_row(
      user=self.logged_in_user,
      comment=self.tb_comment.text,
      id=self.state_name,
      value=self.profit,
      at=datetime.now()
    )
    self.tb_comment.text = ""
    self.repeating_panel_1.items = app_tables.comments.search()

Reload your extension in your dashboard, add a comment, and watch the table update!

https://extension-documentation.s3.amazonaws.com/tutorials/chat/finaloutput.gif

Congrats! You now have a fully functioning Tableau Extension, built with Anvil X.

Looking for more to do? Check out the Value Override tutorial next to learn about dashboard settings. Or, try to add some of the following functionality to your chat extension:

  • Hide the “save comment” button until a user selects a mark

  • Format the “At” column of the data grid using strftime

  • Handle multiple selections instead of just saving the first one

Click to view the full code for Main
 1from ._anvil_designer import MainTemplate
 2from anvil import *
 3from anvil.tables import app_tables
 4import anvil.tables.query as q
 5from anvil import tableau
 6
 7from trexjacket.api import get_dashboard
 8dashboard = get_dashboard()
 9
10from datetime import datetime
11
12class Main(MainTemplate):
13  def __init__(self, **properties):
14    self.state_name = None
15    self.profit = None
16    self.logged_in_user = None
17    self.repeating_panel_1.items = app_tables.comments.search()
18    self.init_components(**properties)
19    dashboard.register_event_handler('selection_changed', self.selection_changed_event_handler)
20
21  def selection_changed_event_handler(self, event):
22    user_selection = event.worksheet.get_selected_marks()
23
24    if len(user_selection) == 0:
25        self.state_name = None
26        self.profit = None
27        self.logged_in_user = None
28    else:
29        record = user_selection[0]
30        self.state_name = record['State']
31        self.profit = record['AGG(Profit Ratio)']
32        self.logged_in_user = record['logged_in_user']
33
34  def btn_save_click(self, **event_args):
35    app_tables.comments.add_row(
36      user=self.logged_in_user,
37      comment=self.tb_comment.text,
38      id=self.state_name,
39      value=self.profit,
40      at=datetime.now()
41    )
42    self.tb_comment.text = ""
43    self.repeating_panel_1.items = app_tables.comments.search()