Question about Router Code in Sample

exports.goChannels = function() {
            router.goto( "home", {}, "channels", {}, "list", {} )
            TheEdge.dismiss()
        }
        exports.goContacts = function() {
            router.goto( "home", {}, "contacts", {}, "list", {} )
            TheEdge.dismiss()
        }
        exports.goSettings = function() {
            router.goto( "home", {}, "settings", {} )
            TheEdge.dismiss()
        }

        exports.openMenu = function() {
            console.log( "Goto Menu" )
            TheEdge.open( "Left" )
        }

The app happily sends users to a home page, contacts page and a list page. The router.goto has 5 arguments, I understand the three different pages but don’t understand why there are five arguments. I also can’t really follow what “TheEdge” does.

The full code is at: https://github.com/fusetools/fuse-samples/tree/master/Samples in the sample called UI Structure.

Thanks for any help and if this is documented well in the API docs or a video, I apologize. I have looked through it several times before posting this.

Hi!

Here is a good article describing router and navigation in Fuse: https://www.fusetools.com/docs/navigation/navigation

As for that sample. The name TheEdge is defined in UX, and is therefore accessible in JavaScript. That type also has a JavaScript method which you can call, in order to open it and (in this case) dismiss it: https://www.fusetools.com/docs/fuse/controls/edgenavigator#section-table-of-contents

This reply was very helpful. I still have one question. Here is my mainview.ux:

<App>

    <Router ux:Name="router" />
    <DockPanel>

        <Navigator DefaultTemplate="home">
            <HomePage ux:Template="home" router="router" />
        </Navigator>

    </DockPanel>

</App>

All I want it to do is start up a “home” page that I can use to start the dialog with the user and that users can return to when they hit the home button.

Here is HomePage.ux

<DefaultPage ux:Class="HomePage">
    <Router ux:Dependency="router" />

    <JavaScript File="HomePage.js" />

    <DockPanel>

        <PageControl ux:Name="pageControl" >
            <PageOne ux:Name="pageOne" router="router" />  
            <PageTwo ux:Name="pageTwo" router="router" />  
        </PageControl> 


        <Panel Dock="Top">
            <Grid Alignment="Bottom" Height="50" ColumnCount="3" Background="#7f5ce6" >
                <HomePageTab Label="Page One" pageControl="pageControl" page="pageOne" />
                <HomePageTab Label="Page Two" pageControl="pageControl" page="pageTwo" />
            </Grid>
        </Panel>


    </DockPanel>


</DefaultPage>

All I want it to do is display a blank screen with a couple of HomePageTab objects. HomePageTab is precisely as in the caatr example but to make life easy I’ll include it here:

<Panel ux:Class="HomePageTab" HitTestMode="LocalBoundsAndChildren">
    <string ux:Property="Label" />
    <PageControl ux:Dependency="pageControl" />
    <Page ux:Dependency="page" />
    <Text Alignment="Center" Value="{Property this.Label}" />
    <Clicked>
        <NavigateTo NavigationContext="pageControl" Target="page" />
    </Clicked>
    <WhilePressed>
        <Scale Factor=".70" Duration=".08" Easing="QuadraticInOut" />
    </WhilePressed>
</Panel>

PageOne and PageTwo.ux are basically the same right now as I just want to focus on navigation. They are just page objects that display “i am on Page One” and “I am on Page Two” in a text object.

PageOne.ux is:

Page ux:Class="PageOne">
  <Router ux:Dependency="router" />
    <JavaScript File="PageOne.js" />   
            <StackPanel>
              <Text Value="This is Page One" />
         </StackPanel>
</Page>

PageTwo.ux is:

<Page ux:Class="PageTwo">
  <Router ux:Dependency="router" />
    <JavaScript File="PageTwo.js" />   
            <StackPanel>
              <Text Value="This is Page Two" />
         </StackPanel>
</Page>

When I run this, instead of a blank screen I get a “This is Page One” upon the start of the application. I want this to be blank with just the two HomePageTab’s so I can give the users directions. The HomePageTabs are there and work perfectly.

