- Creating an event handler for checkbox changes.
- Writing the **update_assessment_completed** function in the **assessment_service** to update the database.
- Testing the implementation by verifying changes in the database.
We can enter assessment details and we can view them. We even have a check box on the AssessmentPanel that allows the user to tick whether they have completed an assessment. Only problem is, this doesn't change the information saved in our Assessment table. let's fix that.
We want Anvil to respond when the check_box_completed is ticked, this will require an event handler. We know from working with buttons and links, that we create event handlers in the Design screen.
We want that handler to take the current value of the check_box_completed and write it to the completed field for the item belonging to that specific panel. Since this happens server-side, we need to create a new function in the assessment_service.
We will start with the code in the AssessmentsPanel, so open it in Design mode.
- Click on the check_box_completed
- Click on change event
- Switch to Code mode
In the check_box_completed_change event handler, replace lines 24 and 25 with the highlighted code.
:linenos:
:lineno-start: 23
:emphasize-lines: 2, 3
def check_box_completed_change(self, **event_args):
new_value = self.check_box_completed.checked
anvil.server.call('update_assessment_completed', self.item.get_id(), new_value)
:class: notice
- **line 24** → takes the current value from **check_box_completed**
- **line 25** → sends that value to the server
- `'update_assessment_completed'` → a function we will have to write
- `self.item.get_id()` → gets the id for the item for this specific panel
- `new_value` → the value we retrieved from **check_box_completed**
Now we have to create the update_assessment_completed function.
Open the update_assessment_completed function in the assessment_service module under the Server Code.
At the bottom of the file add the following code:
:linenos:
:lineno-start: 25
:emphasize-lines: 1 - 5
@anvil.server.callable
def update_assessment_completed(assessment_id, completed):
assessment = app_tables.assessments.get_by_id(assessment_id)
if assessment:
assessment["completed"] = completed
:class: notice
- **line 25** → makes the functional callable by frontend code
- **line 26** → creates the `update_assessment_completed` function which accept 2 arguments:
- `assessment_id` → the unique identifier for the assessment
- `completed` → the completed state (`True` or `False`) of the assessment
- **line 27** → retrieves the row from the **assessment** table that has the passed `assessment_id` and stores it in the **assessment variable**
- **line 28** → checks the truthiness of the **assessment variable**
- if an assessment was retrieved, it will be `True`
- if an assessment wasn't retrieved (ie. doesn't exist), it will be `False`
- **line 29** → changes the **completed** value of the assessment to match the value passed to the function
Now to test your code. Launch your web app.
- Click on the completed checkbox for one of the assessments
- Stop your web app
- Click on the data menu
- In the submenu choose Assessments
- Check to see if the assessment's completed box is now ticked.
By the end of this tutorial your code should be the same as below:
:linenos:
from ._anvil_designer import AssessmentPanelTemplate
from anvil import *
import anvil.server
import anvil.users
import anvil.tables as tables
import anvil.tables.query as q
from anvil.tables import app_tables
import datetime
class AssessmentPanel(AssessmentPanelTemplate):
def __init__(self, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)
# Any code you write here will run before the form opens.
self.check_box_completed.checked = self.item['completed']
self.label_subject.text = self.item['subject']
self.label_details.text = self.item['details']
self.label_start.text = self.item['start_date'].strftime('%d/%m/%Y')
self.label_due.text = self.item['due_date'].strftime('%d/%m/%Y')
def check_box_completed_change(self, **event_args):
new_value = self.check_box_completed.checked
anvil.server.call('update_assessment_completed', self.item.get_id(),new_value)
:linenos:
import anvil.users
import anvil.tables as tables
import anvil.tables.query as q
from anvil.tables import app_tables
import anvil.server
@anvil.server.callable
def add_assessment(subject, details, start_date, due_date):
user = anvil.users.get_user()
app_tables.assessments.add_row(user= user,
subject= subject,
details=details,
start_date=start_date,
due_date=due_date,
completed=False)
@anvil.server.callable
def get_assessment():
user = anvil.users.get_user()
return app_tables.assessments.search(tables.order_by('due_date'),
user=user)
@anvil.server.callable
def update_assessment_completed(assessment_id, completed):
assessment = app_tables.assessments.get_by_id(assessment_id)
if assessment:
assessment["completed"] = completed