diff --git a/src/ipyautoui/custom/editgrid.py b/src/ipyautoui/custom/editgrid.py index 2e057d32..4f9acf34 100644 --- a/src/ipyautoui/custom/editgrid.py +++ b/src/ipyautoui/custom/editgrid.py @@ -58,6 +58,11 @@ # BUG: Reported defects -@jovyan at 9/16/2022, 5:25:13 PM # the selection when filtered issue is creating a problem. # - + +# TODO: Tasks pending completion -@jovyan at 9/22/2022, 9:25:53 PM +# Can BaseForm inherit autoipywidget.AutoObject directly? + + class BaseForm(widgets.VBox): _value = traitlets.Dict() _cls_ui = traitlets.Callable(default_value=None, allow_none=True) @@ -74,7 +79,6 @@ def __init__( revert: typing.Callable = lambda: print("REVERT"), fn_onsave: typing.Callable = lambda: None, ): - self.fn_save = save self.fn_revert = revert self.fn_onsave = fn_onsave @@ -324,7 +328,6 @@ def is_incremental(li): class GridWrapper(DataGrid, traitlets.HasTraits): - _value = traitlets.List() def __init__( @@ -451,7 +454,8 @@ def _check_value(self, value: list): self.li_field_names ): raise Exception( - f"Schema fields and data fields do not match.\nRejected Columns: {set(columns) ^ set(self.li_field_names)}" + "Schema fields and data fields do not match.\nRejected Columns:" + f" {set(columns) ^ set(self.li_field_names)}" ) def _set_titles(self, value: list): @@ -561,36 +565,28 @@ def di_field_to_titles(self): @property def selected_rows(self): - return [{"r1": v["r1"], "r2": v["r2"]} for v in self.selections] + """Get position of rows selected.""" + _selected_rows = set() + for di in self.selections: + r1 = di["r1"] + r2 = di["r2"] + if r1 == r2: + _selected_rows.add(r1) + else: + for i in range(r1, r2 + 1): + _selected_rows.add(i) + return list(_selected_rows) @property - def selected_obj_id(self): - return self.selected_cell_values[ - -1 - ] # Set to -1 as this as ID is last column. Will break if ID moves column! + def get_selected_data(self): + """Get the data selected in the table which is returned as a dataframe.""" + df_tmp = self.get_visible_data() + return df_tmp.iloc[self.selected_rows] @property def selected_keys(self): - self._selected_keys = set() - no_rows_selected = 0 - for di in self.selected_rows: - no_rows_selected += di["r2"] - di["r1"] + 1 - - col_posx = list(self.data.columns).index("Name") - - arr_property_name_posx = (np.arange(no_rows_selected) * 3) + col_posx - - li_property_names_selected = [ - self.selected_cell_values[i] for i in arr_property_name_posx - ] - - self._selected_keys = { - i - for i, v in enumerate(self.value) - if v["Name"] in li_property_names_selected - } - - return self._selected_keys + """Return the keys of the selected rows.""" + return list(self.get_selected_data.index.values) @property def li_field_names(self): @@ -727,7 +723,6 @@ class RowUiCallables(BaseModel): # object and the EditGrid object up-to-date. or maybe GridWrapper # doesn't require a _value trait as it is never used within EditGrid. class EditGrid(widgets.VBox): - _value = traitlets.List() def __init__( @@ -811,7 +806,7 @@ def _init_controls(self): def _update_baseform(self, onchange): if ( - len(self.grid.selected_keys) == 1 + len(self.grid.selected_rows) == 1 and self.baseform.layout.display == "block" ): print(self.di_row_value) @@ -840,7 +835,6 @@ def _edit(self): self.baseform.cls_ui = self.ui_edit try: self._check_one_row_selected() - if len(self.grid.selected_keys) == 0: raise ValueError("you must select a row") self.initial_value = self.di_row_value @@ -860,14 +854,13 @@ def _edit(self): def _copy(self): try: - selected_rows = self.grid.selected_keys - if selected_rows == set(): + if self.grid.selected_keys == set(): self.button_bar.message.value = markdown( " 👇 _Please select a row from the table!_ " ) else: li_values_selected = [ - self.value[i] for i in sorted([i for i in selected_rows]) + self.value[i] for i in sorted([i for i in self.grid.selected_keys]) ] if self.fn_on_copy is not None: li_values_selected = self.fn_on_copy(li_values_selected) @@ -890,16 +883,10 @@ def _copy(self): def _delete(self): try: self._set_toggle_buttons_to_false() - # Delete from data frame. - self.rows_to_delete = [] - if self.grid.selected_rows: - for i in self.grid.selected_rows: - start_row = i["r1"] - end_row = i["r2"] - self.rows_to_delete += [i for i in range(*[start_row, end_row + 1])] - print(f"Row Number: {self.rows_to_delete}") + if self.grid.selected_keys: + print(f"Row Number: {self.grid.selected_keys}") if self.datahandler is not None: - value = [self.value[i] for i in self.rows_to_delete] + value = [self.value[i] for i in self.grid.selected_keys] for v in value: self.datahandler.fn_delete(v) self._reload_all_data() @@ -907,9 +894,9 @@ def _delete(self): self.value = [ value for i, value in enumerate(self.value) - if i not in self.rows_to_delete + if i not in self.grid.selected_keys ] - # ^ Only set for values NOT in self.rows_to_delete + # ^ Only set for values NOT in self.grid.selected_keys self.button_bar.message.value = markdown(" 🗑️ _Deleted Row_ ") else: @@ -920,7 +907,7 @@ def _delete(self): traceback.print_exc() def _check_one_row_selected(self): - if len(self.grid.selected_keys) > 1: + if len(self.grid.selected_rows) > 1: raise Exception( markdown(" 👇 _Please only select ONLY one row from the table!_") ) @@ -1003,10 +990,7 @@ def value(self, value): def di_row_value(self): try: self._check_one_row_selected() # Performing checks to see if only one row is selected - self.selected_row = self.grid.selected_rows[0][ - "r1" - ] # Only one row selected during editing - return self.value[self.selected_row] + return self.value[self.grid.selected_rows[0]] except Exception as e: self.button_bar.message.value = markdown(f"_{e}_") @@ -1015,8 +999,16 @@ def di_row_value(self): if __name__ == "__main__": AUTO_GRID_DEFAULT_VALUE = [ - {"string": "important string", "integer": 1, "floater": 3.14,}, - {"string": "update", "integer": 4, "floater": 3.12344,}, + { + "string": "important string", + "integer": 1, + "floater": 3.14, + }, + { + "string": "update", + "integer": 4, + "floater": 3.12344, + }, {"string": "evening", "integer": 5, "floater": 3.14}, {"string": "morning", "integer": 5, "floater": 3.14}, {"string": "number", "integer": 3, "floater": 3.14}, @@ -1037,7 +1029,8 @@ class TestDataFrameOnly(BaseModel): if __name__ == "__main__": description = markdown( - "The Wonderful Edit Grid Application
Useful for all editing purposes whatever they may be 👍" + "The Wonderful Edit Grid Application
Useful for all editing purposes" + " whatever they may be 👍" ) editgrid = EditGrid( schema=TestDataFrameOnly, description=description, ui_add=None, ui_edit=AutoUi @@ -1061,10 +1054,13 @@ class TestDataFrame(BaseModel): if __name__ == "__main__": description = markdown( - "The Wonderful Edit Grid Application
Useful for all editing purposes whatever they may be 👍" + "The Wonderful Edit Grid Application
Useful for all editing purposes" + " whatever they may be 👍" ) editgrid = EditGrid( schema=TestDataFrame, description=description, ui_add=None, ui_edit=AutoUi ) + editgrid.value = AUTO_GRID_DEFAULT_VALUE display(editgrid) +