From 2e1e06de23fcf17983d3f252a3fb0d70d7d4baf5 Mon Sep 17 00:00:00 2001 From: dankito Date: Wed, 4 Sep 2024 21:48:39 +0200 Subject: [PATCH] if minTextLengthForSearch == 0, showing dropdown when TextField gets focus --- .../ui/forms/AutocompleteTextFieldNew.kt | 55 +++++++++++-------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/forms/AutocompleteTextFieldNew.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/forms/AutocompleteTextFieldNew.kt index fdb27bf..6eeb3e3 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/forms/AutocompleteTextFieldNew.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/forms/AutocompleteTextFieldNew.kt @@ -8,13 +8,12 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close import androidx.compose.runtime.* import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusProperties -import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.focus.* import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.window.PopupProperties +import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.launch import net.codinux.banking.ui.config.Colors @@ -30,13 +29,14 @@ fun AutocompleteTextFieldNew( getItemTitle: ((T) -> String)? = null, dropdownMaxHeight: Dp = 400.dp, leadingIcon: @Composable (() -> Unit)? = null, - fetchSuggestions: (query: String) -> Collection = { emptyList() }, + fetchSuggestions: suspend (query: String) -> Collection = { emptyList() }, suggestionContent: @Composable (T) -> Unit ) { var searchQuery by remember { mutableStateOf("") } var expanded by remember { mutableStateOf(false) } var isLoading by remember { mutableStateOf(false) } var suggestions by remember { mutableStateOf>(emptyList()) } + var suggestionsFetchJob: Job? = null val textFieldFocus = remember { FocusRequester() } val keyboardController = LocalSoftwareKeyboardController.current @@ -45,6 +45,27 @@ fun AutocompleteTextFieldNew( val coroutineScope = rememberCoroutineScope() + fun fetchSuggestionsAsync() { + suggestionsFetchJob?.cancel() + + suggestionsFetchJob = coroutineScope.launch { + isLoading = true + + suggestions = fetchSuggestions(searchQuery) + + isLoading = false + if (expanded == false && suggestions.isNotEmpty()) { + expanded = true + } + + // Delay to ensure menu is fully displayed before requesting focus + delay(100) + textFieldFocus.requestFocus() // Request focus back to TextField + keyboardController?.show() + } + } + + ExposedDropdownMenuBox(expanded, { isExpanded -> expanded = isExpanded }, Modifier.fillMaxWidth()) { OutlinedTextField( value = searchQuery, @@ -54,31 +75,17 @@ fun AutocompleteTextFieldNew( onEnteredTextChanged?.invoke(query) if (query.length >= minTextLengthForSearch) { - isLoading = true - - coroutineScope.launch { - suggestions = fetchSuggestions(query) - - isLoading = false - if (expanded == false) { - expanded = true - } - - // Delay to ensure menu is fully displayed before requesting focus - delay(100) - textFieldFocus.requestFocus() // Request focus back to TextField - keyboardController?.show() // Show keyboard - - delay(1000) - textFieldFocus.requestFocus() - keyboardController?.show() // Show keyboard - } + fetchSuggestionsAsync() } else { suggestions = emptyList() expanded = false } }, - modifier = Modifier.fillMaxWidth().focusRequester(textFieldFocus), + modifier = Modifier.fillMaxWidth().focusRequester(textFieldFocus).onFocusChanged { focusState -> + if (focusState.isFocused && minTextLengthForSearch == 0) { + fetchSuggestionsAsync() + } + }, interactionSource = interactionSource, label = { Text(label) }, maxLines = 1,