elektronika/lib/library/multi_selector/controller.dart

144 lines
3.6 KiB
Dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../app/app.dart';
import 'multi_select_action.dart';
import 'multi_select_item.dart';
class MultiSelectController extends GetxController
with StateMixin<List<MultiSelectItem<FilterOption>>>, MultiSelectActions<FilterOption>, ScrollMixin {
// List<FilterOption> initialValues;
// String modelCode;
Timer? _debounce;
FilterModel model;
MultiSelectController(this.model);
RxList<FilterOption> selectedValues = <FilterOption>[].obs;
List<MultiSelectItem<FilterOption>> items = [];
RxString searchKey = ''.obs;
int page = 1;
int itemPerPage = 20;
bool getFirstData = false;
RxBool lastPage = false.obs;
@override
void onInit() {
searchKey.value = '';
debugPrint('model.selectedOptions ${model.selectedOptions}');
this.selectedValues.addAll(model.selectedOptions);
update();
getData();
super.onInit();
}
Future<void> getData() async {
await FilterApi.getOptions(page, itemPerPage, model, searchKey.value).then((result) {
final bool emptyRepositories = result.isEmpty;
if (!getFirstData && emptyRepositories) {
change(null, status: RxStatus.empty());
} else if (getFirstData && emptyRepositories) {
lastPage.value = true;
} else {
getFirstData = true;
// convert data
var newItems = result.map((option) => MultiSelectItem<FilterOption>(option, option.label)).toList();
debugPrint('newItems ${newItems.length}');
for (var item in newItems) {
item.selected = this.selectedValues.where((element) => element.id == item.value.id).isNotEmpty;
items.add(item);
}
// check is last item
if (items.length < itemPerPage) {
lastPage.value = true;
}
change(items, status: RxStatus.success());
}
update();
}, onError: (err) {
change(null, status: RxStatus.error(err.toString()));
});
}
@override
Future<void> onEndScroll() async {
debugPrint('onEndScroll ${lastPage.value}');
if (!lastPage.value) {
page += 1;
await getData();
}
}
@override
Future<void> onTopScroll() async {
debugPrint('onTopScroll');
}
void clearFilter(BuildContext ctx, void Function(List<FilterOption>)? onClear) {
debugPrint('clearFilter');
for (int i = 0; i < items.length; i++) {
if (selectedValues.contains(items[i].value)) {
items[i].selected = false;
}
}
selectedValues.clear();
this.onClearTap(ctx, selectedValues, onClear);
update();
}
Future<void> onSearchChanged(String val) async {
getFirstData = false;
page = 1;
searchKey.value = val;
if (_debounce?.isActive ?? false) _debounce!.cancel();
_debounce = Timer(const Duration(milliseconds: 600), () {
items.clear();
change(items, status: RxStatus.loading());
getData();
update();
});
}
void onListBoxListTileChanged(
MultiSelectItem<FilterOption> item, void Function(List<FilterOption>)? onSelectionChanged, checked) {
debugPrint('onListBoxListTileChanged');
if (checked) {
item.selected = true;
selectedValues.add(item.value);
} else {
item.selected = false;
selectedValues.removeWhere((e) => e.id == item.value.id);
}
selectedValues.refresh();
if (onSelectionChanged != null) {
onSelectionChanged(selectedValues);
}
update();
}
void onConfirmSelection(BuildContext context, void Function(List<FilterOption>) onConfirm) {
onConfirmTap(context, selectedValues, onConfirm);
update();
}
}