rxkotlinfx-tornadofx-demo icon indicating copy to clipboard operation
rxkotlinfx-tornadofx-demo copied to clipboard

how to use paging and filter data

Open amasahara opened this issue 5 years ago • 0 comments

I try to make an project that get data from databse but my data rather big >10k rows so i want to paging it but don't know how to convert to rxkotlin and improve loading. I try to get data with runAsync for tableview hope you can show me how to do that Here is my code:

 private val danhMucController: DanhMucDVKTController by inject()
private val eventController = EventController()
private var lstDanhMucModel = FXCollections.observableArrayList<DanhMucDVKTModel>()
private var filteredList: FilteredList<DanhMucDVKTModel> by singleAssign()
private var comboboxData = FXCollections.observableArrayList(10, 100, 500)
private val selectedData = SimpleIntegerProperty(10)
private val searchData = SimpleStringProperty()

private var btnXemDanhMuc: Button by singleAssign()
private var btnCapNhatDanhMuc: Button by singleAssign()
private var btnChonFile: Button by singleAssign()

private var table: TableView<DanhMucDVKTModel> by singleAssign()

private var paging: Pagination by singleAssign()

override val root = borderpane {
    center {
        tableview(lstDanhMucModel){
            isEditable = true

            column("STT", DanhMucDVKTModel::STT)
            column("Mã DVKT", DanhMucDVKTModel::maDVKT).makeEditable()
            column("Mã ánh xạ", DanhMucDVKTModel::maAX).makeEditable()

            columnResizePolicy = SmartResize.POLICY

            enableCellEditing()
            regainFocusAfterEdit()

            tableFilter.executeFilter()

            table = this

            onEditCommit {
                //update data
                danhMucController.update(it).subscribe()
            }

            //broadcast selections
            selectionModel.selectedItems.onChangedObservable()
                    .map { it.filterNotNull().toSet() }
                    .subscribe(eventController.selectedDanhMucDVKT)

            eventController.refreshDanhMucDVKT.startWith(Unit)
                    .flatMapSingle {
                        danhMucController.loadAll.toList()
                    }.subscribeBy(
                            onNext = {
                                lstDanhMucModel.clear()
                                table.items.clear()
                                lstDanhMucModel.addAll(it)
                            },
                            onError = {
                                alert(Alert.AlertType.ERROR, "Lỗi lấy dữ liệu", it.message ?: "").show()
                            }
                    )

            filteredList = FilteredList(lstDanhMucModel)
            table.items = filteredList
        }

    }

    bottom {
        hbox {
            combobox(selectedData, comboboxData) {
                hboxConstraints {
                    alignment = Pos.CENTER_LEFT
                }
                selectionModel.selectFirst()
            }
            paging = pagination {
                hboxConstraints {
                    alignment = Pos.CENTER
                }
                pageCount = lstDanhMucModel.size / selectedData.value + 1
                currentPageIndex = 0
                currentPageIndexProperty().addListener { _, _, newValue ->
                    changeTableView(newValue.toInt(), selectedData.value)
                }
            }
        }
    }

    top {
        toolbar {
            addClass(fontSize16px, fontFamily)
            paddingAll = 5.0

            //reload data from database
            btnXemDanhMuc = button("", refreshGlyph) {
                useMaxWidth = true
                tooltip(toolTipReload)
                actionEvents().map { Unit }.subscribe(eventController.refreshDanhMucDVKT)
            }

            //get data from excel
            btnChonFile = button("", uploadGlyph) {
                useMaxWidth = true
                tooltip(toolTipUpload)
                actionEvents().map {
                    danhMucController.loadFromExcel().map { danhMucDVKT ->
                        DanhMucDVKTModel().apply {
                            item = danhMucDVKT
                        }
                    }.observable()
                }.subscribe {
                    if (it.size != 0) {
                        lstDanhMucModel.clear()
                        table.items.clear()
                        lstDanhMucModel.addAll(it)
                        table.selectionModel.clearSelection()
                        table.requestFocus()
                    }
                }
            }

            //save data into database
            btnCapNhatDanhMuc = button("", saveGlyph) {
                useMaxWidth = true
                tooltip(toolTipSaveAs)
                actionEvents().map { Unit }.subscribe(eventController.saveDanhMucDVKT)
            }

            //remove an row
            button("", removeGlyph) {
                useMaxWidth = true
                tooltip(toolTipDelete)

                val keyEvents = table.events(KeyEvent.KEY_PRESSED).filter { it.code == KeyCode.DELETE }
                val buttonEvents = actionEvents()

                Observable.merge(keyEvents, buttonEvents).flatMapSingle {
                    table.selectionModel.selectedItems.toObservable()
                            .map { it.STT.value.toInt() }
                            .toSet()
                }.subscribe(eventController.deleteDanhMucDVKT)
            }

            textfield(searchData)
        }
    }

    lstDanhMucModel.onChange {
        changeTableView(paging.currentPageIndex, selectedData.value)
    }

    selectedData.onChange {
        changeTableView(paging.currentPageIndex, it)
    }

    searchData.onChange { searchValue ->
        filteredList.setPredicate { data ->
            data.tenDVKT.value.toLowerCase().contains(searchValue!!)
        }
        changeTableView(paging.currentPageIndex, selectedData.value)
    }

    searchData.onChange {
        JavaFxObservable.changesOf(searchData).map {
            lstDanhMucModel.filter { data ->
                data.tenDVKT.value.toLowerCase().contains(it.newVal)
            }
        }.subscribe {
            filteredList = FilteredList(it.observable())
        }
    }

    //handler save data into database
    val saveData = eventController.saveDanhMucDVKT
            .map { lstDanhMucModel }
            .flatMapSingle { lstDMDVKT ->
                Alert(Alert.AlertType.CONFIRMATION, "Lựa chọn hình thức lưu dữ liệu",
                        ButtonType("Thêm", ButtonBar.ButtonData.YES),
                        ButtonType("Lưu và xóa", ButtonBar.ButtonData.NO),
                        ButtonType("Bỏ qua", ButtonBar.ButtonData.CANCEL_CLOSE))
                        .toMaybe().toObservable()
                        .flatMap {
                            when {
                                it.buttonData == ButtonBar.ButtonData.YES -> danhMucController.createList(lstDMDVKT).toObservable()
                                it.buttonData == ButtonBar.ButtonData.NO -> {
                                    danhMucController.delete().subscribe()
                                    danhMucController.createList(lstDMDVKT).toObservable()
                                }
                                else -> Observable.empty()
                            }
                        }.toSet()
            }.publish() //publish() to prevent multiple subscriptions triggering alert multiple times
    saveData.subscribe(eventController.savedDanhMucDVKT)
    //add data into database
    eventController.savedDanhMucDVKT
            .map { Unit }
            .subscribe(eventController.refreshDanhMucDVKT)
    saveData.connect()
}

