AndroidKotlin

Kotlin – Formulaire – partie 2

By 18 février 2019 No Comments

Dans cet article, nous allons voir comment effectuer la validation du formulaire créé dans la partie 1

Le projet de cet article est disponible ici.

 

Voici le formulaire que nous allons utiliser :

 

Pour que le bouton « Envoyer » soit actif, il faudra avoir  :

  • Soit un téléphone fixe valide, soit un téléphone mobile valide, soit les 2 téléphones valides
  • Une date de naissance valide (supérieur à 18 ans)
  • Un mot de passe valide
  • Une confirmation du mot de passe, devant être identique au mot de passe ci-dessus
  • Le checkbox coché

Voici le contenu de l’activité permettant de répondre aux critères ci-dessus :

package fr.sebastienlaunay.formulaire

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_form.*

class FormActivity : AppCompatActivity() {

    private lateinit var mValidator: FormValidator

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_form)

        /*****************************/
        /* Validation du formulaire  */
        /*****************************/
        mValidator = FormValidator()
            // Ajout vérification s'il y a un tel fixe ou un tel mobile, ou les 2 valides
            .addField(UFieldFirstValidOrSecondValidOrBoth(landLinePhone, mobilePhone))
            // Ajout vérification du mot de passe
            .addField(password)
            // Ajout vérification de la confirmation du mot de passe
            .addField(passwordConfirmation.isIdenticalTo(password))
            // Ajout vérification Année de naissance
            .addField(birthday)
            // Ajout vérification externe : Ici un checkbox
            .addValidator { checkBox.isChecked }
            // On valide la vérification du formulaire par l'activation du bouton btnValidateForm
            .validateWith(btnValidateForm)

        // On valide le formulaire
        mValidator.validate()

        // On a besoin de relancer manuellement la validation du formulaire à chaque changement de l'état du checkbox
        // car c'est une vérification "externe"
        checkBox.setOnClickListener {
            mValidator.validate()
        }

        btnValidateForm.setOnClickListener {
            resultat.setText("Le formulaire est valide !")
        }
    }
}

Voici le contenu de la classe « FormValidator » :

package fr.sebastienlaunay.formulaire

import android.view.View

class FormValidator {

    private val fields = ArrayList<UField>()
    private val validators = ArrayList<() -> Boolean>()
    private var button: View? = null
    private var listener: View.OnClickListener? = null

    var isValid: Boolean = false
        set(valid) {
            field = valid
            button?.isEnabled = valid
        }

    fun addField(field: UField): FormValidator {
        fields.add(field)
        field.setOnUpdateListener(object : OnUpdateListener {
            override fun onUpdated() {
                update()
            }
        })
        update()
        return this
    }

    fun addValidator(validator: () -> Boolean): FormValidator {
        validators.add(validator)
        update()
        return this
    }

    fun validateWith(button: View): FormValidator {
        this.button = button
        this.button?.setOnClickListener { listener?.onClick(this.button) }
        update()
        return this
    }

    fun validate() {
        update()
    }

    private fun update() {
        val fieldsValidity = fields.map { it.isValid() }.fold(true, { f1, f2 -> f1 && f2 })
        val validatorsValidity = validators.map { it.invoke() }.fold(true, { f1, f2 -> f1 && f2 })
        isValid = (fieldsValidity && validatorsValidity)
    }

    interface OnUpdateListener {
        fun onUpdated()
    }

}

Voici le contenu de la classe UFieldFirstValidOrSecondValidOrBoth.kt, permenttant de faire la vérification des champs téléphone fixe et téléphone mobile

package fr.sebastienlaunay.formulaire

class UFieldFirstValidOrSecondValidOrBoth(private val first: PersoTextInputLayout, private val second: PersoTextInputLayout) : UField {

    private var mUpdateListener: FormValidator.OnUpdateListener? = null

    init {
        val childrenListener: FormValidator.OnUpdateListener = object : FormValidator.OnUpdateListener {
            override fun onUpdated() {
                mUpdateListener?.onUpdated()
            }
        }
        first.setOnUpdateListener(childrenListener)
        second.setOnUpdateListener(childrenListener)
    }

    override fun isValid(): Boolean = first.isValid() && second.isEmpty()
            || first.isEmpty() && second.isValid()
            || first.isValid() && second.isValid()

    override fun setOnUpdateListener(listener: FormValidator.OnUpdateListener) {
        mUpdateListener = listener
    }

}

Et voici l’interface UField

package fr.sebastienlaunay.formulaire

interface UField {
    fun isValid() : Boolean
    fun setOnUpdateListener(listener : FormValidator.OnUpdateListener)
}