I am trying to update data in a repeating panel that is linked to a list within a dictionary in a simple object. I am completely lost on how to do this. I can update the values on the client-side, but they do not update the data in the database?
I have tried doing a list update, but have no idea how to extract the index of the current repeating panel item, so it updates the whole simple object field with only the data from the repeating panel, deleting all the other dictionary data outside of that list item.
I want to store the data in a single field such that I don’t have to create a plurality of tables and fields to hold this data, what is the best way to manipulate simple object data within a repeating panel?
It the repeating panel, I am displaying each site from the “sites” list. I recently put the “index” in as a work around to enter the data into the table by using a for loop to search for that particular item within the list then do an update on the whole dictionary before updating the field. Although this works I feel that I over complicating the process?
Yes, the way your information is structured, you should be able to plug it in directly to your Data Grid. The Grid should update the data in-place, i.e., in your SimpleObject. The Anvil folks designed all these parts with that in mind. (Brilliant, guys!)
To make this work, assuming that your SimpleObject is named so:
You should bind (or assign) your Data Grid’s items (list) to so['sites'].
Your RepeatingPanel fields should be bound to item['site_name'], item['address_1'], or whichever fields you actually want visible.
With these settings, the Data Grid (and its Repeating Panel instances) should be able to write the end-user’s edits directly back to the list of dicts that is so['sites'].
Tip: when listing Python constructs here, such as program code, dicts, or lists, you can (should) place ``` on a line by itself, before and after the construct. This displays the actual indentation, which is critical to the meaning of your code.
If you have explicit “Save” and “Cancel” buttons, then I would change this slightly, so that both can work as expected. (This is probably of general interest, so I’ll add it here anyway.)
The key is to use a temporarylist in place of the real one. That way, if the user Cancels, the original remains unchanged.
from copy import deepcopy
self.edit_buffer = deepcopy(so['sites'])
bind the Data Grid to self.edit_buffer instead of directly to so['sites']
On Save, re-assign so['sites'] = self.edit_buffer, and write it back to the database.
from ._anvil_designer import AccountTemplate
from anvil import *
import anvil.server
import anvil.users
import anvil.tables as tables
import anvil.tables.query as q
from anvil.tables import app_tables
class Account(AccountTemplate):
def __init__(self, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)
# Any code you write here will run when the form opens.
from .. import data_cache
self.user = data_cache._user
if not self.user:
user = data_cache.require_user()
self.item = anvil.server.call('get_account_data', self.user)
self.repeating_panel_locations.items = self.item['location_details']['sites']
The data bindings in the main form are set for the repeating panel are as such:
self.item['location_details']['sites']
Here is the code for my repeating panel form, I have the text box for ‘state’ hidden so that I can update it with a dropdown:
from ._anvil_designer import SitesTemplate
from anvil import *
import anvil.server
import anvil.users
import anvil.tables as tables
import anvil.tables.query as q
from anvil.tables import app_tables
from ...lists import states
class Sites(SitesTemplate):
def __init__(self, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)
# Any code you write here will run when the form opens.
self.drop_down_states.items = states
self.drop_down_states.selected_value = self.text_box_state.text
def drop_down_states_change(self, **event_args):
self.text_box_state.text = self.drop_down_states.selected_value
The data bindings on the repeating panel form are set as an example:
self.item['site_name']
Also, after understanding how this should work, I would be interested in knowing how to bind it explicitly with a “SAVE” / “CANCEL” operation.
That’s the recommended method. It lets the Data Grid do so much of the work for you!
Nearly every related example, Tutorial, and bit of documentation from the last two years has used a Data Grid. If my experience is any indication, it should fit your case very well.
Absolutely! Anvil’s Search feature
is right at the top of this page. And it searches not just the documentation, but the examples, tutorials, and the forums!
Please give it a try; you’ll be amazed at the wealth of information available.
Data Grids do have their own Tutorial, and it’s much better than I can do on my own.
It’s hard to give useful help when we have so little to start with!
Your question deserves your starting a new Q&A topic, with a new title, and with pertinent details of the problem, as you’re experiencing it.
When you start that new topic, the Forum will give you a template, to help you pull that information together into a coherent story of the problem. The goal is to get us just enough relevant information to actually help you, with as little effort on your part as can be managed.