How to do CRUD with linked table - Correct way

What I’m trying to do:
New kid in town.
mode = learning.

I am going through DataGrid CRUD Tutorial. and I linked two table, I know it was not it tutorial page. Single table CRUD works fine.

Relation - one client can have multiple contact Number[one to many].

Tables
table name: clients
field name: name (text)

table name: clientno
filed name: contactno (text)
field name: link_clients_name (clients row) → link to [name]

What I’ve tried and what’s not working:

Works
CRUD on clients table works fine.
Getting data from clients table and putting it inside dropdown works fine.

Does Not Work
Adding[tried] to table ‘clientno’

server side

def add_contactno(contactno, link_clients_name):
  app_tables.clientno.add_row(contactno=contactno, link_clients_name=link_clients_name)

client side

    """This method is called when the button is clicked"""
    anvil.server.call(
      'add_contactno',
      contactno=self.text_box_contactno.text,
      link_clients_name=self.drop_down_linktoclient.selected_value,
    )

Clone link:
share a copy of your app

Thanks and Happy Fathers Day to All Fathers

Welcome to the forum!

When you’re adding a row that contains a linked field, you need to give the entire linked row as the value for that field, not just a portion of it. In your case you’re giving it just the client name, not the entire client row.

To fix it, you’d want to use the alternate form for populating the dropdown items where you give each item both a visible value and the real value. See this section of the docs for how to do that: Anvil Docs | Dropdowns and Data Tables

After you’ve done that, when you get the selected value from the dropdown you’ll be getting the entire row, not just the name. From there everything else should work.

okay that worked
but now this code does “invalid value” in dropdown after saving
self.drop_down_linktoclient.selected_value =self.drop_down_linktoclient.items[0]

The selected_value property must be set to a valid value (e.g. the second part of the tuple for an item). You’re setting it to the entire tuple. Something like this should work to pull just the value out of the tuple:

self.drop_down_linktoclient.selected_value =self.drop_down_linktoclient.items[0][1]

how to reset/clear dropdown value to basically none/default

in DataGrid tutorials it does set it to none in dropdown

self.drop_down_linktoclient.selected_value = self.drop_down_linktoclient.items[0][1]

[0][1] does not reset - behavior - 1 value is selected same as not writing that code.

this code does not make it clear/none/default [here not sure what it should e called]

There is no None value in a dropdown by default. If you want there to be a blank value that you can use with a None value, you need to add that to the items list yourself. In your clients module you can do that after you sort the list:

names = sorted(list(names))
names = [('', None), *names]

And then to set the dropdown to that empty placeholder, you can use:

self.drop_down_linktoclient.selected_value = None

If that’s not what you’re trying to do, we’ll need more information on what you want to happen.

2 Likes

‘NoneType’ does not support indexing

may be I am going in wrong direction let me reiterate.

what I am trying to do. After clicking on Add button set value of dropdown to blank.

    # Clear the add row's input components
    self.text_box_employee_add.text = ''
    self.text_box_grade_add.text = 0
    self.drop_down_team_add.selected_value = self.drop_down_team_add.items[0]

this code clears input, I just want to do that.

That has nothing to do with the dropdown. In your clientno data table you have a bad row at the end that has a None value for the linked row. Delete that row so that your data bindings (which expect the linked field to not be None) work.

To get your dropdown to be blank after clicking the add button, uncomment line 19 in your clients module and then use self.drop_down_linktoclient.selected_value = None to clear the dropdown value.

I have done what you have said and it worked. Awesome thanks for support. Now going to build update and delete lets hope it works out. :smile:

@jshaffstall I did update and delete, delete works, same app but when I click on edit button it does present data in single one by one letter

Example instead of showing data like - jane - in dropdown it shows
dropdown>
j
a
n
e

databinding - self.item['link_clients_name']['name']

The dropdown will go through each element of whatever you pass it and create an entry in the dropdown for each element. You’ve set the items property of a dropdown to a string. Each element of the string is a character, so each entry in the dropdown is a single character.

If you want the dropdown to have all the names then you should set it’s items property the same way you did for the outside one, as clients.names. You won’t be able to do that in a data binding, but you can do that in the __init__ of your repeating row template form.

1 Like