package Ġme . a art ik ov . ses ame . form . validation . form Ċ Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . flow . drop Ċ import Ġkotlinx . coroutines . flow . filter Ċ import Ġkotlinx . coroutines . flow . launch In Ċ import Ġkotlinx . coroutines . flow . on Each Ċ import Ġme . a art ik ov . ses ame . form . control . Valid atable Control Ċ import Ġme . a art ik ov . ses ame . form . validation . control . Control Validator Ċ import Ġme . a art ik ov . ses ame . form . validation . control . Input Validator Ċ import Ġme . a art ik ov . ses ame . form . validation . control . Validation Result Ċ import Ġme . a art ik ov . ses ame . property . flow Ċ Ċ /** Ċ Ġ* ĠHigh Ġlevel Ġfeature Ġfor Ġ[ Form Validator ]. Ċ Ġ*/ Ċ interface ĠForm Validation Feature Ġ{ ĊĊĠĠĠ Ġfun Ġinstall ( coroutine Scope : ĠCor outine Scope , Ġform Validator : ĠForm Validator ) Ċ } Ċ Ċ /** Ċ Ġ* ĠH ides Ġan Ġerror Ġon Ġa Ġcontrol Ġwhenever Ġsome Ġvalue Ġis Ġentered Ġto Ġit . Ċ Ġ*/ Ċ object ĠHide Error On ValueChanged Ġ: ĠForm Validation Feature Ġ{ ĊĊĠĠĠ Ġoverride Ġfun Ġinstall ( coroutine Scope : ĠCor outine Scope , Ġform Validator : ĠForm Validator ) Ġ{ ĊĠĠĠĠĠĠĠ Ġform Validator . validators . forEach Ġ{ Ġ( control , Ġ_) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhide Error On ValueChanged ( coroutine Scope , Ġcontrol ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhide Error On ValueChanged ( coroutine Scope : ĠCor outine Scope , Ġcontrol : ĠValid atable Control <* >) Ġ{ ĊĠĠĠĠĠĠĠ Ġcontrol :: value . flow ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. drop ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. on Each Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontrol . error Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. launch In ( coroutine Scope ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠValid ates Ġcontrol Ġagain Ġwhenever Ġits Ġvalue Ġis Ġchanged Ġand Ġit Ġalready Ġdisplays Ġan Ġerror . Ċ Ġ*/ Ċ object ĠRe validate On ValueChanged Ġ: ĠForm Validation Feature Ġ{ ĊĊĠĠĠ Ġoverride Ġfun Ġinstall ( coroutine Scope : ĠCor outine Scope , Ġform Validator : ĠForm Validator ) Ġ{ ĊĠĠĠĠĠĠĠ Ġform Validator . validators . forEach Ġ{ Ġ(_, Ġvalidator ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġre validate On ValueChanged ( coroutine Scope , Ġvalidator ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġre validate On ValueChanged ( coroutine Scope : ĠCor outine Scope , Ġvalidator : ĠControl Validator <* >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontrol Ġ= Ġvalidator . control ĊĠĠĠĠĠĠĠ Ġcontrol :: value . flow ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. drop ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. on Each Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( control . error Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalidator . validate () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. launch In ( coroutine Scope ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠValid ates Ġa Ġcontrol Ġwhenever Ġit Ġlo ses Ġa Ġfocus . Ċ Ġ*/ Ċ object ĠValidate On Focus Lost Ġ: ĠForm Validation Feature Ġ{ ĊĊĠĠĠ Ġoverride Ġfun Ġinstall ( coroutine Scope : ĠCor outine Scope , Ġform Validator : ĠForm Validator ) Ġ{ ĊĠĠĠĠĠĠĠ Ġform Validator . validators . forEach Ġ{ Ġ(_, Ġvalidator ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( validator Ġis ĠInput Validator ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalidate On Focus Lost ( coroutine Scope , Ġvalidator ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġvalidate On Focus Lost ( coroutine Scope : ĠCor outine Scope , Ġinput Validator : ĠInput Validator ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġinput Control Ġ= Ġinput Validator . control ĊĠĠĠĠĠĠĠ Ġinput Control :: has Focus . flow ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. drop ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġ! it Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. on Each Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput Validator . validate () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. launch In ( coroutine Scope ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠSets Ġfocus Ġon Ġa Ġfirst Ġinvalid Ġcontrol Ġafter Ġform Ġvalidation Ġhas Ġbeen Ġprocessed . Ċ Ġ*/ Ċ object ĠSet Focus On First Invalid Control After Validation Ġ: ĠForm Validation Feature Ġ{ ĊĊĠĠĠ Ġoverride Ġfun Ġinstall ( coroutine Scope : ĠCor outine Scope , Ġform Validator : ĠForm Validator ) Ġ{ ĊĠĠĠĠĠĠĠ Ġform Validator . validated Event Flow ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. on Each Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . display Result ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfocus On First Invalid Control ( it . result ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. launch In ( coroutine Scope ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfocus On First Invalid Control ( validation Result : ĠForm Validation Result ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfirst Invalid Control Ġ= Ġvalidation Result . control Results . entries ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. first OrNull Ġ{ Ġit . value Ġis ĠValidation Result . Invalid Ġ} ?. key ĊĊĠĠĠĠĠĠĠ Ġfirst Invalid Control ?. request Focus () ĊĠĠĠ Ġ} Ċ }