Chapter 7:
Delete articles

The Delete process is our final step, and it will look like this:

  1. The user clicks the ‘Delete’ button
  2. A popup appears, asking the user to confirm if they wish to delete the selected article
  3. If the user clicks ‘Yes’, we delete the article. Otherwise, we do nothing
  4. If the article is deleted, we refresh the Homepage to remove the deleted article

We’ll walk through these steps below.

Step 1: The Delete button

First, let’s create our ‘Delete’ button:

Adding a delete button to the ArticleView Form

Go to Design View of your ‘ArticleView’ Form, and drop a FlowPanel Flow Panel icon into the page. Move your edit_article_button into the FlowPanel. Then, drop a second button into the FlowPanel, and set the align property of the FlowPanel to ‘right’.

Select the new button, and rename it delete_article_button. Change the role to primary-color, the background property to ‘red’, and the foreground property to ‘white’. I also like to use the trash icon in place of text for my delete buttons. Finally, adjust the column width if necessary to make sure both buttons are displayed properly (use Ctrl+drag for finer adjustments).

Create an event handler for your delete button by double clicking the button in the designer.

  def delete_article_button_click(self, **event_args):
    """This method is called when the button is clicked"""
    pass

Step 2: Confirm the user wants to delete the article

When the delete button is clicked, we want to display a popup asking the user to confirm if they want to delete the article. We do this with a confirmation, which is just an alert with pre-built “Yes” and “No” buttons.

Update your delete_article_button_click function to look like this:

  def delete_article_button_click(self, **event_args):
    # Check that the user does want to delete the selected article
    confirm("Are you sure you want to delete {}?".format(self.item['title']))

This will display a confirmation popup with the article’s title, asking the user if they want to delete the article.

Step 3: Delete the article, or do nothing

We’ll write the function for deleting articles from the Data Table inside a Server Module.

We’re using a Server Module because code in Server Modules can be trusted, and we might want to add authentication or other logic to this delete code. We recommend doing it this way for all CRUD apps.

Add this function to your Server Module:

@anvil.server.callable
def delete_article(article):
  # check that the article being deleted exists in the Data Table
  if app_tables.articles.has_row(article):
    article.delete()
  else:
    raise Exception("Article does not exist")

As with the Update function, we’ve added a security check to ensure that the article actually exists in the Data Table. If not, the server function will raise an exception. Without this check, a malicious user could delete any row from any table by passing it to this function.

We’ll call this server function from our Homepage rather than the ‘ArticleView’ Form. It’s a good idea to keep the CRUD operations on the main Form (our Homepage in this case) where possible.

The delete button is on the ‘ArticleView’ Form, but when it’s clicked, we want to call a function on our Homepage Form. We do this by raising an event on the ArticleView’s parent container.

You can look up any component’s parent container with the .parent attribute. In this case, all our ‘ArticleView’ instances are inside the articles_panel on our HomePage. So we can access articles_panel from within any ‘ArticleView’ on this page, and raise an event on it.

self.parent when called on the ArticleView Form refers to the articles_panel on the Homepage.

self.parent when called on the ArticleView Form refers to the articles_panel on the Homepage.

Next, we’ll set a custom event handler on the articles_panel on our Homepage. Then, we can raise this custom event when the delete button on our ‘ArticleView’ Form is clicked, and catch it on our Homepage.

Go back to your ‘Homepage’ Form, and add the following line to the __init__ method of your Form:

  # Set an event handler on the RepeatingPanel (our 'articles_panel')
  self.articles_panel.set_event_handler('x-delete-article', self.delete_article)

This will call the self.delete_article function on the Homepage when the x-delete-event is raised, so let’s create the self.delete_article function. Add this to your Homepage Form:

  def delete_article(self, article, **event_args):
    # Delete the article
    anvil.server.call('delete_article', article)

We’ll call this function when the delete button on our ‘ArticlesView’ Form is clicked, so go back to your ‘ArticlesView’ Form, and edit your delete_article_button_click to look like this:

  def delete_article_button_click(self, **event_args):
    # Get the user to confirm if they wish to delete the article
    # If they confirm, raise the 'x-delete-article' event on the parent (which is the articles_panel on our Homepage)
    if confirm("Are you sure you want to delete {}?".format(self.item['title'])):
      self.parent.raise_event('x-delete-article', article=self.item)

The delete button on our ‘ArticlesView’ Form will now raise the ‘x-delete-event’ on our articles_panel, which we just configured to call the self.delete_article function on the Homepage. This will call our server function and delete the article.

Step 4: Refresh the list of articles if an article is deleted

The final step is to call the self.refresh_articles() function on the Homepage if an article is deleted.

Update the self.delete_article() on your Homepage to look like this:

def delete_article(self, article, **event_args):
  # Delete the article
  anvil.server.call('delete_article', article)
  # Refresh articles to remove the deleted article from the Homepage
  self.refresh_articles()

Run your app and you’ll see that you can now delete articles from the Data Table!

And that’s it. You’ve just built a working database-backed “CRUD” app in Anvil.

Your news articles aggregator is already live on the internet. Go to Publish App in the Gear Menu gear icon for details.

You can also use the following link to clone the finished app and explore it yourself:

Congratulations!

Congratulations! You’ve built and shipped a database-backed web application!

You also now have a solid foundation in Anvil.

Bonus material: Customise your app

This part is optional! If you’re comfortable with HTML and CSS, we’ll show you how to use these technologies to make fine-grained changes to the appearance of your app. But you don’t need any HTML or CSS knowledge to use Anvil.

Chapter complete

Congratulations, you've completed this chapter!