What I’m trying to do:
I’m trying to create links dynamically (in code), assign a common link_click event handler, and then in the event handler, “know” which dynamically-created link triggered the click event.
What I’ve tried and what’s not working:
This works (see clone as well), but when I try to pass that event handler arguments that might identify the triggering link, whether I put all that in the init or form_show… if there are arguments in the event handler specification then, the event handler fires every time I add the component.
from ._anvil_designer import Form1Template
from anvil import *
class Form1(Form1Template):
def __init__(self, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)
def form_show(self, **event_args):
data=['Choice 1','Choice 2','Choice 3', 'Choice 4', 'Choice 5']
for company in data:
link = Link(text=company,align='center',tag=company)
link.set_event_handler("click", self.eventHandler(link.tag))
self.add_component(link)
def eventHandler(self, source, **event_args):
print("which code-created link was clicked to display me?")
print(source)
Clone link:
https://anvil.works/build#clone:NBDJDBOBQAEGVJZZ=EOJARFH3MDF32YZN6QHW45OI
Just looking quickly but it seems that you are actually calling the link’s event handler when you are attempting simply pass it as an argument.
Try just using …
link.set_event_handler(“click”, self.eventHandler)
Notice the lack of parentheses when passing the function as an argument.
Yep - that works. However, then when I click a link, in the event handler… how can I know which link triggered the click event?
You can examine the tag attribute from within the callback function.
event_args[‘sender’] is the component that was clicked.
Docs:
1 Like
It’s worth noting that event_args[‘sender’] is the component the event handler was set on. In this example that’ll also be the link that was clicked, but in more complicated setups that might not be the component that was actually clicked.
1 Like
i often change me call signatures when sharing an event handler across different components
data=['Choice 1','Choice 2','Choice 3', 'Choice 4', 'Choice 5']
for company in data:
link = Link(text=company,align='center',tag=company)
link.set_event_handler("click", self.event_handler)
self.add_component(link)
def event_handler(self, sender, **event_args):
# include the sender in the call signature
print("which code-created link was clicked to display me?")
print(sender.tag)
It’s basically the same as using event_args['sender']
but occasionally more convenient.
You can no longer just call event_handler
as a raw function (unless you provide it with a sender as an argument) - which is good if you need sender.tag
.
You can still call it via - self.link_1.raise_event('click')
where self.link_1
will become the sender
3 Likes