Programatic clickable images within links in a flow panel

I have images which are served from aws cloudfront.
I am trying to have undetermined number of images to show up in a gallery.
These images should be clickable to display them in a larger window if needed

**What I’ve tried and what is working:
I was able to display the gallery with links. However the links are not clickable
Code:

    imgs = anvil.server.call('return_gallery', user_id)

    for i in range(len(imgs)):

      self.gallery.add_component(Image(source=URLMedia("https://*******l.cloudfront.net/" + imgs[i])), width=110) 

I also was able to make a smaller clickable gallery in another form using this code:

imgs = anvil.server.call('return_image', user_id, user )
    self.image_1.source = imgs[0]
    self.image_2.source = imgs[1]
    self.image_3.source = imgs[2]
    self.image_4.source = imgs[3]
    self.button_submit.enabled = True
                         
    
  def link_1_click(self, **event_args):
    print("CLICK~")
    """This method is called when the link is clicked"""
    alert(
      Image(source=self.image_1.source, height=512),
      buttons=[('Back', None, None)],
      large=True,
    )

but the second was done within the designer.
in the first code an undetermined amount of images are returned, so I feel like I need to create the links programmatically. I managed to get the images within links within a flow panel to work. But I have failed to make the clickable links.

Any help is very much appreciated as I am stuck with this issue for a while now. I hope I was clear in explaining the issue.

Thank you for your time and help in advance.

Welcome to the forum!

It doesn’t look like you are creating images in links in the first example. You’re creating images and putting them inside self.gallery, which is presumably a flow panel? If you want the images inside a link, you need to explicitly create the link, add the image to it, and then add the link to the flow panel.

Something along the lines of (untested, but enough to get you going):

imgs = anvil.server.call('return_gallery', user_id)

for i in range(len(imgs)):
    link = Link()
    link.add_component(Image(source=URLMedia("https://*******l.cloudfront.net/" + imgs[i])))
    link.set_event_handler('click', self.link_1_click)
    self.gallery.add_component(link, width=110)
2 Likes

Thank you very much!

However, the code you provided gives an error saying “gallery(flow pannel) object has no attrribute ‘self.link_1_click’”

another problem is that if we look at this code:

imgs = anvil.server.call('return_image', user_id, user )
    self.image_1.source = imgs[0]
    self.image_2.source = imgs[1]
    self.image_3.source = imgs[2]
    self.image_4.source = imgs[3]
    self.button_submit.enabled = True
                         
    
  def link_1_click(self, **event_args):
    print("CLICK~")
    """This method is called when the link is clicked"""
    alert(
      Image(source=self.image_1.source, height=512),
      buttons=[('Back', None, None)],
      large=True,
    )

I had to create a function for each link click to have an alert pop up display the full image.
How can I accomplish this while doing everything else programmatically. I am baffled.

That’s the point of the code that is giving the error for you. You need to put the self.link_1_click function into the form that you’re using. Then the line:

link.set_event_handler('click', self.link_1_click)

hooks that function up as the click event handler for the link you programmatically created.

1 Like

You can use mouse_enter, mouse_down, and other event handlers to respond to clicks on images. Take a look at the following example - it uses linear panels to create a carousel:

https://anvil.works/build#clone:XJWQNCSPH7PBXE5S=6E2SLTLPKOWBCWTDFZ3DFJ6O

2 Likes

Thank you both for your suggestions.

I will try both and try to get it to work.

Much appreciated

I figured it out with the help of my friend! thanks to your help as it was immensely helpful.

here is the code which worked for us so hopefully others find it useful too.

    # gets the images in a list
    imgs = anvil.server.call('return_gallery', user_id)
    # gets the first 500
    for image in imgs[0:500]:
      link = Link()
      # height and width are very important, otherwise they have a tendency to be "0px"
      link.add_component(Image(source=URLMedia("https://***********.cloudfront.net/" + image), width=110, height=110))
      # tagged the link so I can reach to it in the following function
      link.tag = "https://**********.cloudfront.net/" + image
      link.set_event_handler('click', self.link_click)
      # gallery is a flow panel
      self.gallery.add_component(link, width=110)
  def link_click(self, **event_args):
    # print("CLICK~")
    # test = event_args['sender'] "this is super interesting, difficult to explain but this is the link which is the sender"
    # print(test.tag)
    """This method is called when the link is clicked"""
    alert(
      Image(source=URLMedia(event_args['sender'].tag), height=512),
      buttons=[('Back', None, None)],
      large=True,
    )
1 Like