dazai
dazai

Reputation: 716

Hide text input layout's error after editing the field's text

I'm trying to hide error on a text input layout after the user solves the error but I am not sure how to do that, given that the function afterTextChanged doesn't seem to work with it. How can I do this?

This is the part I'm talking about:

loginViewModel.loginFormState.observe(this, Observer {
           val loginState = it ?: return@Observer

           // disable login button unless fields are valid
           binding.btnLogin.isEnabled = loginState.isDataValid
           if (loginState.emailError != null) {
               binding.etEmail.error = getString(loginState.emailError)
           }
           if (loginState.passwordError != null) {
               binding.tfPassword.error = getString(loginState.passwordError)
           }
       })

       binding.etEmail.afterTextChanged {
           loginViewModel.loginDataChanged(
               binding.etEmail.text.toString(),
               binding.etPassword.text.toString()
           )
       }

       binding.etPassword.afterTextChanged {
           loginViewModel.loginDataChanged(
               binding.etEmail.text.toString(),
               binding.etPassword.text.toString()
           )
       }

private fun TextInputEditText.afterTextChanged(afterTextChanged: (String) -> Unit) {
   this.addTextChangedListener(object : TextWatcher {
       override fun afterTextChanged(editable: Editable?) {
           afterTextChanged.invoke(editable.toString())
       }

       override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}

       override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
   })

Even if the user writes the password correctly and they can click on a button I have, the error is still there, how can I make it go away?

Upvotes: 1

Views: 571

Answers (2)

m.reiter
m.reiter

Reputation: 2555

I guess your error lies in those lines:

if (loginState.emailError != null) {
   binding.etEmail.error = getString(loginState.emailError)
}

Now imagine emailError was "some error" once and now is null. The bindings' text will not be set again, so it's still "some error". To fix this mistake replace it with:

binding.etEmail.error = if(loginState.emailError != null){
    getString(loginState.emailError)
} else {
     null
}

Do the same for your passwordError

Upvotes: 1

mightyWOZ
mightyWOZ

Reputation: 8355

you can use setError method and pass null as argument. from documentation

Sets an error message that will be displayed below our EditText. If the error is null, the error message will be cleared.

you can call this method in afterTextChanged as

textInputEditText.addTextChangedListener (object: TextWatcher {
    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { }
    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int)    { }
    override fun afterTextChanged(s: Editable?) {
         textInputLayout.error = null
    }
})

Upvotes: 1

Related Questions