KivyMD icon indicating copy to clipboard operation
KivyMD copied to clipboard

Is there a way to delete multiple data from the datatable

Open bobwatcherx opened this issue 1 year ago • 2 comments

I haven't found a way to delete multiple times with the checkbox in the handle_delete_confirm function

from kivymd.app import MDApp
from kivy.metrics import dp
from kivy.uix.screenmanager import Screen
from kivy.uix.scrollview import ScrollView
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.datatables import MDDataTable
from kivymd.uix.button import MDFlatButton
from kivymd.uix.dialog import MDDialog

# Inisialisasi data awal untuk ditampilkan di tabel
data = {
    '1': {'name': 'John', 'age': '25', 'gender': 'Male'},
    '2': {'name': 'Jane', 'age': '30', 'gender': 'Female'}
}


class MainScreen(Screen):
    def __init__(self, **kwargs):
        super(MainScreen, self).__init__(**kwargs)
        # Membuat layout untuk menampilkan tabel
        self.layout = MDBoxLayout()
        # Membuat widget tabel
        self.table = MDDataTable(
            size_hint=(1, 1),
            check=True,
            column_data=[
                ("No.", dp(30)),
                ("Name", dp(30)),
                ("Age", dp(30)),
                ("Gender", dp(30)),
            ],
            row_data=[
                (key, data[key]['name'], data[key]['age'], data[key]['gender'])
                for key in data.keys()
            ],
            sorted_on="No.",
            sorted_order="ASC",
        )
        # Menambahkan widget tabel ke layout
        self.layout.add_widget(self.table)
        # Membungkus layout dengan ScrollView
        scroll_view = ScrollView(do_scroll_x=True)
        scroll_view.add_widget(self.layout)
        # Menambahkan ScrollView ke layar utama
        self.add_widget(scroll_view)

        self.table.bind(on_check_press=self.handle_check_press)
        self.deleted_rows = []

        delete_button = MDFlatButton(text="Delete", on_release=self.handle_delete_press)
        self.layout.add_widget(delete_button)

    # Menangani aksi ketika kotak centang pada tabel ditekan
    def handle_check_press(self, instance_table, current_row):
        '''Called when the check box in the table row is checked.'''

        # Mengupdate data pada dictionary `data`
        row_data = current_row[0]
        if current_row[-1]:
            self.deleted_rows.append(row_data)
        # Jika kotak centang dinonaktifkan, hapus nomor baris dari daftar yang dihapus
        else:
            try:
                self.deleted_rows.remove(row_data)
            except ValueError as e:
                print(e)
            else:
                del data[row_data]
        print(len(self.deleted_rows), self.deleted_rows)

    # Menangani aksi ketika tombol "Delete" ditekan
    def handle_delete_press(self, instance_button):
        if not self.deleted_rows:
            # Tidak ada baris yang dipilih untuk dihapus
            return

        # Membuat dialog konfirmasi sebelum menghapus
        dialog = MDDialog(
            text="Are you sure you want to delete the selected rows?",
            buttons=[
                MDFlatButton(
                    text="Cancel",
                    on_release=lambda *args: dialog.dismiss()
                ),
                MDFlatButton(
                    text="Delete",
                    on_release=lambda *args: self.handle_delete_confirm(dialog)
                ),
            ],
        )
        dialog.open()

    # Menangani aksi konfirmasi untuk menghapus baris
    def handle_delete_confirm(self, dialog):
        for row_data in self.deleted_rows:
            del data[row_data]
            # hapus juga dari self.table.row_data
            self.table.row_data = [row for row in self.table.row_data if row[0] != row_data]
        self.deleted_rows = []

        # Menghapus semua widget dalam tabel
        self.table.clear_widgets()

        # Mengisi ulang tabel dengan data yang diperbarui
        for key, value in data.items():
            row = (key, value['name'], value['age'], value['gender'])
            self.layout.add_widget(self.table)
            
            self.table.add_row(row)

        dialog.dismiss()










class MyApp(MDApp):
    def build(self):
        return MainScreen()


if __name__ == '__main__':
    MyApp().run()

bobwatcherx avatar Apr 24 '23 10:04 bobwatcherx

I succeeded in deleting multiple but the checkbox is still on in the data index of the sequence I deleted. how do i reset all the checkboxes in the table after i managed to delete them

from kivymd.app import MDApp
from kivy.metrics import dp
from kivy.uix.screenmanager import Screen
from kivy.uix.scrollview import ScrollView
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.datatables import MDDataTable
from kivymd.uix.button import MDRaisedButton,MDFlatButton
from kivymd.uix.dialog import MDDialog
from kivymd.uix.snackbar import Snackbar
from kivy.core.window import Window
# Inisialisasi data awal untuk ditampilkan di tabel
data = {
    '1': {'name': 'John', 'age': '25', 'gender': 'Male'},
    '2': {'name': 'Jane', 'age': '30', 'gender': 'Female'},
    '3': {'name': 'miidw', 'age': '30', 'gender': 'Female'},
    '4': {'name': 'koo', 'age': '30', 'gender': 'Female'},
    '5': {'name': 'popop', 'age': '30', 'gender': 'Female'}
}


class MainScreen(Screen):
    def __init__(self, **kwargs):
        super(MainScreen, self).__init__(**kwargs)
        # Membuat layout untuk menampilkan tabel
        self.layout = MDBoxLayout(orientation="vertical",
            padding=20,
            spacing=10,
            )
        # Membuat widget tabel
        self.table = MDDataTable(
            size_hint=(1, None),
            height=dp(500),
            check=True,
            column_data=[
                ("No.", dp(30)),
                ("Name", dp(30)),
                ("Age", dp(30)),
                ("Gender", dp(30)),
            ],
            row_data=[
                (key, data[key]['name'], data[key]['age'], data[key]['gender'])
                for key in data.keys()
            ],
            sorted_on="No.",
            sorted_order="ASC",
        )
        # Menambahkan widget tabel ke layout
        self.layout.add_widget(self.table)
        # Membungkus layout dengan ScrollView
        scroll_view = ScrollView(do_scroll_x=True)
        scroll_view.add_widget(self.layout)
        # Menambahkan ScrollView ke layar utama
        self.add_widget(scroll_view)

        self.table.bind(on_check_press=self.handle_check_press)
        self.deleted_rows = []

        delete_button = MDRaisedButton(text="Delete",
            md_bg_color="red",
         on_release=self.handle_delete_press)
        self.layout.add_widget(delete_button)

    # Menangani aksi ketika kotak centang pada tabel ditekan
    def handle_check_press(self, instance_table, current_row):
        '''Called when the check box in the table row is checked.'''

        # Mengupdate data pada dictionary `data`
        row_data = current_row[0]
        if current_row[-1]:
            self.deleted_rows.append(row_data)
        # Jika kotak centang dinonaktifkan, hapus nomor baris dari daftar yang dihapus
        else:
            try:
                self.deleted_rows.remove(row_data)
            except ValueError as e:
                print(e)
            else:
                del data[row_data]
        print(len(self.deleted_rows), self.deleted_rows)

    # Menangani aksi ketika tombol "Delete" ditekan
    def handle_delete_press(self, instance_button):
        if not self.deleted_rows:
            # Tidak ada baris yang dipilih untuk dihapus
            return

        # Membuat dialog konfirmasi sebelum menghapus
        dialog = MDDialog(
            text="Are you sure you want to delete the selected rows?",
            buttons=[
                MDFlatButton(
                    text="Cancel",
                    on_release=lambda *args: dialog.dismiss()
                ),
                MDFlatButton(
                    text="Delete",
                    on_release=lambda *args: self.handle_delete_confirm(dialog)
                ),
            ],
        )
        dialog.open()

    # Menangani aksi konfirmasi untuk menghapus baris
    def handle_delete_confirm(self, dialog):
        for row_data in self.deleted_rows:
            # uncheck checkbox pada baris data yang akan dihapus
            # self.table.checkbox_dict[row_data].active = False
            
            # hapus baris data dari tabel
            del data[row_data]
            if self.table.row_data:
                self.table.row_data = [row for row in self.table.row_data if row[0] != row_data]
            else:
                self.table.row_data = []
                
        self.deleted_rows = []
        
        # reset status checkbox menjadi tidak tercentang untuk semua baris data di tabel
        # self.table.update_checkbox([False] * len(self.table.row_data))
        
        dialog.dismiss()
        Snackbar(text="Success Remove From table",
                 pos_hint={"top":1}, 
                 snackbar_y="10dp",
                 bg_color=(1, 0, 0, 1)).open()












class MyApp(MDApp):
    def build(self):
        return MainScreen()


if __name__ == '__main__':
    MyApp().run()

bobwatcherx avatar Apr 24 '23 10:04 bobwatcherx

@bobwatcherx we you able to fix that I am facing same kind of issue internal states of checkbox is not being updated

ghoshben avatar May 17 '23 17:05 ghoshben