Commenting system in Anvil

Hi ea5505, welcome to the Forum!

@hugetim is right, the Magical Concierge app has a good example of a live chat system. Here’s the clone link for it:

https://anvil.works/ide#clone:EGZVPAOYFPFP4CSQ=IGSLPIF4EO7LS6YST72RASQZ|47NRNWCEGVRBBPLN=H2ZC2KCYFKF6NKE57BDKWFBS

Live Chat app

I’ve also written an as-simple-as-possible version of a live chat app. It stores messages in a Data Table, displays them in a Data Grid, and polls regularly for updates using a Timer.

It has a table of channels, and messages are sent to/from a channel. You could easily write an admin form to allow privileged users to set which channels users are allowed to read and write to. You could also modify it such that users send messages directly to each other.

Here’s a clone link:

https://anvil.works/ide#clone:6APMATYZGK473ZLK=XYBGEZNNM7ELXGFJW6LHHIMM

and a GIF of it in action:

Join me for a chat!

https://live-chat.anvil.app

Comment widget

Here’s an app where I’ve modified the Live Chat app to be a Custom Component called CommentForm. That means it appears in the Toolbox and it can be dragged-and-dropped into Forms.

I’ve assigned the CommentForm a property called entity_type that defines which table in the database the comments relate to - in my example, there are documents, plots and images. Each comment’s database entry has a link to either a document, a plot or an image:

Here’s a clone link for it:

https://anvil.works/ide#clone:U3VHREID2FFXVVTN=TFBDRFR65KV3XKESG7VXMHSJ

Hopefully the code is self-explanatory enough that you can see what’s going on - just ask if it’s not clear.

I’ve used Data Bindings quite a lot, particularly on the Document, Image and Plot Forms, so if you can’t see how something ends up with its value, check the Data Bindings.

Here’s a GIF of it!

And a link to the live app

https://comment-section.anvil.app/

How the comments are fetched from the Data Tables

I should explain how the CommentForm gets the comments from the database. The CommentForm Custom Component is generalised for different entity types so it’s not immediately clear, but if we look at a single example hopefully it makes sense:

  1. When I added the CommentForm to the Document form, I set the CommentForm's entity_type property to be 'document'.
  2. When the Document form is opened by the EntrypointDocRow, it is given a Data Tables Row representing the document in question:
open_form('Document', self.item)  # self.item is the Data Tables Row 
  1. This is assigned to self.item of the Document form, which in turn is assigned to the self.item of the CommentForm using a Data Binding:
    50
  2. The CommentForm calls a server function to fetch the comments.
    In our example, self.entity_type is 'document' and self.item is the Row from the documents table:
  def get_comments(self):
    if self.item:
      return anvil.server.call_s('get_comments', self.entity_type, self.item)
  1. The server function searches the Data Tables for all comments whose document column matches the item passed in.
    In our example entity_type is 'document' and entity is the Row from the documents table:
@anvil.server.callable
def get_comments(entity_type, entity):
  return app_tables.comments.search(
    # In our example, this is equivalent to 'document=my_document_row':
    **{entity_type: entity}
  )

Does that answer your question?

I hope you can make use of some of this. Let me know if you have any questions, if you can’t quite see how this works or if you’d like some advice on how to do something slightly different.

4 Likes