Placeholder inside Each loop

Platform: Windows 10

Fuse version: 0.10.0 (build 5986)

Issue: When placing Placeholders inside an Each loop the elements inside the Placeholder appear to duplicate themselves (see below screen shot).

How to Replicate: Run the below code then click on any of the items. After clicking a dark line above each item will appear.

Expected Outcome: When clicking on any of the items the dark line that appears above “hei” should move to the item that was clicked. This works as expected if the first item in the Each loop is moved out of the Each loop.

How can I structure this to avoid having to duplicate my UX code?

MainView.ux

<App Theme="Basic" Background="#eeeeeeff">
    <DockPanel>
        <JavaScript File="MainView.js" />
        <MultiLayoutPanel ux:Name="_tabBar" Height="50" Dock="Bottom">
            <GridLayout Columns="1*,1*,1*,1*" />

            <Each Items="{elements}">
                <Panel Name="{element.text}" Color="#75b1bd">
                    <!-- First -->
                    <WhileFloat Value="{index}" LessThan="1" >
                        <Placeholder ux:Name="detailPlaceholder">
                            <Rectangle ux:Name="_tabBarSlider" Height="4" Color="#548089" Alignment="Top">
                                <LayoutAnimation>
                                    <Move RelativeTo="LayoutChange" X="1" Duration="0.3" Easing="BackIn"/>
                                </LayoutAnimation>
                            </Rectangle>
                        </Placeholder>
                    </WhileFloat>
                    <!-- ALL BUT First -->
                    <WhileFloat Value="{index}" GreaterThan="0">
                        <Placeholder Target="_tabBarSlider" />
                    </WhileFloat>

                    <Text Value="{element.text}" Padding="7" TextAlignment="Center" />

                    <Clicked>
                        <Set _tabBar.LayoutElement="{element.text}" />
                    </Clicked>
                </Panel>
            </Each>

       </MultiLayoutPanel>
    </DockPanel>
</App>

MainView.js

var Observable = require("FuseJS/Observable");

var elem_text = Observable(
    {"text": "hei"},
    {"text": "hade"},
    {"text": "di"},
    {"text": "hai"}
);


var elements = elem_text.map(function (x, i) {
    return {
        element: x,
        max_index: elem_text.length - 1,
        index: i
    };
});

module.exports = {
    elements: elements
};

Hello,

This sounds like expected behavior. All elements inside an Each are supposed to be duplicated for each data item.

If you want only one instance of the rectangle, you have to place that rectangle outside your Each-loop, for example:

<Placeholder ux:AutoBind="false">
    <Rectangle ux:Name="_tabBarSlider" ...

ux:AutoBind="false" makes sure this rectangle is not added anywhere, it is just an object that doesn’t have a parent yet.

Then inside Each, you only have empty Placeholders that point to _tabBarSlider

Here is a complete example that probably does what you want :slight_smile:

<App Theme="Basic" Background="#eeeeeeff">
    <DockPanel>
        <JavaScript>
            var Observable = require("FuseJS/Observable");

            var elem_text = Observable(
                {"text": "hei"},
                {"text": "hade"},
                {"text": "di"},
                {"text": "hai"}
            );

            var activeTab = Observable("hei");

            var elements = elem_text.map(function (x, i) {
                return {
                    element: x,
                    max_index: elem_text.length - 1,
                    index: i,
                    makeActive: function () {
                        activeTab.value = x.text;
                    }
                };
            });

            module.exports = {
                elements: elements,
                activeTab: activeTab
            };
        </JavaScript>
        <MultiLayoutPanel ux:Name="_tabBar" Height="50" Dock="Bottom" LayoutElement="{activeTab}">
            <GridLayout Columns="1,1,1,1" />

            <Placeholder ux:AutoBind="false">
                <Rectangle ux:Name="_tabBarSlider" Height="4" Color="#548089" Alignment="Top">
                    <LayoutAnimation>
                        <Move RelativeTo="LayoutChange" X="1" Duration="0.3" Easing="BackIn"/>
                    </LayoutAnimation>
                </Rectangle>
            </Placeholder>

            <Each Items="{elements}">
                <Panel Name="{element.text}" Color="#75b1bd" Clicked="{makeActive}">
                    <Placeholder Target="_tabBarSlider" />
                    <Text Value="{element.text}" Padding="7" TextAlignment="Center" />
                </Panel>
            </Each>

       </MultiLayoutPanel>
    </DockPanel>
</App>

Thanks your example works perfectly.