How to implement EdgeNavigator on components?

Hi! Can anyone please guide me on how to correctly implement EdgeNavigator with components? I wanted to create a generic page with EdgeNavigator inserted so that I can put a hamburger menu with access to my app sections. I followed the EdgeNavigator sample but I can’t figure out how to correctly put it on a rehusable way with a component.

I tried to use the Container tag but it does not work, probably because I’m using it all wrong.

Here is my component code:

<Page ux:Class="club.Page">
  <iOS.StatusBarConfig Style="Dark" Animation="Slide" IsVisible="False" />

  <Container ux:Class="PageContent" Subtree="innerPanel">
    <EdgeNavigator>
      <Panel ux:Name="sidebar" Edge="Left" Width="100%" Margin="0,0,56,0" Background="#000000">
        <Shadow ux:Name="shadow" Angle="180" Distance="8" Size="16" Color="#0000" />
        <ActivatingAnimation>
          <Change shadow.Color="#0004" />
          <Change sidebarFade.Opacity="1" />
        </ActivatingAnimation>
        <StackPanel ux:Name="normalMenuItems" ItemSpacing="30">
          <Image Alignment="HorizontalCenter" File="../Assets/logo.png" Row="0" Margin="20" Width="75%" />
          <MenuButton Name="home" Alignment="Left" Text="My Account">
            <Clicked>
              <Callback Handler="{go}" />
              <NavigateToggle Target="sidebar" />
            </Clicked>
          </MenuButton>
          <MenuButton Name="rewards" Alignment="Left" Text="Rewards">
            <Clicked>
              <Callback Handler="{go}" />
              <NavigateToggle Target="sidebar" />
            </Clicked>
          </MenuButton>
          <MenuButton Name="services" Alignment="Left" Text="Services">
            <Clicked>
              <Callback Handler="{go}" />
              <NavigateToggle Target="sidebar" />
            </Clicked>
          </MenuButton>
          <MenuButton Name="locations" Alignment="Left" Text="Locations">
            <Clicked>
              <Callback Handler="{go}" />
              <NavigateToggle Target="sidebar" />
            </Clicked>
          </MenuButton>
          <MenuButton Name="feedback" Alignment="Left" Text="Contact Us">
            <Clicked>
              <Callback Handler="{go}" />
              <NavigateToggle Target="sidebar" />
            </Clicked>
          </MenuButton>
        </StackPanel>
      </Panel>
      
      <DockPanel>
        <Image Layer="Background" File="../Assets/bg.png" StretchMode="UniformToFill" />
        <Rectangle ux:Name="sidebarFade" Layer="Overlay" Color="#0005" Opacity="0" HitTestMode="None" />
        <StackPanel Dock="Top" Color="#AE1D1A">
          <Shadow Size="3" Distance="1" />
          <StatusBarBackground />
          <Panel Height="56">
            <Hamburger Alignment="Left">
              <Clicked>
                <NavigateToggle Target="sidebar" />
              </Clicked>
            </Hamburger>
            <Text Alignment="Center" Font="MainView.AppFont" FontSize="21" Color="ForegroundColor">My Incredible Pizza</Text>
          </Panel>
        </StackPanel>
        
        <Rectangle ux:Binding="Children" CornerRadius="10" Margin="10">
          <Stroke Color="Red" Width="2" />
          <Panel Margin="10" ux:Name="innerPanel" />
        </Rectangle>        
      </DockPanel>
    </EdgeNavigator>
  </Container>
</Page>

And here is how I am using it on a page:

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

  <JavaScript File="Nav.js" />
  <JavaScript File="HomePage.js" />

  <PageContent>
      <Text Value="Some content for my container" Alignment="Center"/>
  </PageContent>
</club.Page>

Am I on the right track? Any help would be much appreciated!

Thanks in advance!
Damian

I stripped out all references to missing components, scripts, globals, etc. (hint, hint :wink: ) and removed the Container settings and it seems you can inject the EdgeNavigator from a component. Perhaps you can back into your app from the following (hope it helps):

MainView.ux

<App>
    <club.Page />
</App>

ClubPage.ux

<Page ux:Class="club.Page">
    <EdgeNavigator>
        <Panel ux:Name="sidebar" Edge="Left" Width="100%" Margin="0,0,56,0" Background="#000000">
            <ActivatingAnimation>
                <Change sidebarFade.Opacity="1" />
            </ActivatingAnimation>
            <Text Value="Settings" />
        </Panel>
        
        <DockPanel>
            <Rectangle ux:Name="sidebarFade" Layer="Overlay" Color="#0005" Opacity="0" HitTestMode="None" />

            <StackPanel Dock="Top" Color="#AE1D1A">
                <Panel Height="56">
                    <Rectangle Alignment="Left" Width="20" Height="20" Color="Blue">
                        <Clicked>
                            <NavigateToggle Target="sidebar" />
                        </Clicked>
                    </Rectangle>
                    <Text Alignment="Center" Font="Regular" FontSize="21" Color="#aaa">My Incredible Pizza</Text>
                </Panel>
            </StackPanel>
            
            <Rectangle CornerRadius="10" Margin="10">
            <Stroke Color="Red" Width="2" />
            <Panel Margin="10" ux:Name="innerPanel" />
            </Rectangle>        
        </DockPanel>
    </EdgeNavigator>
</Page>

