2025-10-27 01:54:35 +07:00

108 lines
3.7 KiB
Dart

part of 'field.dart';
class CustomerAutocomplete extends StatefulWidget {
final TextEditingController controller;
final Customer? selectedCustomer;
final ValueChanged<Customer?>? onSelected;
const CustomerAutocomplete({
super.key,
required this.controller,
this.selectedCustomer,
this.onSelected,
});
@override
State<CustomerAutocomplete> createState() => _CustomerAutocompleteState();
}
class _CustomerAutocompleteState extends State<CustomerAutocomplete> {
final FocusNode _focusNode = FocusNode();
@override
void initState() {
super.initState();
context.read<CustomerLoaderBloc>().add(CustomerLoaderEvent.fetched());
}
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Pelanggan',
style: AppStyle.lg.copyWith(
color: AppColor.black,
fontWeight: FontWeight.w600,
),
),
const SpaceHeight(6.0),
BlocBuilder<CustomerLoaderBloc, CustomerLoaderState>(
builder: (context, state) {
return RawAutocomplete<Customer>(
textEditingController: widget.controller,
focusNode: _focusNode,
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text.isEmpty) {
return const Iterable<Customer>.empty();
}
return state.customers.where((Customer customer) {
return customer.name.toLowerCase().contains(
textEditingValue.text.toLowerCase(),
);
});
},
displayStringForOption: (Customer option) => option.name,
onSelected: (Customer selection) {
widget.controller.text = selection.name;
if (widget.onSelected != null) {
widget.onSelected!(selection);
}
},
fieldViewBuilder:
(context, controller, focusNode, onFieldSubmitted) {
return TextFormField(
controller: controller,
focusNode: focusNode,
decoration: const InputDecoration(
hintText: 'Nama Pelanggan',
),
onChanged: (value) {
if (widget.onSelected != null) {
widget.onSelected!(null); // reset jika ketik manual
}
},
);
},
optionsViewBuilder: (context, onSelected, options) {
return Material(
elevation: 1,
borderRadius: BorderRadius.circular(8),
color: Colors.white,
child: SizedBox(
height: context.deviceHeight * 0.4,
child: ListView.separated(
padding: EdgeInsets.zero,
itemCount: options.length,
separatorBuilder: (_, __) => const Divider(height: 1),
itemBuilder: (BuildContext context, int index) {
final Customer option = options.elementAt(index);
return ListTile(
title: Text(option.name),
onTap: () {
onSelected(option);
},
);
},
),
),
);
},
);
},
),
],
);
}
}