I just do not understand why the text on Page One is displayed before the user has done anything. I have to think some default in the router is being triggered, but I still really don’t have a good grasp of route to know how to fix this.

Really appreciate your help – feel like I’m very close to getting the hang of navigation. Note that I have all the include’s for javascript but each javascript file (for this example) has only:

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

Many thanks for your help.

Hi again!

I think i see what the issue is here. The PageControl works a bit differently than the Navigator; it always has an active page and works with concrete instances of each page (unlike the navigator which instantiates and destroys “Templates” on demand).

Since the PageControl belongs to HomePage and PageOne is the first page in it, that is what you see.

There are several ways you can get around this, but the best approach depends on your exact use case.

If your reason is just to show some tutorial content before you show the actual pages, you could just layer your tutorial bit on top of your PageControl until the user somehow dismisses it.

Here is a short snippet to illustrate:

<WhileTrue ux:Name="showTut" Value="true"><!-- Value == true so that it is visible by default -->
    <Panel>
         ... your tutorial content ---
        <Button>
            <Clicked>
                <Set showTut.Value="false" /><!-- this removes the panel -->
            </Clicked>
        </Button>
    </Panel>
</WhileTrue>
<PageControl>
    <PageOne ..
    .....
    ....
</PageControl>

I hope this made things more clear :slight_smile: Otherwise let me know

Really appreciate your quick reply. I can see that what you are doing works, but really I want the user to select one of the two choices and go to the right page based on the choice. I already have the choices displayed.

I wonder if the right thing is to not use page control at all and just use navigator. It feels like page control was sort of a quick way for fuse to get multi-paging rolling and now navigator is sort of the right way to move forward.

My only question is to do this should I have the naviator on the mainview.ux just include page one and page two. Or should I have a navigator on the home page. I am not that clear on what it measn to have multiple navigator objects.

Many thanks.

Really appreciate your quick reply. I tried your code as it makes sense and it doesn’t wait for the button.

Here is the full contents of homepage.ux

<DefaultPage ux:Class="HomePage">
    <Router ux:Dependency="router" />

    <JavaScript File="HomePage.js" />

    <DockPanel>


        <WhileTrue ux:Name="showTut" Value="true"><!-- Value == true so that it is visible by default -->
            <Panel>
                 <Text Value=" tutorial content" />
                <Button>
                    <Clicked>
                        <Set showTut.Value="false" /><!-- this removes the panel -->
                    </Clicked>
                </Button>
            </Panel>

        </WhileTrue>

        <PageControl ux:Name="pageControl" >
            <PageOne ux:Name="pageOne" router="router" />  
            <PageTwo ux:Name="pageTwo" router="router" />  
        </PageControl> 


        <Panel Dock="Top">
            <Grid Alignment="Bottom" Height="50" ColumnCount="3" Background="#7f5ce6" >
                <HomePageTab Label="Page One" pageControl="pageControl" page="pageOne" />
                <HomePageTab Label="Page Two" pageControl="pageControl" page="pageTwo" />
            </Grid>
        </Panel>


    </DockPanel>


</DefaultPage>

Sadly it still displays the text of Page One prior to my clicking the new button. I’m wondering if I should just use navigator instead of page control, but i’m not sure I could still use NavigateTo as done in HomePageTab. Some hints on how best to use navigator for this sort of structure would be great. It does sound like Navigator will give me much more control over page transitions.

To fix the fact that you see the text of pageone behind the “tutorial page” can be fixed by giving the Panel inside the WhileTrue a Color, for example <Panel Color="White"

I might have missunderstood your reason for using a PageControl. The main reason to use a PageControl is so you get the SwipeNavigate behavior, which lets you swipe between pages.

If you just want to go to pages whenever a tab item is clicked, you can do this by a JS callback very easily until we get some UX actions to work with the router. :

