fabulous-dev / Fabulous

Declarative UI framework for cross-platform mobile & desktop apps, using MVU and F# functional programming

Home Page:https://fabulous.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Entry behaviour sample

sandeep-eroad opened this issue · comments

Is there a sample showing how to use Entry behaviour to disallow entering some characters in Entry control?

@sandeep-eroad

I tested behavior and entry with a passwordchecker but I think you can change the little part and then you can disallow specific characters.

Here is the code I come up with:

module TestEntryBehavior =
    open Xamarin.Forms
    type EntryBehavior() =
        inherit Xamarin.Forms.Behavior<Entry>()

        let onTextChanged(sender: obj, args: TextChangedEventArgs) =
            let passwordRegex = @"^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,}$"
            let IsValid = (System.Text.RegularExpressions.Regex.IsMatch(args.NewTextValue, passwordRegex))
            match IsValid with
            | true -> (sender :?> Entry).TextColor <- Color.Default
            | false -> (sender :?> Entry).TextColor <- Color.Red

        override this.OnAttachedTo(entry: Entry) =
            entry.TextChanged.AddHandler(fun x y -> onTextChanged(x,y))
            base.OnAttachedTo(entry)

        override this.OnDetachingFrom(entry: Entry) =
            entry.TextChanged.RemoveHandler(fun x y -> onTextChanged(x,y))
            base.OnDetachingFrom(entry)

    type Fabulous.XamarinForms.View with 

        static member inline EntryBehavior() = 

            // Get the attributes for the base element. The number is the expected number of attributes.
            // You can add additional base element attributes here if you like
            let attribCount = 0
            let attribs = ViewBuilders.BuildView(attribCount) 

            
            // The incremental update method
            let update (prevOpt: ViewElement voption) (source: ViewElement) (target: Xamarin.Forms.Behavior) = 
                ViewBuilders.UpdateBindableObject(prevOpt, source, target)
                
            let updateAttachedProperties propertyKey prevOpt source targetChild =
                ViewBuilders.UpdateBindableObjectAttachedProperties(propertyKey, prevOpt, source, targetChild)

            ViewElement.Create<EntryBehavior>(EntryBehavior, update, updateAttachedProperties, attribs)

And then you can use it like the following:

View.Entry(
                    text = entryText,
                    horizontalOptions = LayoutOptions.CenterAndExpand,
                    behaviors = [View.EntryBehavior()], // behavior used here
                    textChanged = (fun args -> dispatch (TextChanged(args.OldTextValue, args.NewTextValue))), 
                    completed = fun text -> dispatch (EntryEditCompleted text)
                )

I've opened a feature request for better integration of behaviors in Fabulous: #832.
In the meantime, the solution of @SergejDK is the recommended way.

Thanks @SergejDK for the sample code.

Hi @SergejDK , I tried your solution but I want to change the text - trim spaces, and as soon as I do that the handler is called recursively and is stuck in a loop.

@SergejDK - It was only an issue while debugging, it seems to work fine if not debugging.