Making rows in a DataGrid clickable

I’m trying to make rows in a data grid clickable. I want a user to be able to click a row in the data grid and be taken to an edit form or a details page.

How do I get the row id and how do I pass it to the form?

Regards,

Andrew

Hello and welcome :wave:,

Unfortunately, asking “how do I do X?”, without explaining where you’ve searched and what you’ve tried, is not a great way to ask for help.

My best advice would be to search to docs for “row id” and the other questions you have (passing variables to forms, data grid examples, etc).

I’m certain that there are examples in the docs and on the forum that you will find very helpful.

Unfortunately for clicking a row in a data grid there’s no in built Anvil event to setup (though maybe that would be a good Feature Request :thinking:). However, you can easily set one up yourself with just a few lines of code and jQuery like so in your Repeating Panel Template:

At the top with all your imports import jQuery and anvil.js:

from anvil.js.window import jQuery
import anvil.js

Then register the template’s show event with a function to setup your alert:

  def form_show(self, **event_args):
    """This method is called when the data row panel is shown on the screen"""
    jQuery(anvil.js.get_dom_node(self)).on("click", self.row_click)
    pass
  
  def row_click(self, js_args):
    alert(f"This is an alert from clicking the Row with these column values: {list(self.item.values())}")

For getting the row_id, I’m also not sure, but @campopianoa’s advice is good here :slight_smile:

2 Likes

If you’re using anvil-extras you can achieve something similar to @duncan_richards12 suggestion with:

from anvil_extras import augment

class RowTemplate(RowTemplateTemplate):
    def __init__(self, **properties):
        ...
        augment.set_event_handler(self, 'click', self.row_click)

    def row_click(self, **event_args):
        print("row clicked")
    

Another approach comes from the data grid tutorials:

I think it’s the add widget tutorial.
You create DataRowPanel’s inside the RowTemplate - turning off auto_display_data
And to make the DataRowPanel clickable you can place it inside a Link component - looks like that question was already answered in the forum :wink: :

And then there’s the option of using:

both of which have row click events out of the box.

2 Likes

Weird thing about being a noob at Anvil is I don’t really know the lingo, I haven’t build up the mental model, and I lack the framework knowledge to ask good questions.

Sorry if I offended you.

1 Like

I figured out that if I put something clickable into the RowTemplate then it’s effectively clickable.

Your method is way cooler though.

Oh yeah, of course adding buttons, etc. to a column would work too!

As a side note, I don’t think @campopianoa was angry (though of course I don’t want to speak for him). His response was more giving you advice on steps to a) solve this and other problems on your own with existing resources and b) improve the quality of your questions so that you don’t waste anyone’s (yours and the people answering the question) time trying to figure the question itself out.

He was basically giving you advice that will improve both the quality of experience answering your future questions and the quality of responses you will get as a result. :grin:

You’ll find that most people here on the forum really do want to help, but we also want to cultivate a community that helps each other out with Anvil without wasting people’s time copy pasting the Anvil Docs and Forum :+1:

5 Likes

This was quite helpful for me. Although I needed to follow deeper to determine where I was adding the code snippets, registering and handling the new click handler, and an issue resulting from my original attempts using ‘parent’ failing because of nested controls.

I appreciate it’s an old answer, but it still lands at the top of the list.

Note that my response applies to the part of the answer using the ‘anvil-extras’ solution.

This goes inside the ‘RowTemplate’ sub-module of your form.

from anvil_extras import augment
from anvil import get_open_form

# in the __init__ function add this line
augment.set_event_handler(self, 'click', self.row_click)

# And define the function itself
def row_click(self, **event_args):
    # Fire the event directly to the main open form
    row_data = self.item
    #print(f"Click from RowTemplate2 {row_data['score']}")
    get_open_form().raise_event('x-row-clicked', item=row_data)

You have to register and handle the event in the main form:

	# Registering the even handler in the __init__ for the form
	self.set_event_handler('x-row-clicked', self.handle_row_click)
	
	# Define the function that does the work
	def handle_row_click(self, item, **event_args):
    # 'item' contains the clicked row's data
	    print(f"Parent form received click for: {item['name']}")
	

You might find the anvil-extras messaging module helpful for the events there.

Messaging — Anvil Extras documentation

1 Like

Thanks for that. It certainly looks interesting.

On first glance it almost feels like an application level MQTT service.
That makes me think might be heavier than I need, but that’s not necessarily the case. If it works, I’m all for it!

1 Like