<App>
    <DockPanel>
        <Router ux:Name="router" />
        <JavaScript>
            module.exports.gotoPage1 = function(){router.goto("page1",{})}
            module.exports.gotoPage2 = function(){router.goto("page2",{})}
        </JavaScript>
        <Grid ColumnCount="2" Height="50" Dock="Top">
            <Panel Color="Blue">
                <Clicked>
                    <Callback Handler="{gotoPage1}" />
                </Clicked>
            </Panel>
            <Panel Color="Red">
                <Clicked>
                    <Callback Handler="{gotoPage2}" />
                </Clicked>
            </Panel>
        </Grid>
        <Navigator DefaultTemplate="defaultTemp">
            <Page ux:Template="defaultTemp" Color="White">
                <Text Value="no page is chosen yet" Alignment="Center" Color="#000" FontSize="30"/>
            </Page>
            <Page ux:Template="page1" Color="Teal" />
            <Page ux:Template="page2" Color="#f0f" />
        </Navigator>
    </DockPanel>
</App>

Thanks so much – I now am able to do enough navigation to make progress on my app and it works thanks to your help. I do have one remaining question. I tried to modify the HomePageTab class to leverage routes. First here is homepage.ux

<Page ux:Class="HomePage">
    <Router ux:Dependency="router" />

    <JavaScript File="HomePage.js" />

    <DockPanel>

         <Panel Dock="Top">
            <Grid Alignment="Bottom" Height="50" ColumnCount="2" Background="#7f5ce6" >

                 <HomePageTab Label="Page ONE" PageHandler="{gotoPage1}"/>
                 <HomePageTab Label="Page TWO" PageHandler="{gotoPage2}"/>
                </Grid>
        </Panel>

        <Text Value="Home Page" TextColor="Blue"/>

        <Grid ColumnCount="2" Height="50" Dock="Top">
            <Panel Color="Blue">
                <Text Value="Go to Page One" TextColor="White"/>
                <Clicked>
                    <DebugAction Message="Going to Page 1" />
                    <Callback Handler="{gotoPage1}" />
                </Clicked>
            </Panel>
            <Panel Color="Red">
                <Text Value="Go to Page Two" TextColor="White"/>
                <Clicked>
                    <DebugAction Message="GOING to Page 2" />
                    <Callback Handler="{gotoPage2}" />
                </Clicked>
            </Panel>
        </Grid>
    </DockPanel>
</Page>

The two navigation buttons work well. Here’s the HomePage.js file

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

module.exports.gotoPage1 = function()
    {
        console.log("going to page1")
        router.goto("page1",{})
    }

module.exports.gotoPage2 = function()
    {
        console.log("going to page2")
        router.goto("page2",{})
    }

Now for my question: HomePageTab looks like this:

<Panel ux:Class="HomePageTab">
    <string ux:Property="Label" />
    <string ux:Property="PageHandler"  />
        <Text Alignment="Center" Value="{Property this.Label}" TextColor="White" />
        <Clicked>
                <Callback Handler="{Property this.PageHandler}" />
        </Clicked>
        <WhilePressed>
                <Scale Factor=".70" Duration=".08" Easing="QuadraticInOut" />
        </WhilePressed>
</Panel>

I want to pass in a PageHandler to the Panel that makes up HomePage, but passing it as a string doesn’t work. I click on the button and nothing happens. I suspect its because the value I’m passing is really not a string, its a javascript class that is really a handler. Is there any way to pass in a handler.

I realize I can get this to work by simply making two separate panels, but seems like one could have an app with 10 or 20 of these panels and it’d be nice to just have a generic object.

Thanks again for all your help.

Hi, I’m having trouble understanding what you’re after. If you’re trying to pass a callback through the router, that will not work; functions are not properly serializable objects in JS. You’ll need to move the data between them another way, perhaps by putting your callback in another JS module that the relevant pages can see via require.

Jake,

This makes sense – many thanks for your reply. I didn’t realize functions were not properly serialized in JS – but I’ve avoided JS for a long time. Keep up the great work on Fuse, it looks really promisng. I’m making good progress on a fun app.

No problem! Happy to help :slight_smile: