Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

methods for robustly retrieving key of selected_cells #340

Open
Tracked by #4
jgunstone opened this issue Sep 27, 2022 · 5 comments
Open
Tracked by #4

methods for robustly retrieving key of selected_cells #340

jgunstone opened this issue Sep 27, 2022 · 5 comments

Comments

@jgunstone
Copy link
Contributor

Is your feature request related to a problem? Please describe.

I have a workflow where users select an ipydatagrid row, press a button to edit the row data (using ipywidgets), and then save the edit back to the grid. Users continually use the column filters to navigate to appropriate rows, and ideally the workflow can work independently of where a filter is applied.

the process i'd like to follow is:

  1. user selects row
  2. user pushes "edit" button, the code uses the ipydatagrid API to retrieve the data from that row
  3. the row data is edited
  4. the users presses "save" and the row is updated

the problem I'm having is with retrieving the row index for a selected row.
the grid.selected_cells method returns the cells, but the row indexes match up with filtered table rather than the un-filtered table

unfiltered:
image

filtered:
image

so grid.selected_cells returns rows == 0 and 1 whereas the keys to look up the data from grid.data or grid._data['data'] is actually 0 and 4

Describe the solution you'd like
it would be great if the the grid.selected_cells method returned the row numbers for the base data rather than the filtered grid (or if there was an additional method for this).

Describe alternatives you've considered
I did have a method where I:

  • got the grid.selected_cells
  • then got the keys of those cells using grid.get_visible_data()

this was a bit hacky, but appeared to work. but then it fell down if sorting was applied...

image

many thanks!

@jgunstone
Copy link
Contributor Author

I noted this as a "feature-request" but i think that the following linked behaviour could be considered a bug...

image

here:

grid.selected_cell_iterator.all_values() returns incorrect values as the SelectionHelper is initiated with self._data whereas the selected_cell_values method is initiates the SelectionHelper with sliced version of the data object

https://github.com/bloomberg/ipydatagrid/blob/f45a84df204137163c1a14607bc6318d21745d9f/ipydatagrid/datagrid.py#L655-L673

@jgunstone
Copy link
Contributor Author

digging a bit deeper - it appears that selections and transforms and mutually exclusive...
i.e. applying a transform will clear any selections

@jgunstone
Copy link
Contributor Author

for my immediate requirement I did something akin to:

class GridWrapper(DataGrid):
    def __init__(df, **kwargs):
        super().__init__(df, **kwargs)

    @property
    def selected_rows_data(self):
        """Get the data selected in the table which is returned as a dataframe."""
        s = self.selected_visible_cell_iterator
        rows = set([l["r"] for l in s])
        return [s._data["data"][r] for r in rows]

    @property
    def selected_keys(self):
        """Return the keys of the selected rows."""
        s = self.selected_visible_cell_iterator
        index = self.get_dataframe_index(self.data)
        rows = set([l["r"] for l in s])
        return [s._data["data"][r][index] for r in rows]

    @property
    def selected_visible_cell_iterator(self):
        """
        An iterator to traverse selected cells one by one.
        Identical to the `selected_cell_iterator` property but the SelectionHelper
        is initiated from the visible data only.
        """
        # Copy of the front-end data model
        view_data = self.get_visible_data()

        # Get primary key from dataframe
        index_key = self.get_dataframe_index(view_data)

        # Serielize to JSON table schema
        view_data_object = self.generate_data_object(view_data, "ipydguuid", index_key)

        return SelectionHelper(view_data_object, self.selections, self.selection_mode)

this way accessing the SelectionHelper with the visible data only (i.e. the transformed grid, self.get_visible_data() .

I'll leave this open as it took me a while (and some digging in the source code) to understand that was what I needed to do. If you think that these methods (or similar) would be a useful addition to the source code I'll happily make a PR, or if I've missed something about how to achieve the desired outcome another way I'm keen to understand it.

many thanks

@ibdafna
Copy link
Member

ibdafna commented Sep 30, 2022

@jgunstone Thank you so much for taking the time to compose and post your findings 🙏. I will be pushing bug fixes and some enhancements in the next couple of weeks, so will definitely get back to you.

@jgunstone
Copy link
Contributor Author

you're most welcome and I'm looking forward to the updates!
(apologies if the above is a little hard to follow, I understood the issue better by the end than I did when I first created the issue!)

many thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants