How to make use of the Code-Input component in my own app

Hi guys.

I’m trying to implement this recent code input component as a separate class and grab its value in my own component, like this:

<SegmentedInput Label="Enter your code" />
<TextInput PlaceholderText="Enter the password" Value="{password}" />

And in my js file:

var Observable = require("FuseJS/Observable");
var MyService = require("Services/MyService");
var SegmentedInput = require("Components/SegmentedInput");

var url = "http://someURL";
var password = Observable("");

function login() {

  MyService.loginService(url, SegmentedInput.code.value, password.value)
    .then(function(result) {
      console.log(result);
    });
}

module.exports = {
  password: password,
  login: login
}

I saw a video from Jake teaching how to organize the JS files in a Fuse project and expose them as a Bundle and then call it with the “require” method (just like the code above), but I noticed that it doesn’t work with Observables, only with simple variables.
My question is: How can I get the value of the “code” Observable (as in the tutorial) in my own component since all the logic is encapsulated inside the SegmentedInput Class?

Thanks in advance!

Hi Renato,
what you need to do is properly split the component in its own UX file. I have taken the liberty to do that quickly for you.

First, a separate SegmentedInput.ux file turns into:

<StackPanel ux:Class="SegmentedInput" HitTestMode="LocalBounds">
    <string ux:Property="Label" />
    <string ux:Property="Code" />
    <JavaScript>
        var Observable = require("FuseJS/Observable");

        var editMode = Observable(false);
        function enterEditMode() {
            editMode.value = true;
        };
        function exitEditMode() {
            editMode.value = false;
        };

        var codeLength = 5;
        var code = this.Code; // IMPORTANT: this here binds to the new <string ux:Property="Code" /> I added above
        var splitCode = code.map(function(item) {
            var entered = item.split("");
            while (entered.length < codeLength) {
                entered.push("");
            }
            return entered;
        }).expand();

        var symbols = splitCode.map(function(item, index) {
            var obj = {symbol: item, selected: false};
            if (index == code.value.length) {
                obj.selected = true;
            }
            return obj;
        });

        module.exports = {
            code: code,
            codeLength: codeLength,
            symbols: symbols,
            editMode: editMode,
            enterEditMode: enterEditMode,
            exitEditMode: exitEditMode
        };
    </JavaScript>

    <Panel ux:Class="SymbolBox">
        <string ux:Property="Symbol" />

        <WhileTrue Value="{editMode}">
            <Change backgroundRect.Margin="8,0" Delay="0.2" DelayBack="0" />
            <Change backgroundRect.CornerRadius="1" Delay="0.2" DelayBack="0" />
            <Change label.Opacity="1" Delay="0.2" Duration="0.42" Easing="ExponentialOut" EasingBack="ExponentialIn" />
        </WhileTrue>

        <WhileTrue Value="{selected} && {editMode}">
            <Change backgroundRect.Color="Black" Delay="0.2" Duration="0.42" Easing="ExponentialOut" EasingBack="ExponentialIn" />
        </WhileTrue>

        <Text ux:Name="label" Alignment="Center" Value="{ReadProperty Symbol}" FontSize="32" Color="Highlight" Opacity="0" />
        <Rectangle ux:Name="backgroundRect" Color="Highlight" Height="2" Alignment="Bottom">
            <LayoutAnimation>
                <Move X="1" Y="1" RelativeTo="PositionChange" Duration="0.42" Easing="ExponentialOut" EasingBack="ExponentialIn" />
                <Resize X="1" Y="1" RelativeTo="SizeChange" Duration="0.42" Easing="ExponentialOut" EasingBack="ExponentialIn" />
            </LayoutAnimation>
        </Rectangle>
    </Panel>

    <Clicked>
        <GiveFocus Target="codeInput" />
    </Clicked>

    <TextInput ux:Name="codeInput" Value="{code}" MaxLength="{codeLength}" InputHint="Number"
        Layer="Background" Visibility="Hidden" HitTestMode="None"
        Focus.Gained="{enterEditMode}" Focus.Lost="{exitEditMode}" />

    <Panel Height="24">
        <Text Value="{ReadProperty Label}" FontSize="20" Color="Highlight" Alignment="TopLeft" TransformOrigin="TopLeft">
            <Translation ux:Name="labelTrans" Y="1" RelativeTo="ParentSize" />
            <WhileTrue Value="{editMode}">
                <Change labelTrans.Y="0" Delay="0.2" Duration="0.42" Easing="ExponentialOut" EasingBack="ExponentialIn" />
                <Scale Factor="0.8" Delay="0.2" Duration="0.42" Easing="ExponentialOut" EasingBack="ExponentialIn" />
            </WhileTrue>
        </Text>
    </Panel>

    <Grid ColumnCount="{codeLength}" Height="40">
        <Each Items="{symbols}">
            <SymbolBox Symbol="{symbol}" />
        </Each>
    </Grid>
</StackPanel>

And second, use it from MainView.ux (or any other UX file) like this:

<App>
    <float4 ux:Global="Highlight" ux:Value="#999" />

    <JavaScript>
        var Observable = require("FuseJS/Observable");
        var theCode = Observable("");

        // I am only adding the following to see how the code changes.
        // you can read theCode.value when you call a submit() function or something similar
        theCode.onValueChanged(module, function(x) {
            console.log("theCode changed to: " + x);
        });

        module.exports = {
            theCode: theCode
        };
    </JavaScript>

    <ClientPanel>
        <SegmentedInput Label="Enter Code" Code="{theCode}" Alignment="Top" Margin="16,64,16,0" />
    </ClientPanel>
</App>

That’s exactly what I was looking for! Thanks!