//pagingation when change view private fun changeTableView(index: Int, limit: Int) { val fromIndex = index * limit val toIndex = min(fromIndex + limit, lstDanhMucModel.size)

    val minIndex = min(toIndex, filteredList.size)
    val sortedData = SortedList<DanhMucDVKTModel>(
            FXCollections.observableArrayList(filteredList.subList(min(fromIndex, minIndex), minIndex)))
    sortedData.comparatorProperty().bind(table.comparatorProperty())

    table.items = sortedData

    paging.pageCount = filteredList.size / selectedData.value + 1
}

init {
    //action to delete rows from database
    eventController.deleteDanhMucDVKT.flatMapSingle {
        table.currentSelections.toList().flatMap { deleteItems ->
            when {
                deleteItems.size == 0 -> {
                    Alert(Alert.AlertType.ERROR, "Bạn chưa chọn DVKT cần xóa", ButtonType.OK)
                            .toMaybe().map { 0 }.toObservable().toSet()
                }
                else -> {
                    Alert(Alert.AlertType.WARNING, "Bạn có chắc là muốn xóa ${deleteItems.size} DVKT không?",
                            ButtonType("Có", ButtonBar.ButtonData.YES),
                            ButtonType("Không", ButtonBar.ButtonData.NO)).toMaybe()
                            .filter { it.buttonData == ButtonBar.ButtonData.YES }
                            .flatMapObservable { deleteItems.toObservable() }
                            .flatMapSingle {
                                danhMucController.deleteWhere(it.STT.value.toInt())
                            }.map { deleteItems.first().STT.value.toInt() }
                            .toSet()
                }
            }
        }
    }.subscribe { deletedIds ->
        if (deletedIds.hashCode().absoluteValue != 0) {
            //thực hiện việc xóa dòng dữ liệu trong tableview
            lstDanhMucModel.deleteWhere { it.STT.value.toInt() in deletedIds }
            Alert(Alert.AlertType.INFORMATION, "Xóa dịch vụ kĩ thuật thành công", ButtonType.OK).show()
        }
    }
}

amasahara avatar Aug 14 '19 01:08 amasahara