Hi Darrin!
Sorry but I’m still missing the implementation of the component. If I take out the Container, how does Fuse know where it has to inject the contents of each page so they fit in on the correct place for EdgeNavigator to work properly?

I would expect for example Homepage.ux and Contact.ux to implement <club.Page>, each with different contents.

Thank you very much for your help!

@Damian: if you create a ux:Class that holds an EdgeNavigator, and then use it to create a number of pages, then you end up with a number of EdgeNavigator instances.

There should only be one EdgeNavigator in an app. You can pass it in to your components via ux:Dependency.

@Uldis I think I understand but in that case shouldn’t I use the EdgeNavigator on the MainView.ux and pass it to my club.Page instances as a dependency?

I’m still confused on this, if it was on the MainView would I really need to pass it to my pages? I mean, if I send it as a dependency, do I need to use it to show it or only if I need to manipulate it?

The problem I have is that the Login and SignUp page should not have the EdgeNavigator as you are not logged yet, so that’s why I thought of defining it on a page level but it’s clear now that there should only one defined, question is how.

I’m sorry to have so many questions but I didn’t find any example of a multi page app with a menu navigator to use as a guide and dependency is hard to understand. Could you please show me how to use it on the sample @Darrin kindly corrected?

Many many thanks!

Damian Lobalzo wrote:

@Uldis I think I understand but in that case shouldn’t I use the EdgeNavigator on the MainView.ux and pass it to my club.Page instances as a dependency?

Yes, you need to do exactly that. But see the next point.

I’m still confused on this, if it was on the MainView would I really need to pass it to my pages? I mean, if I send it as a dependency, do I need to use it to show it or only if I need to manipulate it?

You should obviously only pass it in as a dependency for manipulation. E.g., if you need to be able to show/dismiss the edge menu from a given page. Otherwise no, you don’t need to pass it in.

The problem I have is that the Login and SignUp page should not have the EdgeNavigator as you are not logged yet, so that’s why I thought of defining it on a page level but it’s clear now that there should only one defined, question is how.

Ah, but you can easily have that! Just put a top-level Navigator in your MainView that holds two templates - one with edge menu, one without. Inside of those templates, put another Navigator (or rather an EdgeNavigator in one of them first), and add whatever pages belong in each of them. Multi-level navigation isn’t that hard in Fuse.

Ok I moved the EdgeNavigator to MainView.ux and so far so good, but I can’t figure out how to declare the contents I want for each page, which as far as I understand need to be declared inside the EdgeNavigator tag.

So this arises two new questions:

  1. If I inject something through a dependency, how do I put it on the markup of the page?
  2. If the EdgeNavigator is declared on the MainView.ux, I assume it will be available on all pages, but how do I override a portion of it on each page so that I put each page’s content inside of it?

Thank you!

Sorry, I didn’t attach the code, perhaps you can spotlight what I’m doing wrong:

<App>
    <EdgeNavigator ux:Name="sidebarMenu">
        <Panel ux:Name="sidebar" Edge="Left" Width="100%" Margin="0,0,56,0" Background="#000000">
            <ActivatingAnimation>
                <Change sidebarFade.Opacity="1" />
            </ActivatingAnimation>
            <Text Value="Settings" />
        </Panel>
        
        <DockPanel>
            <Rectangle ux:Name="sidebarFade" Layer="Overlay" Color="#0005" Opacity="0" HitTestMode="None" />

            <StackPanel Dock="Top" Color="#AE1D1A">
                <Panel Height="56">
                    <Rectangle Alignment="Left" Width="20" Height="20" Color="Blue">
                        <Clicked>
                            <NavigateToggle Target="sidebar" />
                        </Clicked>
                    </Rectangle>
                    <Text Alignment="Center" Font="Regular" FontSize="21" Color="#aaa">My Incredible Pizza</Text>
                </Panel>
            </StackPanel>
            
            <Rectangle CornerRadius="10" Margin="10">
            <Stroke Color="Red" Width="2" />
            <Panel Margin="10" ux:Name="innerPanel" />
            </Rectangle>        
        </DockPanel>
    </EdgeNavigator>

  <ClientPanel>
    <Navigator DefaultPath="splash">
      <SplashPage ux:Template="splash" router="router" />
      <HomePage ux:Template="home" router="router" sidebar="sidebarMenu" />
    </Navigator>
  </ClientPanel>

</App>

And here is my HomePage.ux

<Page ux:Class="HomePage">
  <Router ux:Dependency="router" />
  
  <EdgeNavigator ux:Dependency="sidebar">
    <Panel>
      <Text Alignment="Center">
       Why can´t I see this content???
      </Text>
    </Panel>
  </EdgeNavigator>

  <JavaScript File="Nav.js" />
  <JavaScript File="HomePage.js" />

</Page>

Thank you again!

You have misunderstood how ux:Dependency works. You can’t do stuff like this:

  <EdgeNavigator ux:Dependency="sidebar">
    <Panel>
      <Text Alignment="Center">
       Why can´t I see this content???
      </Text>
    </Panel>
  </EdgeNavigator>

As explained above, you can pass in something via dependency to then have access to the original instance of that something, for manipulation purposes, such as showing or hiding the edge panel in case of an EdgeNavigator.

If you want to show different content inside of the edge menu, depending on which page you are currently on, you could look into using AlternateRoot. Coincidentally, you’ll still need the dependency injection, so that’s fine.