Find components in the app console

The new beta editor has a nice App Console that allows to interact with the running app. Awesome!!

Unfortunately there is no easy way to find a component by its name (one, two, three, four, …) and it is not easy to find stuff in the form. For example, if you have a main form that loads other forms using HashRouting or in any other way, and there are data grids or repeating panels nested inside each other and yada yada yada, it can be difficult to find what you are looking for.

This little function recursively digs into all the components in the form and returns a list of components that either contain a specific attribute or that have an attribute with a specific value.

For example:

# get the list of components containing a label_1
comps('label_1')

# get the list of components containing a property text with value 'hello'
comps('text', 'hello')

# get the last instance of a component called repeating_panel_1
comps('repeating_panel_1')[-1].repeating_panel_1

# add a rectangle to the first canvas in the form
c = comps('stroke_rect')[0]
c.stroke_rect(2, 2, 10, 10)

# get all Canvas components
comps(class_name='Canvas')

Here is the function:

def comps(property_name='', property_value='@undefined@', class_name='', parent=None):
    components = []
    if not parent:
        parent = get_open_form()
    try:
        children = parent.get_components()
    except AttributeError:
        children = []
    for c in children:
        if property_name:  # search by attribute
            attribute_value = getattr(c, property_name, '@undefined@')
            if attribute_value != '@undefined@' and (property_value == '@undefined@' or property_value == attribute_value):
                components.append(c)
        else:              # search by class name
            if c.__class__.__name__ == class_name:
                components.append(c)
        for c in comps(property_name, property_value, class_name, c):
            components.append(c)
    return components

You can use it by making sure that the app imports it, or by just copying it and pasting it in the App Console, see the red arrow here:

EDIT
Unfortunately this function does not crawl into forms that are displayed as content on an alert().
Any help on this front is welcome.

EDIT 2
I added the parameter class_name that allows to do comps(class_name='Canvas').

6 Likes

In the class_name example, the comment should be # get all Canvas components (not TextAreas), right?

Oops… yes!
Thanks for catching it.
I tried to fix it, but I wasn’t able to edit my own post :frowning:

1 Like