ScrollView scroll to "Top" or "Front" to make selections visible

I have scoured the FuseTools web site docs, forums and tried Google, and each attempt at a solution has failed and I have been stuck for the better part of a day trying to figure out how I can trigger scrolling of my ScrollView that contains a StackPanel of horizontal buttons so that the first button is present. Admittedly, this is unlikely a bug, but I could really use some help. This occurs because my ScrollView contains 50+ items and when the user scolls all the way to the right, and selects an item, I want to assist them by scrolling it to the “front” so that the most important Search Keywords are visible after each and every re-binding of the Observable (list) data.

My original UX code looks like this:

<ScrollView AllowedScrollDirections="Horizontal" ux:Name="tagbarScrollView">
    <StackPanel Height="40" Orientation="Horizontal" ItemSpacing="4" Padding="2">
        <Each Items="{searchTags}">
            <KeywordButton Text="{tag}" Clicked="{searchTagClicked}>
            </KeywordButton>
        </Each>							
    </StackPanel>
</ScrollView>

With this code, I have a Javascript Handler named, searchTagClicked that does a couple of fetches via HTTP and re-populates my searchTags Observable to redraw the ScrollView row of buttons.

My questions are:

  1. What’s the right approach to trigger scrolling? I originally thought Fuse would presribe a declarative approach over an imperative manner?
    => Please note that I am rendering the component via an Observable (list) with an iterator and don’t have a specific element tagged with ‘ux:Name’

  2. Suppose I needed to coordinate the activities and want to do this via my existing searchTagClicked Javascript Handler, how do I get a reference to the underlying ScrollView in my Javascript code and what methods do I need to call, and which parameters do I need to pass in to animate the scrolling to the front?

  3. Suppose I needed to coordinate the activities and want to do this via my existing searchTagClicked Javascript Handler, how do I get a reference to the underlying ScrollView in my Javascript code and what methods do I need to call, and which parameters do I need to pass in to animate the scrolling to the front?

Now the short version of the failed approaches and my current problems…
I tried the declarative approach by arbitrarily splitting my Observable into a first and others sub lists so that I can create TargetNode used in conjunction with

<ScrollView AllowedScrollDirections="Horizontal" ux:Name="tagbarScrollView">
    <StackPanel Height="40" Orientation="Horizontal" ItemSpacing="4" Padding="2">
        <Each Items="{firstSearchTag}">
            <Rectangle ux:Name="firstSearchTag">
                <KeywordButton Text="{tag}">
                    <Clicked Handler="{searchTagClicked}">										
                    </Clicked>
                </KeywordButton>
            </Rectangle>
        </Each>

        <Each Items="{otherSearchTags}">
            <KeywordButton Text="{tag}">
                <Clicked Handler="{searchTagClicked}">	
                    <BringIntoView TargetNode="firstSearchTag" />
                </Clicked>									
                </Clicked>
            </KeywordButton>
        </Each>							
    </StackPanel>
</ScrollView>

This fails with these errors:

E8001: 'firstSearchTag' declared in app.ux(78) cannot be accessed from this scope.
/Users/calvin/Documents/Safezone/Projects/Amazon/hack-week/yaks/app.ux(89,1): Error E8001: 'firstSearchTag' declared in app.ux(78) cannot be accessed from this scope.
app.ux(89): E8001: There is nothing named 'firstSearchTag' in this scope, and no global resources with that alias.

I tried to tag with ux:Gobal and that failed with this pro tip.

E8001: Global objects do not support bindings. Pro tip: Create a ux:Class and create a global instance of that instead.
/Users/calvin/Documents/Safezone/Projects/Amazon/hack-week/yaks/app.ux(79,1): Error E8001: Global objects do not support bindings. Pro tip: Create a ux:Class and create a global instance of that instead.

I then changed directions and tried to find Imperative methods to trigger scrolling but reached dead ends. I’ve tried much or all of the Fuse documentation and cannot find a solution that I understand. Will you help with an example? On a slight tangent, suppose I have two Text inputs, how do I declaratively set focus on one or the other on startup or in response to other actions?

If i understand correctly; you want to scroll back to the start whenever one of the first buttons is clicked. In JS you can use the goto function on ScrollView:

<App>

	<JavaScript>
		function gotoStart(){ tagbarScrollView.gotoRelative(0,0); }
		module.exports = { gotoStart };
	</JavaScript>
	<ScrollView ux:Name="tagbarScrollView" AllowedScrollDirections="Horizontal">
		<StackPanel Height="60" Orientation="Horizontal" ItemSpacing="4" Padding="2">
			<Each Count="50">
				<Panel Background="Red" Padding="10">
					<Button Text="Foo">
						<Clicked>
							<Callback Handler="{gotoStart}"/>
						</Clicked>
					</Button>
				</Panel>
			</Each>                            
		</StackPanel>
	</ScrollView>
</App>

In pure UX you can use the ScrollTo action (https://www.fusetools.com/docs/fuse/gestures/scrollto) like so:

<Clicked>
	<ScrollTo Target="tagbarScrollView" RelativePosition="0,0" />
</Clicked>

For you second question. You can use the GiveFocus (https://www.fusetools.com/docs/fuse/triggers/actions/givefocus) action in UX.
Here is how to trigger that on startup using a WhileTrue trigger:

<WhileTrue Value="true" Bypass="Never"> <!-- we need Bypass="Never" so that it triggers in its default state -->
    <GiveFocus Target="yourTextInput" />
</WhileTrue>

I see that both ScrollTo and GiveFocus are not in our UX Class reference (which they should be), i’ll investigate this. Sorry about the inconvenience this caused you.

Kristian, thank you for this great insight. It’s awesome how flexible and powerful Fuse’s ux:Name construct is. I had only previously seen it as a mechanism for subclassing UX elements and now realize instance references are readily available in JS as well. That said, I prefer the declarative options better in both cases.

One follow up, suppose I have a JS handler to that performs validation and needs to dynamically set focus on a UX element based on which errors were present. In this case, how can I use JS to set focus on a particular control? I read this documentation page here but didn’t see any JS interfaces.
https://www.fusetools.com/docs/fuse/triggers/actions/givefocus