Arash Shahzamani
Arash Shahzamani

Reputation: 437

How to clear textfield value in Jetpack Compose?

I've developed a textInput composable with a trailing icon, and I'd like to clear the textInput when the icon is clicked. How can I access the textInput value, so that I can clear it?

    @Composable
fun TextInput(
    myVal: String,
    label: String,
    placeholder: String="",
    helperText: String="",
    errorText: String="",
    onValueChange : (String) -> Unit){
    val hasError = !errorText.isNullOrEmpty()
    val helperColor =  if (hasError)
        Color(0xFFfe392f)
        else
            Color(0xFF5c6a79)

    Row() {
            Column() {
                TextField(
                    colors = TextFieldDefaults.textFieldColors(
                        backgroundColor = Color.Transparent,
                        textColor = Color(0xFF011e41),
                        cursorColor = Color(0xFF011e41),
                        focusedLabelColor = Color(0xFF011e41),
                        unfocusedLabelColor = Color(0xFF011e41),
                        unfocusedIndicatorColor = Color(0xFFebeced),
                        focusedIndicatorColor = Color(0xFF011e41),
                        errorCursorColor = Color(0xFFfe392f),
                        errorIndicatorColor = Color(0xFFfe392f),
                        errorLabelColor = Color(0xFFfe392f)
                    ),
                    value = myVal,
                    onValueChange = onValueChange,
                    label = { Text(label) },
                    placeholder = { Text(placeholder) },
                    isError = hasError,
                    trailingIcon = {Icon(Icons.Filled.Email, contentDescription = "sdsd", modifier = Modifier.offset(x= 10.dp).clickable {
                       //What should I do here?
                    })}
                )

                Text(
                    modifier = Modifier.padding(8.dp),
                    text = if (hasError) errorText else helperText,
                    fontSize = 12.sp,
                    color = helperColor,
                )
            }
    }
}

it's used like this:

var text by remember { mutableStateOf("") }
                    TextInput(myVal = text, label = "label", helperText = "", errorText = "my error") {text = it}

Upvotes: 22

Views: 14206

Answers (4)

Rob Meeuwisse
Rob Meeuwisse

Reputation: 2937

the click handler of your trailing icon has to call the TextField's onValueChange with an empty string:

...
trailingIcon = { 
    Icon(
        Icons.Filled.Email,
        contentDescription = "sdsd",
        modifier = Modifier
            .offset(x= 10.dp)
            .clickable {
                //just send an update that the field is now empty
                onValueChange("") 
            }
        )
}
...

Upvotes: 19

Gabriele Mariotti
Gabriele Mariotti

Reputation: 363825

You can use the trailingIcon attribute with a custom clickable modifier.
Something like:

var text by rememberSaveable { mutableStateOf("") }

TextField(
    value = text,
    onValueChange = { text = it },
    trailingIcon = {
        Icon(Icons.Default.Clear,
            contentDescription = "clear text",
            modifier = Modifier
                .clickable {
                    text = ""
                }
        )
    }
)

enter image description here

If you are using a TextFieldValue:

val content = "content"
var text by rememberSaveable(stateSaver = TextFieldValue.Saver) {
    mutableStateOf(TextFieldValue(content))
}

TextField(
    value = text,
    onValueChange = { text = it },
    trailingIcon = {
        Icon(Icons.Default.Clear,
            contentDescription = "clear text",
            modifier = Modifier
                .clickable {
                    text = TextFieldValue("")
                }
        )
    }
)

Upvotes: 32

Vikas Patidar
Vikas Patidar

Reputation: 43349

Use trailingIcon Composable property with IconButton to match the background selector of the icon with the rest of the theme. You can also put empty condition to display it only when there is some input in the text field.

Below is sample code snippet:

var text by remember { mutableStateOf ("") }

TextField(
    trailingIcon = {
        when {
            text.isNotEmpty() -> IconButton(onClick = {
                text = ""
            }) {
                Icon(
                    imageVector = Icons.Filled.Clear,
                    contentDescription = "Clear"
                )
            }
        }
    }
)

Upvotes: 4

Richard Onslow Roper
Richard Onslow Roper

Reputation: 6835

This shall achieve this

//Caller
val text by remember { mutableStateOf (...) }

TextInput(text, ..., ...,)

//Composable
@Composable
fun TextInput(text, ..., ...){
val textState by remember { mutableStateOf (text) }
TextField(
 value = textState,
trailingIcon = {
 Icon(..., Modifier.clickable { textState = "" })
}
}

Upvotes: 0

Related Questions