From 1f50e29aa695f7521825996651549751ed7ceeec Mon Sep 17 00:00:00 2001 From: Xavier Molloy Date: Fri, 2 Feb 2024 11:03:36 +0100 Subject: [PATCH 1/3] fix: [ANDROAPP-5900] adapt Input providers to new TextFieldValue usage --- .../providers/InputFieldsProvider.kt | 21 ++-- .../ui/provider/inputfield/DateProvider.kt | 21 ++-- .../ui/provider/inputfield/FieldProvider.kt | 95 ++++++++++--------- .../InputsForTextValueTypeProvider.kt | 33 +++---- .../inputfield/UnitIntervalInputProvider.kt | 9 +- 5 files changed, 95 insertions(+), 84 deletions(-) diff --git a/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/providers/InputFieldsProvider.kt b/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/providers/InputFieldsProvider.kt index dbbc2040ee..e18437e62a 100644 --- a/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/providers/InputFieldsProvider.kt +++ b/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/providers/InputFieldsProvider.kt @@ -9,6 +9,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag +import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.unit.dp import org.dhis2.R import org.dhis2.commons.resources.ResourceManager @@ -52,7 +53,11 @@ fun ProvideInputDate( if (uiModel.showField) { Spacer(modifier = Modifier.height(16.dp)) var value by remember(uiModel.eventDate.dateValue) { - mutableStateOf(uiModel.eventDate.dateValue?.let { formatStoredDateToUI(it) }) + if (uiModel.eventDate.dateValue != null) { + mutableStateOf(TextFieldValue(formatStoredDateToUI(uiModel.eventDate.dateValue) ?: "")) + } else { + mutableStateOf(TextFieldValue()) + } } var state by remember { @@ -62,25 +67,21 @@ fun ProvideInputDate( InputDateTime( title = uiModel.eventDate.label ?: "", allowsManualInput = uiModel.allowsManualInput, - value = value, + inputTextFieldValue = value, actionIconType = DateTimeActionIconType.DATE, onActionClicked = uiModel.onDateClick, state = state, visualTransformation = DateTransformation(), onValueChanged = { value = it - state = getInputShellStateBasedOnValue(it) - manageActionBasedOnValue(uiModel, it) + state = getInputShellStateBasedOnValue(it.text) + manageActionBasedOnValue(uiModel, it.text) }, isRequired = uiModel.required, modifier = modifier.testTag(INPUT_EVENT_INITIAL_DATE), onFocusChanged = { focused -> - if (!focused) { - value?.let { - if (!isValid(it)) { - state = InputShellState.ERROR - } - } + if (!focused && !isValid(value.text)) { + state = InputShellState.ERROR } }, ) diff --git a/form/src/main/java/org/dhis2/form/ui/provider/inputfield/DateProvider.kt b/form/src/main/java/org/dhis2/form/ui/provider/inputfield/DateProvider.kt index 2d79a341e3..36994889c9 100644 --- a/form/src/main/java/org/dhis2/form/ui/provider/inputfield/DateProvider.kt +++ b/form/src/main/java/org/dhis2/form/ui/provider/inputfield/DateProvider.kt @@ -8,6 +8,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.text.input.TextFieldValue import org.dhis2.commons.date.DateUtils import org.dhis2.commons.extensions.toDate import org.dhis2.form.extensions.inputState @@ -38,12 +39,18 @@ fun ProvideInputDate( } var value by remember(fieldUiModel.value) { - mutableStateOf(fieldUiModel.value?.let { formatStoredDateToUI(it, fieldUiModel.valueType) }) + mutableStateOf( + if (fieldUiModel.value != null) { + TextFieldValue(formatStoredDateToUI(fieldUiModel.value!!, fieldUiModel.valueType)) + } else { + TextFieldValue() + }, + ) } InputDateTime( title = fieldUiModel.label, - value = value, + inputTextFieldValue = value, actionIconType = actionType, onActionClicked = { when (actionType) { @@ -51,7 +58,7 @@ fun ProvideInputDate( RecyclerViewUiEvents.OpenCustomCalendar( uid = fieldUiModel.uid, label = fieldUiModel.label, - date = value?.toDate(), + date = value.text.toDate(), allowFutureDates = fieldUiModel.allowFutureDates ?: true, isDateTime = false, ), @@ -61,7 +68,7 @@ fun ProvideInputDate( RecyclerViewUiEvents.OpenTimePicker( uid = fieldUiModel.uid, label = fieldUiModel.label, - date = formatUIDateToStored(value, fieldUiModel.valueType)?.let { + date = formatUIDateToStored(value.text, fieldUiModel.valueType)?.let { DateUtils.timeFormat().parse(it) }, isDateTime = false, @@ -72,7 +79,7 @@ fun ProvideInputDate( RecyclerViewUiEvents.OpenCustomCalendar( uid = fieldUiModel.uid, label = fieldUiModel.label, - date = formatUIDateToStored(value, fieldUiModel.valueType)?.let { + date = formatUIDateToStored(value.text, fieldUiModel.valueType)?.let { DateUtils.databaseDateFormatNoSeconds().parse(it) }, allowFutureDates = fieldUiModel.allowFutureDates ?: true, @@ -81,7 +88,7 @@ fun ProvideInputDate( ) } }, - modifier = modifier.semantics { contentDescription = formatStoredDateToUI(value ?: "", fieldUiModel.valueType) }, + modifier = modifier.semantics { contentDescription = formatStoredDateToUI(value.text, fieldUiModel.valueType) }, state = fieldUiModel.inputState(), legendData = fieldUiModel.legend(), supportingText = fieldUiModel.supportingText(), @@ -94,7 +101,7 @@ fun ProvideInputDate( intentHandler.invoke( FormIntent.OnTextChange( uid = fieldUiModel.uid, - value = formatUIDateToStored(it, fieldUiModel.valueType), + value = formatUIDateToStored(it.text, fieldUiModel.valueType), valueType = fieldUiModel.valueType, allowFutureDates = fieldUiModel.allowFutureDates ?: true, ), diff --git a/form/src/main/java/org/dhis2/form/ui/provider/inputfield/FieldProvider.kt b/form/src/main/java/org/dhis2/form/ui/provider/inputfield/FieldProvider.kt index 8039db46dc..dd56aecfe4 100644 --- a/form/src/main/java/org/dhis2/form/ui/provider/inputfield/FieldProvider.kt +++ b/form/src/main/java/org/dhis2/form/ui/provider/inputfield/FieldProvider.kt @@ -24,6 +24,7 @@ import androidx.compose.ui.geometry.Size import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.TextFieldValue import kotlinx.coroutines.launch import org.dhis2.commons.resources.ResourceManager import org.dhis2.form.extensions.autocompleteList @@ -448,7 +449,7 @@ private fun ProvideIntegerPositive( onNextClicked: () -> Unit, ) { var value by remember(fieldUiModel.value) { - mutableStateOf(fieldUiModel.value) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) } InputPositiveInteger( @@ -457,15 +458,15 @@ private fun ProvideIntegerPositive( state = fieldUiModel.inputState(), supportingText = fieldUiModel.supportingText(), legendData = fieldUiModel.legend(), - inputText = value ?: "", + inputTextFieldValue = value, isRequiredField = fieldUiModel.mandatory, onNextClicked = onNextClicked, onValueChanged = { - value = it + value = it ?: TextFieldValue() intentHandler( FormIntent.OnTextChange( fieldUiModel.uid, - value, + value.text, fieldUiModel.valueType, ), ) @@ -487,7 +488,7 @@ private fun ProvideIntegerPositiveOrZero( ) { var value by remember(fieldUiModel.value) { - mutableStateOf(fieldUiModel.value) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) } InputPositiveIntegerOrZero( @@ -496,15 +497,15 @@ private fun ProvideIntegerPositiveOrZero( state = fieldUiModel.inputState(), supportingText = fieldUiModel.supportingText(), legendData = fieldUiModel.legend(), - inputText = value ?: "", + inputTextFieldValue = value, isRequiredField = fieldUiModel.mandatory, onNextClicked = onNextClicked, onValueChanged = { - value = it + value = it ?: TextFieldValue() intentHandler( FormIntent.OnTextChange( fieldUiModel.uid, - value, + value.text, fieldUiModel.valueType, ), ) @@ -526,7 +527,7 @@ private fun ProvidePercentage( ) { var value by remember(fieldUiModel.value) { - mutableStateOf(fieldUiModel.value) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) } InputPercentage( @@ -535,15 +536,15 @@ private fun ProvidePercentage( state = fieldUiModel.inputState(), supportingText = fieldUiModel.supportingText(), legendData = fieldUiModel.legend(), - inputText = value ?: "", + inputTextFieldValue = value, isRequiredField = fieldUiModel.mandatory, onNextClicked = onNextClicked, onValueChanged = { - value = it + value = it ?: TextFieldValue() intentHandler( FormIntent.OnTextChange( fieldUiModel.uid, - value, + value.text, fieldUiModel.valueType, ), ) @@ -565,7 +566,7 @@ private fun ProvideNumber( ) { var value by remember(fieldUiModel.value) { - mutableStateOf(fieldUiModel.value) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) } InputNumber( @@ -574,15 +575,15 @@ private fun ProvideNumber( state = fieldUiModel.inputState(), supportingText = fieldUiModel.supportingText(), legendData = fieldUiModel.legend(), - inputText = value ?: "", + inputTextFieldValue = value, isRequiredField = fieldUiModel.mandatory, onNextClicked = onNextClicked, onValueChanged = { - value = it + value = it ?: TextFieldValue() intentHandler( FormIntent.OnTextChange( fieldUiModel.uid, - value, + value.text, fieldUiModel.valueType, ), ) @@ -605,7 +606,7 @@ private fun ProvideIntegerNegative( ) { var value by remember(fieldUiModel.value) { - mutableStateOf(fieldUiModel.value?.replace("-", "")) + mutableStateOf(TextFieldValue(fieldUiModel.value?.replace("-", "") ?: "")) } InputNegativeInteger( @@ -614,15 +615,15 @@ private fun ProvideIntegerNegative( state = fieldUiModel.inputState(), supportingText = fieldUiModel.supportingText(), legendData = fieldUiModel.legend(), - inputText = value ?: "", + inputTextFieldValue = value, isRequiredField = fieldUiModel.mandatory, onNextClicked = onNextClicked, onValueChanged = { - value = it + value = it ?: TextFieldValue() intentHandler( FormIntent.OnTextChange( fieldUiModel.uid, - value, + value.text, fieldUiModel.valueType, ), ) @@ -644,7 +645,7 @@ private fun ProvideLongText( ) { var value by remember(fieldUiModel.value) { - mutableStateOf(fieldUiModel.value) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) } InputLongText( @@ -653,15 +654,15 @@ private fun ProvideLongText( state = fieldUiModel.inputState(), supportingText = fieldUiModel.supportingText(), legendData = fieldUiModel.legend(), - inputText = value ?: "", + inputTextFieldValue = value, isRequiredField = fieldUiModel.mandatory, onNextClicked = onNextClicked, onValueChanged = { - value = it + value = it ?: TextFieldValue() intentHandler( FormIntent.OnTextChange( fieldUiModel.uid, - value, + value.text, fieldUiModel.valueType, ), ) @@ -684,7 +685,7 @@ private fun ProvideLetter( ) { var value by remember(fieldUiModel.value) { - mutableStateOf(fieldUiModel.value) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) } InputLetter( @@ -693,15 +694,15 @@ private fun ProvideLetter( state = fieldUiModel.inputState(), supportingText = fieldUiModel.supportingText(), legendData = fieldUiModel.legend(), - inputText = value ?: "", + inputTextFieldValue = value, isRequiredField = fieldUiModel.mandatory, onNextClicked = onNextClicked, onValueChanged = { - value = it + value = it ?: TextFieldValue() intentHandler( FormIntent.OnTextChange( fieldUiModel.uid, - value, + value.text, fieldUiModel.valueType, ), ) @@ -723,7 +724,7 @@ private fun ProvideInteger( ) { var value by remember(fieldUiModel.value) { - mutableStateOf(fieldUiModel.value) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) } InputInteger( @@ -732,15 +733,15 @@ private fun ProvideInteger( state = fieldUiModel.inputState(), supportingText = fieldUiModel.supportingText(), legendData = fieldUiModel.legend(), - inputText = value ?: "", + inputTextFieldValue = value, isRequiredField = fieldUiModel.mandatory, onNextClicked = onNextClicked, onValueChanged = { - value = it + value = it ?: TextFieldValue() intentHandler( FormIntent.OnTextChange( fieldUiModel.uid, - value, + value.text, fieldUiModel.valueType, ), ) @@ -762,7 +763,7 @@ private fun ProvideEmail( onNextClicked: () -> Unit, ) { var value by remember(fieldUiModel.value) { - mutableStateOf(fieldUiModel.value) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) } InputEmail( @@ -771,15 +772,15 @@ private fun ProvideEmail( state = fieldUiModel.inputState(), supportingText = fieldUiModel.supportingText(), legendData = fieldUiModel.legend(), - inputText = value ?: "", + inputTextFieldValue = value, isRequiredField = fieldUiModel.mandatory, onNextClicked = onNextClicked, onValueChanged = { - value = it + value = it ?: TextFieldValue() intentHandler( FormIntent.OnTextChange( fieldUiModel.uid, - value, + value.text, fieldUiModel.valueType, ), ) @@ -788,7 +789,7 @@ private fun ProvideEmail( uiEventHandler.invoke( RecyclerViewUiEvents.OpenChooserIntent( Intent.ACTION_SENDTO, - value, + value.text, fieldUiModel.uid, ), ) @@ -811,7 +812,7 @@ private fun ProvideInputPhoneNumber( ) { var value by remember(fieldUiModel.value) { - mutableStateOf(fieldUiModel.value) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) } InputPhoneNumber( @@ -820,15 +821,15 @@ private fun ProvideInputPhoneNumber( state = fieldUiModel.inputState(), supportingText = fieldUiModel.supportingText(), legendData = fieldUiModel.legend(), - inputText = value ?: "", + inputTextFieldValue = value, isRequiredField = fieldUiModel.mandatory, onNextClicked = onNextClicked, onValueChanged = { - value = it + value = it ?: TextFieldValue() intentHandler( FormIntent.OnTextChange( fieldUiModel.uid, - value, + value.text, fieldUiModel.valueType, ), ) @@ -837,7 +838,7 @@ private fun ProvideInputPhoneNumber( uiEventHandler.invoke( RecyclerViewUiEvents.OpenChooserIntent( Intent.ACTION_DIAL, - value, + value.text, fieldUiModel.uid, ), ) @@ -860,7 +861,7 @@ private fun ProvideInputLink( ) { var value by remember(fieldUiModel.value) { - mutableStateOf(fieldUiModel.value) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) } InputLink( @@ -869,15 +870,15 @@ private fun ProvideInputLink( state = fieldUiModel.inputState(), supportingText = fieldUiModel.supportingText(), legendData = fieldUiModel.legend(), - inputText = value ?: "", + inputTextFieldValue = value, isRequiredField = fieldUiModel.mandatory, onNextClicked = onNextClicked, onValueChanged = { - value = it + value = it ?: TextFieldValue() intentHandler( FormIntent.OnTextChange( fieldUiModel.uid, - value, + value.text, fieldUiModel.valueType, ), ) @@ -886,7 +887,7 @@ private fun ProvideInputLink( uiEventHandler.invoke( RecyclerViewUiEvents.OpenChooserIntent( Intent.ACTION_VIEW, - value, + value.text, fieldUiModel.uid, ), ) diff --git a/form/src/main/java/org/dhis2/form/ui/provider/inputfield/InputsForTextValueTypeProvider.kt b/form/src/main/java/org/dhis2/form/ui/provider/inputfield/InputsForTextValueTypeProvider.kt index e51321a7bb..4b52d9cb97 100644 --- a/form/src/main/java/org/dhis2/form/ui/provider/inputfield/InputsForTextValueTypeProvider.kt +++ b/form/src/main/java/org/dhis2/form/ui/provider/inputfield/InputsForTextValueTypeProvider.kt @@ -8,6 +8,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusManager +import androidx.compose.ui.text.input.TextFieldValue import org.dhis2.form.extensions.autocompleteList import org.dhis2.form.extensions.inputState import org.dhis2.form.extensions.legend @@ -72,7 +73,7 @@ private fun ProvideQRInput( onNextClicked: () -> Unit, ) { var value by remember(fieldUiModel.value) { - mutableStateOf(fieldUiModel.value) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) } InputQRCode( @@ -81,21 +82,21 @@ private fun ProvideQRInput( state = fieldUiModel.inputState(), supportingText = fieldUiModel.supportingText(), legendData = fieldUiModel.legend(), - inputText = value ?: "", + inputTextFieldValue = value, isRequiredField = fieldUiModel.mandatory, onNextClicked = onNextClicked, onValueChanged = { - value = it + value = it ?: TextFieldValue() intentHandler( FormIntent.OnTextChange( fieldUiModel.uid, - value, + value.text, fieldUiModel.valueType, ), ) }, onQRButtonClicked = { - if (value.isNullOrEmpty()) { + if (value.text.isEmpty()) { uiEventHandler.invoke( RecyclerViewUiEvents.ScanQRCode( fieldUiModel.uid, @@ -108,7 +109,7 @@ private fun ProvideQRInput( RecyclerViewUiEvents.DisplayQRCode( fieldUiModel.uid, optionSet = fieldUiModel.optionSet, - value = value!!, + value = value.text, renderingType = fieldUiModel.renderingType, editable = fieldUiModel.editable, label = fieldUiModel.label, @@ -132,7 +133,7 @@ private fun ProvideDefaultTextInput( onNextClicked: () -> Unit, ) { var value by remember(fieldUiModel.value) { - mutableStateOf(fieldUiModel.value) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) } InputText( modifier = modifier.fillMaxWidth(), @@ -140,15 +141,15 @@ private fun ProvideDefaultTextInput( state = fieldUiModel.inputState(), supportingText = fieldUiModel.supportingText(), legendData = fieldUiModel.legend(), - inputText = value ?: "", + inputTextFieldValue = value, isRequiredField = fieldUiModel.mandatory, onNextClicked = onNextClicked, onValueChanged = { - value = it + value = it ?: TextFieldValue() intentHandler( FormIntent.OnTextChange( fieldUiModel.uid, - value, + value.text, fieldUiModel.valueType, ), ) @@ -170,7 +171,7 @@ private fun ProvideBarcodeInput( onNextClicked: () -> Unit, ) { var value by remember(fieldUiModel.value) { - mutableStateOf(fieldUiModel.value) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) } InputBarCode( @@ -179,21 +180,21 @@ private fun ProvideBarcodeInput( state = fieldUiModel.inputState(), supportingText = fieldUiModel.supportingText(), legendData = fieldUiModel.legend(), - inputText = value ?: "", + inputTextFieldValue = value, isRequiredField = fieldUiModel.mandatory, onNextClicked = onNextClicked, onValueChanged = { - value = it + value = it ?: TextFieldValue() intentHandler( FormIntent.OnTextChange( fieldUiModel.uid, - value, + value.text, fieldUiModel.valueType, ), ) }, onActionButtonClicked = { - if (value.isNullOrEmpty()) { + if (value.text.isEmpty()) { uiEventHandler.invoke( RecyclerViewUiEvents.ScanQRCode( fieldUiModel.uid, @@ -206,7 +207,7 @@ private fun ProvideBarcodeInput( RecyclerViewUiEvents.DisplayQRCode( fieldUiModel.uid, optionSet = fieldUiModel.optionSet, - value = value!!, + value = value.text, renderingType = fieldUiModel.renderingType, editable = fieldUiModel.editable, label = fieldUiModel.label, diff --git a/form/src/main/java/org/dhis2/form/ui/provider/inputfield/UnitIntervalInputProvider.kt b/form/src/main/java/org/dhis2/form/ui/provider/inputfield/UnitIntervalInputProvider.kt index 9c4558ae90..8f033dca80 100644 --- a/form/src/main/java/org/dhis2/form/ui/provider/inputfield/UnitIntervalInputProvider.kt +++ b/form/src/main/java/org/dhis2/form/ui/provider/inputfield/UnitIntervalInputProvider.kt @@ -7,6 +7,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.text.input.TextFieldValue import org.dhis2.form.extensions.inputState import org.dhis2.form.extensions.legend import org.dhis2.form.extensions.supportingText @@ -22,7 +23,7 @@ fun ProvideUnitIntervalInput( onNextClicked: () -> Unit, ) { var value by remember(fieldUiModel.value) { - mutableStateOf(fieldUiModel.value) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) } InputUnitInterval( modifier = modifier.fillMaxWidth(), @@ -30,15 +31,15 @@ fun ProvideUnitIntervalInput( state = fieldUiModel.inputState(), supportingText = fieldUiModel.supportingText(), legendData = fieldUiModel.legend(), - inputText = value ?: "", + inputTextFieldValue = value, isRequiredField = fieldUiModel.mandatory, onNextClicked = onNextClicked, onValueChanged = { - value = it + value = it ?: TextFieldValue() intentHandler( FormIntent.OnTextChange( fieldUiModel.uid, - value, + value.text, fieldUiModel.valueType, ), ) From be69d70c1e9c23caf1fdfa59c2047fe46c2469c6 Mon Sep 17 00:00:00 2001 From: Xavier Molloy Date: Tue, 6 Feb 2024 08:45:16 +0100 Subject: [PATCH 2/3] fix: [ANDROAPP-5900] update mobile ui 0.2-20240206.071329-16 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5173b968ea..b7e71c8cfa 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,7 +10,7 @@ kotlin = '1.9.21' hilt = '2.47' hiltCompiler = '1.0.0' jacoco = '0.8.10' -designSystem = "0.2-20240123.112704-7" +designSystem = "0.2-20240206.071329-16" dhis2sdk = "1.10.0-20240119.100209-6" ruleEngine = "2.1.9" appcompat = "1.6.1" From 84aab558f677fcf5abd767698415df7fa4503e70 Mon Sep 17 00:00:00 2001 From: Xavier Molloy Date: Tue, 6 Feb 2024 12:21:42 +0100 Subject: [PATCH 3/3] fix: [ANDROAPP-5900] set initial selection to value length --- .../providers/InputFieldsProvider.kt | 5 ++- .../ui/provider/inputfield/DateProvider.kt | 4 +- .../ui/provider/inputfield/FieldProvider.kt | 42 ++++++++++++++----- .../InputsForTextValueTypeProvider.kt | 8 +++- .../inputfield/UnitIntervalInputProvider.kt | 5 ++- 5 files changed, 48 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/providers/InputFieldsProvider.kt b/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/providers/InputFieldsProvider.kt index e18437e62a..4dd1678f0e 100644 --- a/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/providers/InputFieldsProvider.kt +++ b/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/providers/InputFieldsProvider.kt @@ -9,6 +9,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag +import androidx.compose.ui.text.TextRange import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.unit.dp import org.dhis2.R @@ -52,9 +53,11 @@ fun ProvideInputDate( ) { if (uiModel.showField) { Spacer(modifier = Modifier.height(16.dp)) + val textSelection = TextRange(if (uiModel.eventDate.dateValue != null) uiModel.eventDate.dateValue.length else 0) + var value by remember(uiModel.eventDate.dateValue) { if (uiModel.eventDate.dateValue != null) { - mutableStateOf(TextFieldValue(formatStoredDateToUI(uiModel.eventDate.dateValue) ?: "")) + mutableStateOf(TextFieldValue(formatStoredDateToUI(uiModel.eventDate.dateValue) ?: "", textSelection)) } else { mutableStateOf(TextFieldValue()) } diff --git a/form/src/main/java/org/dhis2/form/ui/provider/inputfield/DateProvider.kt b/form/src/main/java/org/dhis2/form/ui/provider/inputfield/DateProvider.kt index 36994889c9..3083b5dfc3 100644 --- a/form/src/main/java/org/dhis2/form/ui/provider/inputfield/DateProvider.kt +++ b/form/src/main/java/org/dhis2/form/ui/provider/inputfield/DateProvider.kt @@ -8,6 +8,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.text.TextRange import androidx.compose.ui.text.input.TextFieldValue import org.dhis2.commons.date.DateUtils import org.dhis2.commons.extensions.toDate @@ -37,11 +38,12 @@ fun ProvideInputDate( ValueType.TIME -> DateTimeActionIconType.TIME to TimeTransformation() else -> DateTimeActionIconType.DATE to DateTransformation() } + val textSelection = TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0) var value by remember(fieldUiModel.value) { mutableStateOf( if (fieldUiModel.value != null) { - TextFieldValue(formatStoredDateToUI(fieldUiModel.value!!, fieldUiModel.valueType)) + TextFieldValue(formatStoredDateToUI(fieldUiModel.value!!, fieldUiModel.valueType), textSelection) } else { TextFieldValue() }, diff --git a/form/src/main/java/org/dhis2/form/ui/provider/inputfield/FieldProvider.kt b/form/src/main/java/org/dhis2/form/ui/provider/inputfield/FieldProvider.kt index dd56aecfe4..625a51a7e5 100644 --- a/form/src/main/java/org/dhis2/form/ui/provider/inputfield/FieldProvider.kt +++ b/form/src/main/java/org/dhis2/form/ui/provider/inputfield/FieldProvider.kt @@ -23,6 +23,7 @@ import androidx.compose.ui.geometry.Rect import androidx.compose.ui.geometry.Size import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.TextRange import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.TextFieldValue import kotlinx.coroutines.launch @@ -448,8 +449,10 @@ private fun ProvideIntegerPositive( focusManager: FocusManager, onNextClicked: () -> Unit, ) { + val textSelection = TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0) + var value by remember(fieldUiModel.value) { - mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection)) } InputPositiveInteger( @@ -487,8 +490,10 @@ private fun ProvideIntegerPositiveOrZero( onNextClicked: () -> Unit, ) { + val textSelection = TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0) + var value by remember(fieldUiModel.value) { - mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection)) } InputPositiveIntegerOrZero( @@ -526,8 +531,10 @@ private fun ProvidePercentage( onNextClicked: () -> Unit, ) { + val textSelection = TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0) + var value by remember(fieldUiModel.value) { - mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection)) } InputPercentage( @@ -565,8 +572,10 @@ private fun ProvideNumber( onNextClicked: () -> Unit, ) { + val textSelection = TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0) + var value by remember(fieldUiModel.value) { - mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection)) } InputNumber( @@ -605,8 +614,9 @@ private fun ProvideIntegerNegative( onNextClicked: () -> Unit, ) { + val textSelection = TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0) var value by remember(fieldUiModel.value) { - mutableStateOf(TextFieldValue(fieldUiModel.value?.replace("-", "") ?: "")) + mutableStateOf(TextFieldValue(fieldUiModel.value?.replace("-", "") ?: "", textSelection)) } InputNegativeInteger( @@ -644,8 +654,10 @@ private fun ProvideLongText( onNextClicked: () -> Unit, ) { + val textSelection = TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0) + var value by remember(fieldUiModel.value) { - mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection)) } InputLongText( @@ -684,8 +696,9 @@ private fun ProvideLetter( onNextClicked: () -> Unit, ) { + val textSelection = TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0) var value by remember(fieldUiModel.value) { - mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection)) } InputLetter( @@ -723,8 +736,9 @@ private fun ProvideInteger( onNextClicked: () -> Unit, ) { + val textSelection = TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0) var value by remember(fieldUiModel.value) { - mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection)) } InputInteger( @@ -762,8 +776,10 @@ private fun ProvideEmail( focusManager: FocusManager, onNextClicked: () -> Unit, ) { + val textSelection = TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0) + var value by remember(fieldUiModel.value) { - mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection)) } InputEmail( @@ -811,8 +827,10 @@ private fun ProvideInputPhoneNumber( onNextClicked: () -> Unit, ) { + val textSelection = TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0) + var value by remember(fieldUiModel.value) { - mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection)) } InputPhoneNumber( @@ -860,8 +878,10 @@ private fun ProvideInputLink( onNextClicked: () -> Unit, ) { + val textSelection = TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0) + var value by remember(fieldUiModel.value) { - mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection)) } InputLink( diff --git a/form/src/main/java/org/dhis2/form/ui/provider/inputfield/InputsForTextValueTypeProvider.kt b/form/src/main/java/org/dhis2/form/ui/provider/inputfield/InputsForTextValueTypeProvider.kt index 4b52d9cb97..9d069fdea0 100644 --- a/form/src/main/java/org/dhis2/form/ui/provider/inputfield/InputsForTextValueTypeProvider.kt +++ b/form/src/main/java/org/dhis2/form/ui/provider/inputfield/InputsForTextValueTypeProvider.kt @@ -8,6 +8,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusManager +import androidx.compose.ui.text.TextRange import androidx.compose.ui.text.input.TextFieldValue import org.dhis2.form.extensions.autocompleteList import org.dhis2.form.extensions.inputState @@ -72,8 +73,9 @@ private fun ProvideQRInput( focusManager: FocusManager, onNextClicked: () -> Unit, ) { + val textSelection = TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0) var value by remember(fieldUiModel.value) { - mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection)) } InputQRCode( @@ -170,8 +172,10 @@ private fun ProvideBarcodeInput( focusManager: FocusManager, onNextClicked: () -> Unit, ) { + val textSelection = TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0) + var value by remember(fieldUiModel.value) { - mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection)) } InputBarCode( diff --git a/form/src/main/java/org/dhis2/form/ui/provider/inputfield/UnitIntervalInputProvider.kt b/form/src/main/java/org/dhis2/form/ui/provider/inputfield/UnitIntervalInputProvider.kt index 8f033dca80..eb7dfa93f8 100644 --- a/form/src/main/java/org/dhis2/form/ui/provider/inputfield/UnitIntervalInputProvider.kt +++ b/form/src/main/java/org/dhis2/form/ui/provider/inputfield/UnitIntervalInputProvider.kt @@ -7,6 +7,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.text.TextRange import androidx.compose.ui.text.input.TextFieldValue import org.dhis2.form.extensions.inputState import org.dhis2.form.extensions.legend @@ -22,8 +23,10 @@ fun ProvideUnitIntervalInput( intentHandler: (FormIntent) -> Unit, onNextClicked: () -> Unit, ) { + val textSelection = TextRange(if (fieldUiModel.value != null) fieldUiModel.value!!.length else 0) + var value by remember(fieldUiModel.value) { - mutableStateOf(TextFieldValue(fieldUiModel.value ?: "")) + mutableStateOf(TextFieldValue(fieldUiModel.value ?: "", textSelection)) } InputUnitInterval( modifier = modifier.fillMaxWidth(),