简体   繁体   中英

Accessible form validation in jetpack compose

I am trying to make an accessible form with Jetpack Compose.

My form uses OutlinedTextField for text input and a normal button for submission. When the submit button is pressed, my ViewModel validates the input and updates a state. This state is then used to display an extra Text element with the error message below the OutlinedTextField . I also set isError = true on my text field.

My goal is to have Talkback read out all form errors on submit, or to implement a better behavior for accessibility.

When the error state of my OutlinedTextField changes, Talkback reads "error, invalid input". This is good, because users can at least recognize that something is wrong. The problem is that i cannot bring Talkback to read more than this. I have custom error messages for each form field and want a way for users to hear them. I have tried to play around with Modifier.semantics { } and used error() function inside, but Talkback still just reads "error, invalid input" when submitting. To get Talkback to read my error message, I have to focus the OutlinedTextField , but then it does not only read my message, but also the default "error, invalid input". I have not found a way to stop this behavior.

I also tried to set a content description for the submit button that contains the error messages, but this will only read the first time and still read the default text field error message.

Does anyone know a clean way to accomplish this task. I would also appreciate better suggestions for accessible form validation in compose.

I have the same issue - the TextReader saying "error, invalid input" is not too helpful.

Looking at the code for androidx/compose/material/TextFieldImpl.kt particularly line 147 in the CommonDecorationBox.kt ( androidx.compose.material 1.3.1 ), note the ambiguous comment

// Developers need to handle invalid input manually. But since we don't provide error
// message slot API, we can set the default error message in case developers forget about it.

val defaultErrorMessage = getString(DefaultErrorMessage)
val decorationBoxModifier = Modifier.semantics { if (isError) error(defaultErrorMessage) }

it would seem that the only way to override the error message "invalid input" is to somehow override the R.string.default_error_message strings specified in Strings.android.kt

    @Composable
    internal actual fun getString(string: Strings): String {
        LocalConfiguration.current
        val resources = LocalContext.current.resources
        return when (string) {
            Strings.NavigationMenu -> resources.getString(R.string.navigation_menu)
            Strings.CloseDrawer -> resources.getString(R.string.close_drawer)
            Strings.CloseSheet -> resources.getString(R.string.close_sheet)
---->       Strings.DefaultErrorMessage -> resources.getString(R.string.default_error_message)
            Strings.ExposedDropdownMenu -> resources.getString(R.string.dropdown_menu)
            Strings.SliderRangeStart -> resources.getString(R.string.range_start)
            Strings.SliderRangeEnd -> resources.getString(R.string.range_end)
            else -> ""
        }
    }

or copy the code from CommonDecorationBox upwards ( OutlinedTextFieldDecorationBox and OutlinedTextField ) and edit it to your own ends which isnt a great solution. But I'm not a Compose expert so hopefully someone out there can answer better than me

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM